From cf3bd4d7457356b3f53056652943fa9beebfbfe8 Mon Sep 17 00:00:00 2001 From: Sanjar Ahmadov Date: Fri, 19 Feb 2021 18:44:22 -0500 Subject: [PATCH] Finished all grammar - passes 24 test cases --- src/main/cup/chocopy/pa1/ChocoPy.cup | 150 ++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 28 deletions(-) diff --git a/src/main/cup/chocopy/pa1/ChocoPy.cup b/src/main/cup/chocopy/pa1/ChocoPy.cup index fb1f495..40f819a 100644 --- a/src/main/cup/chocopy/pa1/ChocoPy.cup +++ b/src/main/cup/chocopy/pa1/ChocoPy.cup @@ -237,19 +237,25 @@ terminal UNRECOGNIZED; * of type . */ non terminal Program program; non terminal List program_head, class_body, class_body_defs, fun_body_decs; -non terminal List stmt_list, opt_stmt_list; -non terminal Stmt stmt, expr_stmt; -non terminal Expr expr, binary_expr; +non terminal List stmt_list, opt_stmt_list, block, else_body; +non terminal Stmt stmt, simple_stmt; +non terminal Expr expr, binary_expr, pexpr, cexpr, cmp_pexpr; non terminal VarDef var_def; non terminal ClassDef class_def; non terminal FuncDef fun_def; non terminal Literal literal; +non terminal StringLiteral bin_op, comp_op; non terminal TypedVar typed_var; non terminal TypeAnnotation type, ret_type; non terminal Identifier identifier; non terminal List typed_vars; non terminal GlobalDecl global_decl; non terminal NonLocalDecl nonlocal_decl; +non terminal List opt_target, expr_list; +non terminal Expr target; +non terminal MemberExpr member_expr; +non terminal IndexExpr index_expr; + @@ -262,6 +268,7 @@ precedence nonassoc EQUAL, NEQ, LT, GT, LEQ, GEQ, IS; precedence left PLUS, MINUS; precedence left MUL, DIV, MOD; precedence left DOT, COMMA, LBR, RBR; +precedence left IF, ELSE; /* The start symbol. */ start with program; @@ -284,6 +291,10 @@ program_head ::= program_head:d var_def:vd {: RESULT = combine(d, v | program_head:d error:e {: RESULT = d; :} | {: RESULT = empty(); :} ; + +opt_stmt_list ::= {: RESULT = empty(); :} + | stmt_list:s {: RESULT = s; :} + ; /* class_def */ @@ -318,8 +329,7 @@ typed_vars ::= typed_var:tv {: RESULT= single(tv | {: RESULT= empty(); :} ; - - + /* fun_body */ fun_body_decs ::= fun_body_decs:fbd global_decl:gd {: RESULT= combine(fbd, gd); :} | fun_body_decs:fbd nonlocal_decl:nd {: RESULT= combine(fbd, nd); :} @@ -353,46 +363,130 @@ nonlocal_decl ::= NONLOCAL:n identifier:id NEWLINE {: RESULT = new NonLoc var_def ::= typed_var:t ASSIGN literal:l NEWLINE {: RESULT = new VarDef(txleft, lxright, t, l); :}; +/* stmt */ +stmt ::= simple_stmt:s NEWLINE {: RESULT = s; :} + | IF:i expr:cond COLON block:b else_body:elb {: RESULT = new IfStmt(ixleft, getRight(elb), cond, b, elb); :} + | WHILE:wh expr:cond COLON block:b {: RESULT = new WhileStmt(whxleft, getRight(b), cond, b); :} + | FOR:f identifier:id IN expr:e COLON block:b {: RESULT = new ForStmt(fxleft, getRight(b), id, e, b); :} + ; + + +else_body ::= ELSE:el COLON block:b {: RESULT = b; :} + | ELIF:el expr:cond COLON block:b else_body:elb {: RESULT = single(new IfStmt(elxleft, getRight(elb), cond, b, elb)); :} + | {: RESULT = empty(); :} + ; + +/* simple_stmt */ +simple_stmt ::= PASS:p {: RESULT = null; :} + | expr:e {: RESULT = new ExprStmt(exleft, exright, e); :} + | RETURN:r expr:e {: RESULT = new ReturnStmt(rxleft, exright, e); :} + | RETURN {: RESULT = null; :} + | opt_target:ot expr:e {: RESULT = new AssignStmt(getLeft(ot), exright, ot, e); :} + ; + + +opt_target ::= opt_target:ot target:t ASSIGN {: RESULT = combine(ot, t); :} + | target:t ASSIGN {: RESULT = single(t); :} + ; + + +/* block */ +block ::= NEWLINE INDENT stmt_list:sl DEDENT {: RESULT = sl; :}; + + /* literal */ literal ::= NONE:n {: RESULT = new NoneLiteral(nxleft, nxright); :} | BOOL:b {: RESULT = new BooleanLiteral(bxleft, bxright, b); :} | NUMBER:n {: RESULT = new IntegerLiteral(nxleft, nxright, n); :} | STRING:s {: RESULT = new StringLiteral(sxleft, sxright, s); :} ; + + +/* expr */ +expr ::= pexpr:ce {: RESULT = ce; :} + | NOT:n expr:exp {: RESULT = new UnaryExpr(nxleft, expxright, n, exp); :} + | expr:e1 AND:a expr:e2 {: RESULT = new BinaryExpr(e1xleft, e2xright, e1, a, e2); :} + | expr:e1 OR:o expr:e2 {: RESULT = new BinaryExpr(e1xleft, e2xright, e1, o, e2); :} + | expr:e1 IF expr:e2 ELSE expr:e3 {: RESULT = new IfExpr(e1xleft, e3xright, e2, e1, e3); :} + ; -opt_stmt_list ::= {: RESULT = empty(); :} - | stmt_list:s {: RESULT = s; :} - ; +/* cexpr */ +/* +cexpr ::= pexpr:pe {: RESULT = new Expr(pexleft, pexright); :} + | cmp_pexpr:cp {: RESULT = new Expr(cpxleft, cpxright); :} + ; -stmt_list ::= stmt:s {: RESULT = single(s); :} - | stmt_list:l stmt:s {: RESULT = combine(l, s); :} - | stmt_list:l error {: RESULT = l; :} - /* If there is a syntax error in the source, this says to discard - * symbols from the parsing stack and perform reductions until - * there is a stmt_list on top of the stack, and then to discard - * input symbols until it is possible to shift again, reporting - * a syntax error. */ + +cmp_pexpr ::= pexpr:p comp_op:co cmp_pexpr:p2 {: RESULT = new BinaryExpr(p1xleft, p2xright, p1, co, p2); :} + | pexpr:p {: RESULT = new Expr(pxleft, pxright); :} + ; +*/ + +/* pexpr */ +pexpr ::= identifier:id {: RESULT = id; :} + | literal:l {: RESULT = l; :} + | LBR:lbr expr_list:l RBR:rbr {: RESULT = new ListExpr(lbrxleft, rbrxright, l); :} + | LPAR:lpar expr:e RPAR:rpar {: RESULT = e; :} + | member_expr:m {: RESULT = m; :} + | index_expr:i {: RESULT = i; :} + | member_expr:m LPAR expr_list:l RPAR:rpar {: RESULT = new MethodCallExpr(mxleft, rparxright, m, l); :} + | identifier:id LPAR expr_list:l RPAR:rpar {: RESULT = new CallExpr(idxleft, rparxright, id, l); :} + | pexpr:p1 bin_op:bo pexpr:p2 {: RESULT = new BinaryExpr(p1xleft, p2xright, p1, bo.value, p2); :} + | MINUS:m pexpr:p {: RESULT = new UnaryExpr(mxleft, pxright, m, p); :} + | pexpr:p1 comp_op:co pexpr:p2 {: RESULT = new BinaryExpr(p1xleft, p2xright, p1, co.value, p2); :} + ; + +expr_list ::= expr:e {: RESULT = single(e); :} + | expr_list:el COMMA expr:e {: RESULT = combine(el, e); :} + | {: RESULT = null; :} ; -stmt ::= expr_stmt:s NEWLINE {: RESULT = s; :} - ; -expr_stmt ::= expr:e {: RESULT = new ExprStmt(exleft, exright, e); :} - ; +/* bin_op */ +bin_op ::= PLUS:a {: RESULT = new StringLiteral(axleft, axright, "+"); :} + | MINUS:a {: RESULT = new StringLiteral(axleft, axright, "-"); :} + | MUL:a {: RESULT = new StringLiteral(axleft, axright, "*"); :} + | DIV:a {: RESULT = new StringLiteral(axleft, axright, "/"); :} + | MOD:a {: RESULT = new StringLiteral(axleft, axright, "%"); :} + ; -expr ::= binary_expr:e {: RESULT = e; :} - | NUMBER:n {: RESULT = new IntegerLiteral(nxleft, nxright, n); :} - ; +/* comp_op */ +comp_op ::= EQUAL:a {: RESULT = new StringLiteral(axleft, axright, "=="); :} + | NEQ:a {: RESULT = new StringLiteral(axleft, axright, "!="); :} + | LEQ:a {: RESULT = new StringLiteral(axleft, axright, "<="); :} + | GEQ:a {: RESULT = new StringLiteral(axleft, axright, ">="); :} + | LT:a {: RESULT = new StringLiteral(axleft, axright, "<"); :} + | GT:a {: RESULT = new StringLiteral(axleft, axright, ">"); :} + | IS:a {: RESULT = new StringLiteral(axleft, axright, "is"); :} + ; + +/* member_expr */ +member_expr ::= pexpr:p DOT identifier:id {: RESULT = new MemberExpr(pxleft, idxright, p, id); :} + ; -/* A binary expression, illustrating how to find the left and right - * source position of a phrase. */ -binary_expr ::= expr:e1 PLUS:op expr:e2 - {: RESULT = new BinaryExpr(e1xleft, e2xright, - e1, op, e2); :} +/* index_expr */ +index_expr ::= pexpr:p LBR expr:e RBR:rbr {: RESULT = new IndexExpr(pxleft, rbrxright, p, e); :} ; + +/* target */ +target ::= identifier:id {: RESULT = id; :} + | member_expr:m {: RESULT = m; :} + | index_expr:i {: RESULT = i; :} + ; /* Extras - rules below have not been given in language reference, we have them to ease implementation */ identifier ::= ID:idStr {: RESULT = new Identifier(idStrxleft, idStrxright, idStr); :}; + + +stmt_list ::= stmt:s {: RESULT = single(s); :} + | stmt_list:l stmt:s {: RESULT = combine(l, s); :} + | stmt_list:l error {: RESULT = l; :} + /* If there is a syntax error in the source, this says to discard + * symbols from the parsing stack and perform reductions until + * there is a stmt_list on top of the stack, and then to discard + * input symbols until it is possible to shift again, reporting + * a syntax error. */ + ; \ No newline at end of file