Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- public class Modules {
- static Vertex[] graph;
- static int position;
- static HashMap<String, Vertex> functions;
- static Stack<Vertex> stack;
- static int time = 1, count = 1;
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- ArrayList<String> expr = new ArrayList<>();
- while (in.hasNextLine()) expr.add(in.nextLine());
- int length = expr.size();
- for (int i = 0; i < length; i++)
- if (expr.get(i).length() == 0)
- expr.remove(i);
- length = expr.size();
- ArrayList<Token>[] Lex = new ArrayList[length];
- graph = new Vertex[length];
- functions = new HashMap<>();
- stack = new Stack<>();
- for (int i = 0; i < length; i++) {
- Lex[i] = new ArrayList<>();
- getTokens(expr.get(i), Lex[i]);
- graph[i] = new Vertex(Lex[i], expr.get(i));
- }
- Program();
- }
- static class Vertex {
- ArrayList<Token> value;
- ArrayList<Vertex> next;
- ArrayList<String> vars;
- String name;
- String formula;
- int need;
- int t1, comp, low;
- public Vertex(ArrayList<Token> v, String f) {
- this.value = v;
- this.formula = f;
- next = new ArrayList<>();
- this.vars = new ArrayList<>();
- need = 0;
- }
- }
- static void visitVertex(Vertex v) {
- v.t1 = v.low = time++;
- stack.push(v);
- Vertex temp;
- for (Vertex u : v.next) {
- if (u.t1 == 0) visitVertex(u);
- if (u.comp == 0 && v.low > u.low) v.low = u.low;
- }
- if (v.t1 == v.low) {
- do {
- temp = stack.pop();
- temp.comp = count;
- } while (temp != v);
- count++;
- }
- }
- public static void ERROR(){
- System.out.print("error");
- System.exit(0);
- }
- private static void MakeFuncGraph(Vertex[] graph) {
- for (Vertex v : graph) {
- functions.put(v.value.get(0).value, v);
- for (Token item : v.value) {
- if (item.matches(Tag.IDENT)) v.need++;
- if (item.matches(Tag.EQ)) break;
- }
- v.need--;
- }
- for (Vertex item : graph) {
- position = 0;
- try {
- parseFunc(item);
- } catch (Exception e) {
- ERROR();
- }
- if (position < item.value.size()) ERROR();
- }
- }
- static void Program (){
- MakeFuncGraph(graph);
- for (Vertex v : graph) {
- if (v.t1 == 0) {
- visitVertex(v);
- }
- }
- System.out.print(--count);
- }
- private static void getTokens(String exp, ArrayList<Token> Lex) {
- int i, j, length = exp.length();
- for (i = 0; i < length; i++) {
- char k = exp.charAt(i);
- if (exp.charAt(i) != ' ') {
- if (exp.charAt(i) == '+') Lex.add(new Token("+", Tag.PLUS));
- else if (k == '-') Lex.add(new Token("-", Tag.SUB));
- else if (k == '*') Lex.add(new Token("*", Tag.MUL));
- else if (k == '/') Lex.add(new Token("/", Tag.DIV));
- else if (k == '=') Lex.add(new Token("=", Tag.EQ));
- else if (k == '(') Lex.add(new Token("(", Tag.OPEN));
- else if (k == ')') Lex.add(new Token(")", Tag.CLOSE));
- else if (k == ',') Lex.add(new Token(",", Tag.COMMA));
- else if (k == ':') Lex.add(new Token(",", Tag.DOUBLEP));
- else if (k == ';') Lex.add(new Token(";", Tag.EOFUNC));
- else if (k == '?') Lex.add(new Token(";", Tag.QUEST));
- else if (k == '<') Lex.add(new Token("<", Tag.LEFT));
- else if (k == '>') Lex.add(new Token("<", Tag.RIGHT));
- else if (Character.isDigit(k)) {
- j=i;
- while (j < length && Character.isDigit(exp.charAt(j))) {
- j++;
- }
- Lex.add(new Token(exp.substring(i, j), Tag.NUM));
- i = --j;
- } else if (Character.isLetter(k)) {
- j=i;
- while (j < length && (Character.isDigit(exp.charAt(j)) || Character.isLetter(exp.charAt(j)))){
- j++;
- }
- Lex.add(new Token(exp.substring(i, j), Tag.IDENT));
- i = --j;
- } else ERROR();
- }
- }
- }
- enum Tag {
- PLUS, DIV, MUL, SUB, EQ, OPEN, CLOSE, COMMA, NUM, IDENT, DOUBLEP, EOFUNC, QUEST, LEFT, RIGHT
- }
- static class Token {
- String value;
- Tag tag;
- public Token(String value, Tag tag) {
- this.tag = tag;
- this.value = value;
- }
- public boolean matches(Tag... tags) {
- return Arrays.stream(tags).anyMatch(t -> tag == t);
- }
- }
- private static void parseFunc(Vertex v) {
- if (v.value.get(position).tag != Tag.IDENT && v.value.get(position + 1).tag != Tag.OPEN) ERROR();
- v.name = v.value.get(position).value;
- position += 2;
- parseFormalArgsList(v);
- if (v.value.get(position).tag != Tag.CLOSE || v.value.get(position + 1).tag != Tag.DOUBLEP || v.value.get(position + 2).tag != Tag.EQ) ERROR();
- position += 3;
- parseExpr(v);
- if (v.value.get(position).tag != Tag.EOFUNC) ERROR();
- position++;
- }
- private static void parseFormalArgsList(Vertex v){
- if(v.value.get(position).tag==Tag.CLOSE) return;
- parseIdentList(v);
- }
- private static void parseIdentList(Vertex v){
- if(v.value.get(position).tag!=Tag.IDENT) ERROR();
- v.vars.add(v.value.get(position).value);
- position++;
- while(v.value.get(position).tag==Tag.COMMA){
- position++;
- parseIdentList(v);
- }
- }
- private static void parseExpr(Vertex v){
- parseCompExpr(v);
- if(v.value.get(position).tag==Tag.QUEST){
- position++;
- parseCompExpr(v);
- if(v.value.get(position).tag!=Tag.DOUBLEP) ERROR();
- position++;
- parseExpr(v);
- }
- }
- private static void parseCompExpr(Vertex v){
- parseArithExpr(v);
- if(v.value.get(position).tag==Tag.EQ){
- position++;
- parseArithExpr(v);
- }
- if(v.value.get(position).tag==Tag.LEFT){
- position++;
- if(v.value.get(position).tag==Tag.RIGHT || v.value.get(position).tag==Tag.EQ) position++;
- parseArithExpr(v);
- }
- if(v.value.get(position).tag==Tag.RIGHT){
- position++;
- if(v.value.get(position).tag==Tag.EQ) position++;
- parseArithExpr(v);
- }
- }
- private static void parseArithExpr(Vertex v){
- parseF(v);
- while(position<v.value.size()&&(v.value.get(position).tag==Tag.MUL || v.value.get(position).tag==Tag.DIV)) {
- position++;
- parseF(v);
- }
- while(position<v.value.size()&&(v.value.get(position).tag == Tag.PLUS || v.value.get(position).tag == Tag.SUB)){
- position++;
- parseF(v);
- while(position<v.value.size()&&(v.value.get(position).tag==Tag.MUL || v.value.get(position).tag==Tag.DIV)) {
- position++;
- parseF(v);
- }
- }
- }
- private static void parseF(Vertex v){
- if(v.value.get(position).tag == Tag.NUM) position++;
- else if(v.value.get(position).tag == Tag.IDENT){
- if(v.value.get(position+1).tag==Tag.OPEN){
- String name = v.value.get(position).value;
- position+=2;
- int given = parseActArgList(v);
- if(v.value.get(position).tag!=Tag.CLOSE) ERROR();
- if(!functions.containsKey(name) || functions.get(name).need!=given) ERROR();
- if(!v.next.contains(functions.get(name)) && v!=functions.get(name))v.next.add(functions.get(name));
- }
- else if(!v.vars.contains(v.value.get(position).value)) ERROR();
- position++;
- }
- else if(v.value.get(position).tag == Tag.OPEN){
- position++;
- parseExpr(v);
- if(v.value.get(position).tag!=Tag.CLOSE) ERROR();
- position++;
- }
- else if(v.value.get(position).tag == Tag.SUB){
- while(v.value.get(position).tag == Tag.SUB) position++;
- parseF(v);
- }
- else ERROR();
- }
- private static int parseActArgList(Vertex v){
- int res=0;
- if(v.value.get(position).tag==Tag.CLOSE) return 0;
- parseExpr(v);
- while(v.value.get(position).tag==Tag.COMMA){
- position++;
- parseExpr(v);
- res++;
- }
- return (++res);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement