CSC448: Further examples: Arithmetic [21/22] Previous pageContentsNext page

EBNF/BNF for arithmetic expressions.

Precedence and associativity.

Ignore semantic actions (code in braces) for now.

file:arithmetic.flex [source]
00001: import java_cup.runtime.SymbolFactory;
00002: 
00003: %%
00004: 
00005: %class ArithmeticLexer
00006: %public
00007: %{
00008:    private SymbolFactory sf;
00009:    public ArithmeticLexer (java.io.InputStream r, SymbolFactory sf)
00010:    {
00011:      this (r);
00012:      this.sf = sf;
00013:    }
00014: %}
00015: %eofval{
00016:   return sf.newSymbol ("EOF", sym.EOF);
00017: %eofval}
00018: 
00019: %unicode
00020: 
00021: %cup
00022: %cupdebug
00023: 
00024: %char
00025: %column
00026: %line
00027: 
00028: 
00029: ALPHA=[A-Za-z_]
00030: DIGIT=[0-9]
00031: NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012]
00032: NEWLINE=\r|\n|\r\n
00033: IDENT={ALPHA}({ALPHA}|{DIGIT}|_)*
00034: 
00035: %% 
00036: 
00037: <YYINITIAL> {
00038:   "(" { return sf.newSymbol ("LeftParen", sym.LPAREN); }
00039:   ")" { return sf.newSymbol ("RightParen", sym.RPAREN); }
00040:   ";" { return sf.newSymbol ("Semicolon", sym.SEMI); }
00041:   "=" { return sf.newSymbol ("Equals", sym.EQUALS); }
00042:   "+" { return sf.newSymbol ("Plus", sym.PLUS); }
00043:   "-" { return sf.newSymbol ("Minus", sym.MINUS); }
00044:   "*" { return sf.newSymbol ("Times", sym.TIMES); }
00045:   "/" { return sf.newSymbol ("Divide", sym.DIVIDE); }
00046: 
00047:   {NONNEWLINE_WHITE_SPACE_CHAR}+ { }
00048: 
00049:   {IDENT}
00050:     { return sf.newSymbol ("Identifier", sym.IDENTIFIER, yytext ()); }
00051: 
00052:   {DIGIT}+
00053:     {
00054:       int i = Integer.parseInt (yytext ());
00055:       return sf.newSymbol ("IntegerConstant", sym.INTEGER_CONSTANT, new Integer (i));
00056:     }
00057: }
00058: 
00059: {NEWLINE} { }
00060: 
00061: . {
00062:   System.out.println ("Illegal character: <" + yytext () + ">");
00063: }
00064: 
00065: 

file:arithmetic.cup [source]
00001: import java_cup.runtime.*;
00002: 
00003: import java.util.ArrayList;
00004: import java.util.List;
00005: 
00006: 
00007: terminal           LPAREN, RPAREN;
00008: terminal           SEMI, EQUALS;
00009: terminal           PLUS, MINUS, TIMES, DIVIDE;
00010: 
00011: terminal String    IDENTIFIER; 
00012: terminal Integer   INTEGER_CONSTANT;
00013: 
00014: non terminal List<Decl>     decl_list;
00015: non terminal Decl           decl;
00016: non terminal Exp            expression;
00017: 
00018: precedence left PLUS, MINUS;
00019: precedence left TIMES, DIVIDE; 
00020: 
00021: 
00022: decl_list ::= decl_list:l decl:d
00023:               {: l.add (d); RESULT = l; :}
00024:               |
00025:               {: RESULT = new ArrayList<Decl> (); :}
00026:               ;
00027: 
00028: decl ::= IDENTIFIER:id EQUALS expression:e SEMI
00029:          {: RESULT = new Decl (id, e); :}
00030:          ;
00031: 
00032: expression ::= INTEGER_CONSTANT:i
00033:                {: RESULT = new ExpInt (i.intValue ()); :}
00034:                | IDENTIFIER:id 
00035:                {: RESULT = new ExpVar (id); :}
00036:                | expression:e1 PLUS expression:e2
00037:                {: RESULT = new ExpBinOp (ExpBinOp.BinOp.PLUS, e1, e2); :}
00038:                | expression:e1 MINUS expression:e2
00039:                {: RESULT = new ExpBinOp (ExpBinOp.BinOp.MINUS, e1, e2); :}
00040:                | expression:e1 TIMES expression:e2
00041:                {: RESULT = new ExpBinOp (ExpBinOp.BinOp.TIMES, e1, e2); :}
00042:                | expression:e1 DIVIDE expression:e2
00043:                {: RESULT = new ExpBinOp (ExpBinOp.BinOp.DIVIDE, e1, e2); :}
00044:                | LPAREN expression:e RPAREN
00045:                {: RESULT = e; :}
00046:                ;
00047: 
00048: 

Previous pageContentsNext page