我试图用Python编写一个解析器,用PLY编写一种组合语言。我的BNF的简化版本如下:

statement-list -> statement ',' statement-list |
                 'print' expr

statement -> ident 'was' 'a' type |
             ident 'became' expr

type -> 'number' | 'letter'

expr -> factor |
       expr '+' factor |
       expr '-' factor

factor -> number | letter | ident

其中数字和字母类似于int和char。

def p_expression_plus(p):
   'expression : expression PLUS term'
    p[0] = p[1] + p[3]

?I've got:
def p_statement_list_comma(p):
    'statement-list : statement COMMA statement-list'

但我真的不知道接下来该放什么。
任何帮助都将不胜感激!

最佳答案

这实际上取决于你如何构造你的代码以及你想如何评估它。如果您在进行评估时,如果它的评估顺序正确,那么您可能不希望在p_statement_list_comma的docstring之后得到任何东西,也就是说,就像您得到它的方式一样,无论如何,语句都将被评估,如果需要,您可以保留变量的全局字典或类似的东西来跟踪某些状态,如标识符值。
If you want to build up a parse tree e.g. for evaluation separately if you don't like ply's order of evaluation, you might do something like this:

def p_statement_list_comma(p):
    'statement-list : statement COMMA statement-list'
    p[0] = [p[1]] + p[3]

def p_statement_print_expr(p):
    'statement-list : PRINT expr'
    p[0] = [p[2]]

。。
如果希望从yacc.parse返回打印表达式的结果(来自解析树顶层的值将从yacc.parse返回),可以这样做:
def p_statement_list_comma(p):
    'statement-list : statement COMMA statement-list'
    p[0] = p[3]

def p_statement_print_expr(p):
    'statement-list : PRINT expr'
    p[0] = p[2]

10-08 13:02