yacc无法归约(Python Lex-Yacc)

1 投票
1 回答
768 浏览
提问于 2025-04-16 11:06

我正在尝试用PLY(Python实现的yacc)写一个相对简单的语法,但在让yacc正确处理一串令牌时遇到了问题。

我想解析一系列命令,这些命令需要不同类型的参数。每种参数类型都有不同的令牌。从lex输出的令牌串可能看起来像这样:

COMMAND VARARG VARARG STRARG
COMMAND VARARG STRARG STRARG

我希望yacc能把这些行简化成一个叫instruction的规则。然而,yacc不愿意在最后一个参数(STRARG)后停止简化第一行,结果因为意外的COMMAND令牌产生了语法错误。

也就是说,yacc没有把COMMAND VARARG VARARG STRARG简化成instruction,而是多处理了一次,变成了COMMAND VARARG VARARG STRARG COMMAND(把下一行的最后一个COMMAND也读进来了,这本不该发生)。

我代码中的yacc部分看起来是这样的:

def p_rule1(p):
    r'instruction : COMMAND VARARG VARARG STRARG'

    # do stuff

def p_rule2(p):
    r'instruction : COMMAND VARARG STRARG STRARG'

    # do other stuff

我在规则定义上是不是犯了什么明显的错误?这是我第一次使用lex/yacc,所以我不会感到惊讶。

1 个回答

1

你需要添加一些额外的规则来处理多个指令,这样yacc才能知道该如何处理第二个COMMAND标记。下面的代码应该可以解决这个问题。

instructions : instructions '\n' instruction
             | instruction

instruction : COMMAND VARARG VARARG STRARG
            { do stuff }
            | COMMAND VARARG STRARG STRARG
            {do other stuff }

可以查看这个链接了解更多信息:http://luv.asn.au/overheads/lex_yacc/yacc.html#recusive

撰写回答