RecursionError: максимальная глубина рекурсии превышена при использовании lark в python - PullRequest
0 голосов
/ 09 декабря 2018

Я написал грамматику без кофеина, указанную в cs143 course .

Вот мой код.

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()))

Выдает

RecursionError: превышена максимальная глубина рекурсии.

Я впервые использую жаворонок

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

попробуйте использовать sys.setrecursionlimit(xxxx), где xxxx - это максимальная глубина рекурсии, которую вы хотите.Чтобы узнать больше, посетите docs.python.org / 3 .

0 голосов
/ 09 декабря 2018

Проблема в том, что вы не чувствуете разницы между правилами жаворонка и терминалами.Терминалы (они должны быть названы только прописными буквами) должны соответствовать строке, а не структуре вашей грамматики.

Главное свойство терминала, которое вы должны поддерживать, состоит в том, что они, в отличие от правил, не являются "рекурсивными".Из-за этого lark изо всех сил пытается построить свою грамматику и перейти к бесконечной рекурсии и стеку переполнению .

...