【问题标题】:Tokenizing left over data with lex/yacc使用 lex/yacc 标记剩余数据
【发布时间】:2009-05-08 18:23:39
【问题描述】:

请原谅,我对解析和 lex/yacc 完全陌生,我可能有点不知所措,但尽管如此:

我正在用 PLY 编写一个非常基本的计算器,但它的输入可能并不总是一个方程,我需要在解析时确定它是否是。输入的极端情况是可以完美地计算为方程,它可以很好地解析和计算,或者与方程完全不同,解析失败但也很好。

灰色区域是一个具有等式部分的输入,解析器将抓取并计算出这些部分。这不是我想要的 - 我需要能够判断字符串的某些部分是否没有被拾取和标记,以便我可以抛出错误,但我不知道该怎么做。

有谁知道我如何定义,基本上,一个“抓住任何剩下的东西”令牌?或者有没有更好的方法可以解决这个问题?

【问题讨论】:

    标签: python yacc lex ply


    【解决方案1】:

    yacc 中有一个内置的error 令牌。您通常会执行以下操作:

    线路:好线 |坏线;

    badline : error '\n' /* 错误处理操作,如果需要 */

    goodline : 等式 '\n' ;

    任何与equation 不匹配的行都将由badline 处理。

    您可能希望在错误处理操作中使用yyerrok,以确保为下一行重置错误处理。

    【讨论】:

    • 这就是诀窍。我添加了一个刚刚返回 false 的 t_error 令牌,一切都发生得很完美。谢谢!
    【解决方案2】:

    定义一个标记(输入结束),并让您的词法分析器在输入结束时输出它。

    所以之前,如果你有这些令牌:

    '1' 'PLUS' '1'
    

    您现在将拥有:

    '1' 'PLUS' '1' 'END_OF_INPUT'
    

    现在,您可以在解析器中定义顶级规则。而不是(例如):

    Equation ::= EXPRESSION
    

    你会有

    Equation ::= EXPRESSION END_OF_INPUT
    

    显然,您必须用 PLY 语法重写这些,但这应该可以帮助您完成大部分工作。

    【讨论】:

    • 这也是标准 yacc 的工作方式 - 只有在没有更多令牌时才接受。
    【解决方案3】:

    我通常使用单独的“命令阅读器”来获取完整的命令——在你的情况下可能是一行——进入主变量字符串,然后安排词法分析器分析字符串,包括告诉我它什么时候没有。 t 到达终点。这很难设置,但会使某些类别的错误报告更容易。我经常使用这种技术的地方之一是多行命令,带有 3 个注释约定、两组引用的字符串,以及其他一些让我感到紧张的讨厌的东西(上下文敏感的标记化 - 糟糕!)。

    否则,Don 对 Yacc 'error' 令牌的建议是好的。

    【讨论】:

      【解决方案4】:

      您似乎已经找到了解决方案,但如果您或其他人对替代方法感兴趣,我会添加另一个建议。

      您说您正在使用 PLY,但那是因为您希望编译器在 Python 环境中运行吗?如果是这样,您也可以考虑使用其他工具。对于此类工作,我经常使用具有 Python 代码生成器的 ANTLR (http://www.antlr.org)。 ANTLR 有很多技巧可以做一些事情,比如在词法分析器级别吃一堆输入,所以解析器永远不会看到它(例如 cmets),能够在更大的语法中调用子规则(例如方程)(一旦规则已匹配,无需处理任何更多输入...听起来有点像您想要做的)和一个非常好的左因子算法。

      ANTLRs 解析能力与 StringTemplate (http://www.stringtemplate.org) 引擎的使用相得益彰,两者都支持 Python(以及许多其他)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-05
        • 1970-01-01
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多