CSE 3341 Skeleton Scanner and Parser
Relevant details from Scanner.jflex
/* Identifiers */
Ident = [a-z]
/* Integer literals */
IntLiteral = [0-9]+
/* White spaces */
new_line = \r | \n | \r\n;
white_space = {new_line} | [ \t\f]
%%
/* Keywords */
"int" { return symbol("int", INT); } /* helper function to create a token with string name "int" and integer encoding INT */
"if" { return symbol("if", IF); }
"else" { return symbol("else", ELSE); }
"read" { return symbol("print", READ); }
"print" { return symbol("print", PRINT); }
/* Literals */
{IntLiteral} { return symbol("IntLiteral", INT_LITERAL, Integer.decode(yytext())); } /* the token has an associated Java Integer value */
/* Identifiers */
{Ident} { return symbol("ID", IDENT, yytext()); } /* the token has an associated Java String value */
/* Punctuators */
";" { return symbol(";", SEMICOLON); }
"(" { return symbol("(", LPAREN); }
")" { return symbol(")", RPAREN); }
/* Operators */
"+" { return symbol("+", ADD); }
"*" { return symbol("*", MUL); }
"=" { return symbol("=", ASSIGN); }
/* Comments and white spaces */
"/*" [^*] ~"*/" | "/*" "*"+ "/" { }
{white_space} { }
Relevant details from Parser.cup
/* Keywords */
terminal INT, IF, ELSE, READ, PRINT; /* in the generated parser/scanner combo in Java, these become static final int INT = 1; etc. */
/* Punctuators */
terminal SEMICOLON, LPAREN, RPAREN, ADD, MUL, ASSIGN;
/* Literals */
terminal Integer INT_LITERAL; /* the INT_LITERAL token has an associated Java Integer value */
/* identifiers */
terminal String IDENT; /* the IDENT token has an associated String value */
/* Nonterminals */
non terminal Program program; /* the parsing of non terminal program produces an AST node: a Java object of class Program */
non terminal List<Decl> declList;
non terminal Decl decl;
non terminal List<Stmt> stmtList;
non terminal Stmt stmt;
non terminal Expr expr;
non terminal BinaryExpr binaryExpr;
/* Predecence and associativity */
precedence right ASSIGN;
precedence left ADD;
precedence left MUL;
precedence left ELSE; /* resolve "dangling else" ambiguity */
/* Starting nonterminal */
start with program;
/* Productions */
program ::= declList:dl stmtList:sl {: RESULT = new Program(dl, sl); :} ; /* produces a Java object of class Program */
declList ::= /* empty list */ {: RESULT = new LinkedList<Decl>(); :}
| decl:d declList:l {: l.add(0,d); RESULT = l; :} ;
decl ::= INT IDENT:i SEMICOLON {: RESULT = new Decl(i); :} ; /* produces a Java object of class Decl */
stmtList ::= /* empty list */ {: RESULT = new LinkedList<Stmt>(); :}
| stmt:s stmtList:l {: l.add(0,s); RESULT = l; :} ;
stmt ::= expr:e SEMICOLON {: RESULT = new ExprStmt(e); :}
| SEMICOLON {: RESULT = new EmptyStmt(); :}
| READ IDENT:i SEMICOLON {: RESULT = new ReadStmt(i); :}
| PRINT expr:e SEMICOLON {: RESULT = new PrintStmt(e); :}
| IF LPAREN expr:e RPAREN stmt:s {: RESULT = new IfStmt(e, s); :}
| IF LPAREN expr:e RPAREN stmt:s1 ELSE stmt:s2 {: RESULT = new IfStmt(e, s1, s2); :} ;
expr ::= INT_LITERAL:il {: RESULT = new IntLiteralExpr(il); :}
| IDENT:i {: RESULT = new IdentExpr(i); :}
| LPAREN expr:e RPAREN {: RESULT = e; :}
| binaryExpr:e {: RESULT = e; :} ;
binaryExpr ::= expr:e1 ADD expr:e2 {: RESULT = new BinaryExpr(e1, BinaryExpr.ADD, e2); :}
| expr:e1 MUL expr:e2 {: RESULT = new BinaryExpr(e1, BinaryExpr.MUL, e2); :}
| expr:e1 ASSIGN expr:e2 {: RESULT = new BinaryExpr(e1, BinaryExpr.ASSIGN, e2); :} ;
Some classes from package ast
class Program extends ASTNode {
public final List<Decl> dList; // list of declarations
public final List<Stmt> sList; // list of statements
public Program(List<Decl> dl, List<Stmt> sl) { dList = dl; sList = sl; }
public void print(PrintStream ps) {
ps.println("#include <stdio.h>");
ps.println("void main(void) {");
for (Decl d : dList) d.print(ps);
for (Stmt s : sList) s.print(ps," ");
ps.println("}"); } }
class Decl extends ASTNode {
public final String id;
public Decl(String i) { id = i; }
public void print(PrintStream ps) { ps.println(" int " + id + ";"); } }
abstract class Stmt extends ASTNode { public abstract void print(PrintStream ps, String space); }
class ExprStmt extends Stmt {
public final Expr expr;
public ExprStmt(Expr e) { expr = e; }
public void print(PrintStream ps, String space) { ps.print(space); expr.print(ps); ps.println(";"); } }
class IfStmt extends Stmt {
public final Expr expr;
public final Stmt thenStmt;
public final Stmt elseStmt; // null for if-then
public IfStmt(Expr e, Stmt ts) { expr = e; thenStmt = ts; elseStmt = null; }
public IfStmt(Expr e, Stmt ts, Stmt es) { expr = e; thenStmt = ts; elseStmt = es; }
public void print(PrintStream ps, String space) {
ps.print(space + "if ("); expr.print(ps); ps.println(")");
thenStmt.print(ps, space + " ");
if (elseStmt != null) { ps.println(space + "else"); elseStmt.print(ps, space + " "); } } }