import java_cup.runtime.*; import java.io.*; import symtab.*; /* regular languages parser for CUP. * Copyright (C) 2006 Silvano Rivoira * This program is released under the terms of the GPL; see the file * COPYING for more details. There is NO WARRANTY on this code. */ parser code {: public static Scanner s; public static int errors = 0; public SymTable alpha = new SymTable(); public SymTable def = new SymTable(); public static void main(String argv[]) { for (int i = 0; i < argv.length; i++) { try { System.out.println("Parsing ["+argv[i]+"]\n"); s = new Scanner(new FileReader(argv[i])); rlac p = new rlac(s); p.parse(); System.out.println("\nNumber of errors = " + errors + "."); } catch (Exception e) { e.printStackTrace(System.out); System.exit(1); } } } public void sem_error(String lexeme, String message) { errors++; System.err.println("Error "+ s.current_lexeme() + " : Semantic error"); System.err.println(" "+ errors + "==> " + message + ": "+ lexeme + "\n"); } public void report_error(String message, Object info) { if (info instanceof String){ errors++; System.err.println(" "+ errors + "==> " + info + " "+ message + "\n Parsing resumed from 2nd token before" + s.current_lexeme()+"\n"); } else { StringBuffer m = new StringBuffer("Error "); if (info instanceof java_cup.runtime.Symbol) m.append( "("+info.toString()+")" ); m.append(" : "+message); System.err.println(m); } } public void report_fatal_error(String message, Object info) { report_error(message, info); throw new RuntimeException("Fatal Syntax Error"); } :}; terminal LALPHA, RALPHA, LDEF, RDEF, LPAREN, RPAREN, LBRACK, RBRACK, COMMA; terminal EMPTY; terminal NOT, PROD, PLUS, MINUS, UNION, STAR; terminal EQ, EQUESTION, INQUESTION; terminal ILLEGAL_CHARACTER; terminal java.lang.String IDENTIFIER, INPUTSYMBOL; non terminal goal; non terminal alphabet_declaration, expression_declaration, input_symbols, regular_definitions, regular_definition; non terminal evaluations, evaluation; non terminal String string; non terminal Autom expression, regular_expression, conc_expression, closure_expression; non terminal Autom paren_expression, prod_expression, unary_expression, symbol; start with goal; goal ::= alphabet_declaration expression_declaration evaluations | error {: parser.report_error("alphabed_declaration","MISSING"); :} expression_declaration evaluations ; alphabet_declaration ::= LALPHA input_symbols RALPHA {: parser.alpha.put("&", new Autom("&")); new Autom(parser.alpha.table()); // System.out.println(" ALPHABET: "+parser.alpha.keysToString()+"\n"); :} ; input_symbols ::= INPUTSYMBOL:n {: if (!parser.alpha.put(n, null)) parser.sem_error(n,"DUPLICATE NAME"); :} | input_symbols COMMA INPUTSYMBOL:n {: if (!parser.alpha.put(n, null)) parser.sem_error(n,"DUPLICATE NAME"); :} | input_symbols error INPUTSYMBOL:n {: parser.report_error("','","MISSING"); if (!parser.alpha.put(n, null)) parser.sem_error(n,"DUPLICATE NAME"); :} ; expression_declaration ::= | LDEF regular_definitions RDEF {: System.out.println(" DEFINITIONS: "+parser.def+"\n"); :} ; regular_definitions ::= | regular_definitions regular_definition ; regular_definition ::= IDENTIFIER:n EQ expression:e {: if (!parser.def.put(n, e)) parser.sem_error(n,"DUPLICATE NAME"); :} | IDENTIFIER:n error {: parser.report_error("'='","MISSING"); :} expression ; evaluations ::= | evaluations evaluation ; evaluation ::= IDENTIFIER:i1 EQUESTION IDENTIFIER:i2 {: Autom a1 = parser.def.get(i1); if(i1 == null) parser.sem_error(i1,"UNKNOWN NAME"); Autom a2 = parser.def.get(i2); if(i2 == null) parser.sem_error(i2,"UNKNOWN NAME"); boolean eq = a1.verify(a2); System.out.print(" "+i1); if (eq) System.out.print(" == "); else System.out.print(" != "); System.out.println(i2); :} | IDENTIFIER:i1 INQUESTION IDENTIFIER:i2 {: Autom a1 = parser.def.get(i1); if(i1 == null) parser.sem_error(i1,"UNKNOWN NAME"); Autom a2 = parser.def.get(i2); if(i2 == null) parser.sem_error(i2,"UNKNOWN NAME"); Autom p = a1.prod(a2); boolean eq = p.verify(a1); System.out.print(" "+i1); if (eq) System.out.print(" in "); else System.out.print(" !in "); System.out.println(i2); :} | IDENTIFIER error {: parser.report_error("'=?' or 'in?'","MISSING"); :} IDENTIFIER | LPAREN string:s RPAREN INQUESTION IDENTIFIER:i {: Autom a = parser.def.get(i); if(a == null) parser.sem_error(i,"UNKNOWN NAME"); boolean rec = a.recog(s); System.out.print(" ("+s+")"); if (rec) System.out.print(" in "); else System.out.print(" !in "); System.out.println(i); :} | LPAREN RPAREN INQUESTION IDENTIFIER:i {: Autom a = parser.def.get(i); if(a == null) parser.sem_error(i,"UNKNOWN NAME"); boolean rec = a.recog(""); System.out.print(" ()"); if (rec) System.out.print(" in "); else System.out.print(" !in "); System.out.println(i); :} | string error {: parser.report_error("'(' or ')' or 'in?'","MISSING"); :} IDENTIFIER ; string ::= INPUTSYMBOL:n {: Autom s = parser.alpha.get(n); if(s == null) parser.sem_error(n,"UNKNOWN SYMBOL"); RESULT = n; :} | string:s INPUTSYMBOL:n {: Autom is = parser.alpha.get(n); if(is == null) parser.sem_error(n,"UNKNOWN SYMBOL"); if (s.length()==0) RESULT = n; else RESULT = s+" "+n; :} | EMPTY {: RESULT = ""; :} | string:s EMPTY {: RESULT = s; :} ; expression ::= prod_expression:e {: RESULT = e; :} | expression:e PLUS prod_expression:pe {: if(e!=null && pe!=null) RESULT = e.union(pe).determ(); else RESULT = null; // System.out.println("plus: "+RESULT); :} | error {: parser.report_error("expression","WRONG"); :} PLUS prod_expression | expression:e MINUS prod_expression:pe {: if(e!=null && pe!=null) RESULT = e.prod(pe.compl()); else RESULT = null; // System.out.println("minus: "+RESULT); :} | error {: parser.report_error("expression","WRONG"); :} MINUS prod_expression ; prod_expression ::= unary_expression:e {: RESULT = e; :} | prod_expression:pe PROD unary_expression:ue {: if(pe!=null && ue!=null) RESULT = pe.prod(ue); else RESULT = null; // System.out.println("prod: "+RESULT); :} | error {: parser.report_error("prod_expression","WRONG"); :} PROD unary_expression ; unary_expression ::= LBRACK regular_expression:e RBRACK {: if (e!=null) RESULT = e.determ(); else RESULT = null; :} | LBRACK error {: parser.report_error("regular_expression","WRONG"); :} RBRACK | LBRACK expression:e RBRACK {: RESULT = e; :} | NOT unary_expression:e {: if (e!=null) RESULT = e.compl(); else RESULT = null; :} ; regular_expression ::= conc_expression:e {: RESULT = e; :} | regular_expression:re UNION conc_expression:e {: if(re!=null && e!=null) RESULT = re.union(e); else RESULT = null; // System.out.println("union: "+RESULT); :} | error {: parser.report_error("regular_expression","WRONG"); :} UNION conc_expression ; conc_expression ::= closure_expression:e {: RESULT = e; :} | conc_expression:ce closure_expression:e {: if(ce!=null && e!=null) RESULT = ce.conc(e); else RESULT = null; // System.out.println("conc: "+RESULT); :} ; closure_expression ::= symbol:s {: RESULT = s; :} | paren_expression:e {: RESULT = e; :} | symbol:s STAR {: if(s!=null) RESULT = s.closure(); else RESULT = null; // System.out.println("closure: "+RESULT); :} | paren_expression:e STAR {: if(e!=null) RESULT = e.closure(); else RESULT = null; // System.out.println("closure: "+RESULT); :} | error {: parser.report_error("closure_expression","WRONG"); :} STAR ; symbol ::= INPUTSYMBOL:n {: Autom s = parser.alpha.get(n); if(s == null) parser.sem_error(n,"UNKNOWN NAME"); RESULT = s; :} | IDENTIFIER:n {: Autom s = parser.def.get(n); if(s == null) parser.sem_error(n,"UNKNOWN NAME"); RESULT = s; :} | EMPTY {: RESULT = parser.alpha.get("&"); :} ; paren_expression ::= LPAREN regular_expression:e RPAREN {: RESULT = e; :} | LPAREN error {: parser.report_error("paren_expression","WRONG"); :} RPAREN ;