如何使用PLY(Python Lex-Yacc)丢弃语法文件中的非终端

时间:2012-02-27 09:43:12

标签: python yacc lex ply

使用PLY时遇到问题。 我想通过PLY创建一个调用图生成器。 在某些情况下,我需要丢弃语法文件中的一些令牌。 那是因为我需要在解析器丢弃它之前识别该令牌时做一些事情,所以 我不能在lexer文件中丢弃。 例如,'IF'标记是我想要丢弃的标记。 所以我尝试做一些事情在语法文件中丢弃它。 就像:

def p_if(p):
    'if : IF'
    print "if"
    parser.symstack.pop()

但事情并没有像我想的那样。 我打印symstack(它是解析器的一个属性,解析器是yacc.py的LRParser实例), symstack列表只包含以前的标记,但不包含“if”。 所以我想知道在这种情况下如何丢弃令牌。 谁能帮助我?非常感谢!

2 个答案:

答案 0 :(得分:1)

你刚才问过这个问题,但没有任何评论或答案。这是一个可能的解释原因。

我正在查看http://www.dabeaz.com/ply/ply.html中的文档。那里没有关于操纵parser.symstack的东西。它似乎不是一个暴露的,有文档记录的界面。

即。你把叉子插入烤面包机。

如果您搞乱其内部数据结构,或者它可能会破坏下一版本的解析器生成器等,那么解析器可能会感到困惑吗?此外,您没有充分解释您正在尝试做什么。丢弃非终结符号的目的是什么,这究竟是什么意思?那些情况是什么,问题是什么?也许问题可以解决,而不需要进入解析器对象。

此外,没有记录的全局解析器对象。您必须已经定义了此解析器变量,例如“parser = yacc.yacc()”(在第7节:多个分析器和词典中记录)。既然你在解析器规则本身中引用了这个变量,那么这看起来非常糟糕。规则有一种正确的方式来引用解析器,这是通过它们接收的p参数:你想要p.parser。 (再次记录在第7节)。

答案 1 :(得分:0)

非常感谢!! 实际上,我找到了解决问题的方法。 你是对的,不应该操纵parser.symstack。 因为我的英语不好(我母语不是英语),所以我没有解释 我的问题很清楚。但我仍然感谢您的建议。 以下是我的解决方案,我希望这将有助于其他人。

予。定义p_error(p)函数

def p_error(p):
tok = yacc.token() # Get the next token
yacc.errok()
return tok #Return the next token

II。在您需要的函数中引发语法错误

def p_somerule(p):
' a : A '
raise SyntaxError