4

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

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

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

4

2 回答 2

1

您前段时间问过这个问题,但没有任何评论或答案。这是一个可能的解释。

我正在查看http://www.dabeaz.com/ply/ply.html中的文档 。没有关于操纵 pa​​rser.symstack 的内容。它似乎不是一个公开的、记录在案的界面。

即,您将叉子插入烤面包机。

如果您弄乱了解析器的内部数据结构,或者它可能会与解析器生成器的下一个版本中断等,您难道不觉得解析器可能会感到困惑吗?此外,您没有充分解释您要做什么。丢弃非终结符的目的是什么,这到底是什么意思?这些情况是什么,有什么问题?也许问题可以在不深入解析器对象的情况下解决。

此外,没有记录在案的全局解析器对象。您必须像“parser = yacc.yacc()”这样定义这个解析器变量(在第 7 节:多个解析器和词法分析器中记录)。由于您随后在解析器规则本身中引用了此变量,因此这似乎非常笨拙。规则有一种正确的方法来引用解析器,那就是通过它们收到的 p 参数:你想要 p.parser。(再次记录在第 7 节中)。

于 2012-03-06T22:17:19.807 回答
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

二、在您需要的函数中引发语法错误

def p_somerule(p):
' a : A '
raise SyntaxError
于 2012-03-10T14:28:32.610 回答