简体   繁体   English

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

[英]How to discard non-terminal in grammar file with PLY (Python Lex-Yacc)

I have faced a problem when using PLY. 我在使用PLY时遇到了问题。 I want to create a call graph generator by PLY. 我想通过PLY创建一个调用图生成器。 In some situation, I need to discard some tokens in the grammar file. 在某些情况下,我需要丢弃语法文件中的一些令牌。 That is because I need to do something when the parser recognize that token before I discard it, so I can't just discard in the lexer file. 这是因为我需要在解析器丢弃它之前识别该令牌时执行某些操作,因此我不能在lexer文件中丢弃它。 For example, the 'IF' token is the one which I want to discard. 例如,'IF'标记是我想要丢弃的标记。 So I try to do something to discard it in the grammar file. 所以我尝试做一些事情在语法文件中丢弃它。 Just like: 就像:

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

But things didn't go the way I think. 但事情并没有像我想的那样。 I print the symstack(it's a atribute of parser, and parser is a LRParser instance of yacc.py), and the symstack list just contain the previous tokens but not 'if'. 我打印symstack(它是解析器的属性,解析器是yacc.py的LRParser实例),symstack列表只包含先前的令牌但不包含'if'。 So I am wondering how to discard a token in this situation. 所以我想知道在这种情况下如何丢弃令牌。 Could anyone help me? 谁能帮助我? Thanks a lot! 非常感谢!

You asked this a while ago and yet no comments or answers. 你刚才问过这个问题,但没有任何评论或答案。 Here is a possible explanation why. 这是一个可能的解释原因。

I'm looking at the documentation in http://www.dabeaz.com/ply/ply.html . 我正在查看http://www.dabeaz.com/ply/ply.html中的文档。 There is nothing there about manipulating the parser.symstack. 那里没有关于操纵parser.symstack的东西。 It does not appear to be an exposed, documented interface. 它似乎不是一个暴露的,有文档记录的界面。

Ie you're sticking a fork into a toaster. 即你把叉子插入烤面包机。

Don't you tink the parser might be confused if you mess with its internal data structure, or that it might break with the next version of the parser generator, etc? 如果您搞乱其内部数据结构,或者它可能会破坏下一版本的解析器生成器等,那么解析器可能会感到困惑吗? Also, you don't adequately explain what you're trying to do. 此外,您没有充分解释您正在尝试做什么。 What is the objective of discarding the nonterminal symbols, and what exactly does that mean? 丢弃非终结符号的目的是什么,这究竟是什么意思? What are those situations and what is the problem? 那些情况是什么,问题是什么? Maybe the problem can be solved without poking into the parser object. 也许问题可以解决,而不需要进入解析器对象。

Also, there isn't a documented global parser object. 此外,没有记录的全局解析器对象。 You must have defined this parser variable like this "parser = yacc.yacc()" (documented in Section 7: Multiple Parsers and Lexers). 您必须已经定义了此解析器变量,例如“parser = yacc.yacc()”(在第7节:多个分析器和词典中记录)。 Since you then refer to this variable in the the parser rules themselves, that appears to be very kludgy. 既然你在解析器规则本身中引用了这个变量,那么这看起来非常糟糕。 There is a proper way for rules to refer to the parser, and that is through the p parameter they receive: you want p.parser. 规则有一种正确的方式来引用解析器,这是通过它们接收的p参数:你想要p.parser。 (Documented in Section 7, again). (再次记录在第7节)。

Thanks a lot!! 非常感谢!! Actually, I have found a way to solve my problem. 实际上,我找到了解决问题的方法。 You are right, the parser.symstack should never be manipulated. 你是对的,不应该操纵parser.symstack。 Because my English is not good(my mother language is not English), I didn't explain my problem clearly.But I still appreciate for your advice. 因为我的英语不好(我母语不是英语),所以我没有清楚地解释我的问题。但我仍然感谢你的建议。 The following is my solution, and I hope this will help someone else in the future. 以下是我的解决方案,我希望这将有助于其他人。

I. define p_error(p) function I.定义p_error(p)函数

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

II. II。 raise syntax error in the function you need 在您需要的函数中引发语法错误

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

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

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