1

I've written the decaf grammar specified in cs143 course.

Here is my code.

import sys

from lark import Lark, Transformer, v_args

decaf_grammar = r"""
    start : PROGRAM
    PROGRAM : DECL+
    DECL : VARIABLEDECL | FUNCTIONDECL | CLASSDECL | INTERFACEDECL
    VARIABLEDECL : VARIABLE ";"
    VARIABLE : TYPE  "ident"
    TYPE : "int" | "double" | "bool" | "string" | "ident" | TYPE "[]"
    FUNCTIONDECL : ( TYPE "ident"  "(" FORMALS ")" STMTBLOCK ) | ( "void" "ident" "(" FORMALS ")"  STMTBLOCK )
    FORMALS : VARIABLE ("," VARIABLE)*
    CLASSDECL : "class" "ident" ["extends" "ident"] ["implements" "ident" ("," "ident")*] "{" FIELD* "}"
    FIELD : VARIABLEDECL | FUNCTIONDECL
    INTERFACEDECL : "interface" "ident" "{" PROTOTYPE* "}"
    PROTOTYPE : (TYPE "ident" "(" FORMALS ")" ";") | ("void" "ident" "(" FORMALS ")" ";")
    STMTBLOCK : "{" VARIABLEDECL* STMT* "}"
    STMT : ( EXPR? ";") | IFSTMT | WHILESTMT | FORSTMT | BREAKSTMT | RETURNSTMT | RETURNSTMT | PRINTSTMT | STMTBLOCK
    IFSTMT : "if" "(" EXPR ")" STMT ["else" STMT]
    WHILESTMT : "while" "(" EXPR ")" STMT
    FORSTMT : "for" "(" EXPR? ";" EXPR ";" EXPR? ")" STMT
    RETURNSTMT :  "return" EXPR? ";"
    BREAKSTMT : "break" ";"
    PRINTSTMT : "print" "(" EXPR ("," EXPR)* ")" ";"
    EXPR : (LVALUE "=" EXPR) | CONSTANT | LVALUE | "this" | CALL | "(" EXPR ")" | (EXPR "+" EXPR) | (EXPR "-" EXPR) | (EXPR "*" EXPR) | (EXPR "/" EXPR) | (EXPR "%" EXPR) | ("-" EXPR) | (EXPR "<" EXPR) | (EXPR "<=" EXPR) | (EXPR ">" EXPR) | (EXPR ">=" EXPR) | (EXPR "==" EXPR) | (EXPR "!=" EXPR) | (EXPR "&&" EXPR) | (EXPR "||" EXPR) | ("!" EXPR) | ("ReadInteger" "(" ")") | ("ReadLine" "(" ")") | ("new" "ident") | ("NewArray" "(" EXPR "," TYPE ")")
    LVALUE : "ident" | (EXPR "." "ident") | (EXPR "[" EXPR "]")
    CALL : ("ident" "(" ACTUALS ")") | (EXPR "." "ident" "(" ACTUALS ")")
    ACTUALS : EXPR ("," EXPR)* | ""
    CONSTANT : "intConstant" | "doubleConstant" | "boolConstant" | "stringConstant" | "null" 

    """


class TreeToJson(Transformer):
    @v_args(inline=True)
    def string(self, s):
        return s[1:-1].replace('\\"', '"')


json_parser = Lark(decaf_grammar, parser='lalr', lexer='standard', transformer=TreeToJson())
parse = json_parser.parse


def test():
    test_json = '''
        {

        }
    '''

    j = parse(test_json)
    print(j)
    import json
    assert j == json.loads(test_json)


if __name__ == '__main__':
     test()
    #with open(sys.argv[1]) as f:
        #print(parse(f.read()))

It throws

RecursionError: maximum recursion depth exceeded.

I'm using lark for the first time

James Z
  • 12,209
  • 10
  • 24
  • 44
Umair Javaid
  • 421
  • 2
  • 7
  • 22

2 Answers2

0

The problem you have is that you don't feel the difference between lark's rules and terminals. Terminals (they are only should be named in capitals) should match string, not structure of your grammar.

The main terminal's property you must support is that they, unlike rules, are not "recursive". Because of that lark struggle to build your grammar and goes to infinite recursion and stackoverflow.

mingaleg
  • 2,017
  • 16
  • 28
0

try using sys.setrecursionlimit(xxxx) where xxxx is max recursion depth you want. To know more visit docs.python.org/3 .