代码之家  ›  专栏  ›  技术社区  ›  Eli Bendersky

ply:C解析器中的令牌移位问题

  •  3
  • Eli Bendersky  · 技术社区  · 17 年前

    我正在使用ply编写C解析器,最近遇到了一个问题。 此代码:

    typedef int my_type;
    my_type x;
    

    是正确的C代码,因为我的类型是以前定义为 被这样使用。我通过在 lexer用来区分类型和 简单标识符。

    然而,当类型声明规则以分号(“;”标记)结束时,ply移动标记 my_type 从第二行开始,然后决定用第一行完成。因此,我没有机会将类型符号表中的更新传递给lexer和它 将我的类型视为标识符而不是类型。

    有什么解决办法吗?

    完整代码位于: http://code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py 不知道如何从中创建一个较小的示例。

    编辑:

    问题解决了。请参阅下面的解决方案。

    3 回复  |  直到 13 年前
        1
  •  3
  •   paxdiablo    13 年前

    不知道你为什么要在你的lexer里做那样的分析。

    可能应该使用词汇分析将输入流分离为词汇标记(数字、行更改、关键字等)。它是解析阶段,应该执行该级别的分析,包括typedef等的表查找。

    这就是我将lexx和yacc(我选择的工具)之间的职责分离的方式。

        2
  •  2
  •   Eli Bendersky    17 年前

    some help 从戴夫比兹利(ply的创造者),我的问题解决了。

    其思想是使用特殊的子规则并在其中执行操作。在我的案例中,我将 declaration 规则到:

    def p_decl_body(self, p):
        """ decl_body : declaration_specifiers init_declarator_list_opt
        """
        # <<Handle the declaration here>>        
    
    def p_declaration(self, p):
        """ declaration : decl_body SEMI 
        """
        p[0] = p[1]
    

    decl_body 总是在半移动后的令牌之前减少,因此我的操作将在正确的时间执行。

        3
  •  1
  •   Mike G.    17 年前

    我认为您需要将ID是否是typeID的检查从c lexer.py移到c_parser.py。

    正如您所说的,由于解析器正在寻找1个令牌,所以您不能在lexer中做出这个决定。

    相反,更改您的解析器来检查ID,看看它们在声明中是否是typeID,如果不是,则生成一个错误。

    正如Pax Diablo在他出色的回答中所说的那样,lexer/tokenizer的工作不是做出关于token的那种决定。这就是解析器的工作。

    推荐文章