简体   繁体   English

yacc无法减少(Python Lex-Yacc)

[英]yacc fails to reduce (Python Lex-Yacc)

I'm trying to write a fairly simple grammar with PLY (python implementation of yacc) , and am having trouble getting yacc to reduce strings of tokens when I want it to. 我正在尝试使用PLY(yacc的python实现)编写一个相当简单的语法,并且在我希望获得yacc来减少令牌字符串时遇到麻烦。

I want to interpret a series of commands that take different kinds of arguments. 我想解释一系列采用不同类型参数的命令。 Each different kind of argument has a different token. 每种不同的参数都有不同的标记。 The string of tokens that comes out of lex might look like this: lex产生的标记字符串可能看起来像这样:

COMMAND VARARG VARARG STRARG
COMMAND VARARG STRARG STRARG

I want yacc to reduce each of those lines into a rule called instruction . 我希望yacc将这些行中的每一行都简化为称为instruction的规则。 However, yacc refuses to stop reducing the first line after the last argument ( STRARG ) and generates a syntax error because of the unexpected COMMAND token. 但是,由于意外的COMMAND令牌, yacc拒绝停止在最后一个参数( STRARG )之后减少第一行,并生成语法错误。

That is, instead of reducing COMMAND VARARG VARARG STRARG to instruction , yacc shifts one more time to get COMMAND VARARG VARARG STRARG COMMAND (picking up the last COMMAND from the next line, which shouldn't have been read). 也就是说, yaccCOMMAND VARARG VARARG STRARGinstruction ,而是转移了一个更多的时间来获取COMMAND VARARG VARARG STRARG COMMAND (从下一行选择最后一个COMMAND ,这本来不应该被阅读)。

The yacc portion of my code looks like this: 我的代码的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

Am I making some obvious error in my rule specifications? 我在规则说明中犯了一些明显的错误吗? This is the first time I've used lex / yacc , so I wouldn't be surprised. 这是我第一次使用lex / yacc ,所以我不会感到惊讶。

You need to include additional rules for handling multiple instructions, so yacc will know what to do with that second COMMAND token. 您需要包括用于处理多个指令的其他规则,以便yacc知道如何处理第二个COMMAND令牌。 Something like below should work. 像下面这样的东西应该起作用。

instructions : instructions '\n' instruction
             | instruction

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

See http://luv.asn.au/overheads/lex_yacc/yacc.html#recusive 参见http://luv.asn.au/overheads/lex_yacc/yacc.html#recusive

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM