【问题标题】:Why does Python's PLY stop parsing at an $end token?为什么 Python 的 PLY 在 $end 标记处停止解析?
【发布时间】:2013-07-22 06:34:53
【问题描述】:

我在我的语法上运行 Python 的 PLY 库。它似乎可以编译,并且库不会提醒我任何 shift/reduce 或 reduce/reduce 错误。但是,在一个非常简单的示例上运行会引发错误。

深入parser.out文件发现错误发生在程序的最后:

State  : 113
Stack  : DEFN ID ARROW type invariants statement . $end
ERROR: Error  : DEFN ID ARROW type invariants statement . $end
Syntax error at: None

状态 113 在哪里:

state 113

    (16) fn_def -> DEFN ID ARROW type invariants statement .
    (24) tilde_loop -> statement . TILDE constant TILDE

    SEMICOLON       reduce using rule 16 (fn_def -> DEFN ID ARROW type inva\
riants statement .)
    TILDE           shift and go to state 62

据我所知,解析器应该减少到fn_def

为什么到达$end 令牌时不会发生reduce?

(如果有帮助,我可以粘贴我的语法,虽然它可能有点长。)

语法

Rule 0     S' -> program
Rule 1     program -> statement_list
Rule 2     statement -> definition SEMICOLON
Rule 3     statement -> expression SEMICOLON
Rule 4     statement -> control_statement
Rule 5     statement -> compound_statement
Rule 6     statement -> comment
Rule 7     statement -> empty SEMICOLON
Rule 8     statement_list -> statement_list statement
Rule 9     statement_list -> statement
Rule 10    control_statement -> loop
Rule 11    control_statement -> if_statement
Rule 12    compound_statement -> CURLY_OPEN statement_list CURLY_CLOSE
Rule 13    compound_statement -> CURLY_OPEN CURLY_CLOSE
Rule 14    definition -> fn_def
Rule 15    definition -> var_def
Rule 16    fn_def -> DEFN ID ARROW type invariants statement
Rule 17    var_def -> type assignment
Rule 18    assignment -> ID ASSIGN expression
Rule 19    loop -> for_loop
Rule 20    loop -> foreach_loop
Rule 21    loop -> tilde_loop
Rule 22    for_loop -> FOR statement statement statement compound_statement
Rule 23    foreach_loop -> FOREACH ID IN expression compound_statement
Rule 24    tilde_loop -> statement TILDE constant TILDE
Rule 25    if_statement -> IF condition compound_statement
Rule 26    if_statement -> IF condition compound_statement elseif_list
Rule 27    if_statement -> IF condition compound_statement elseif_list else
Rule 28    if_statement -> ternary
Rule 29    elseif_list -> ELSEIF condition compound_statement
Rule 30    elseif_list -> ELSEIF condition compound_statement elseif_list
Rule 31    else -> ELSE compound_statement
Rule 32    ternary -> condition QUESTION_MARK expression COLON expression
Rule 33    invariants -> invariants invariant
Rule 34    invariants -> invariant
Rule 35    invariants -> NONE
Rule 36    invariant -> type ID COLON invariant_tests
Rule 37    invariant_tests -> invariant_tests COMMA test
Rule 38    invariant_tests -> test
Rule 39    test -> ID operator constant
Rule 40    test -> STAR
Rule 41    expression -> declarator
Rule 42    expression -> assignment
Rule 43    expression -> container
Rule 44    expression -> test
Rule 45    expression -> constant
Rule 46    type -> INT_T
Rule 47    type -> DBL_T
Rule 48    type -> STR_T
Rule 49    type -> list_type
Rule 50    operator -> GT_OP
Rule 51    operator -> LT_OP
Rule 52    operator -> GTE_OP
Rule 53    operator -> LTE_OP
Rule 54    operator -> EQ_OP
Rule 55    operator -> NEQ_OP
Rule 56    constant -> INT
Rule 57    constant -> DBL
Rule 58    constant -> STR
Rule 59    declarator -> ID L_PAREN fn_args R_PAREN
Rule 60    declarator -> ID
Rule 61    fn_args -> fn_args COMMA expression
Rule 62    fn_args -> expression
Rule 63    container -> list
Rule 64    list -> L_BRACE container_items R_BRACE
Rule 65    list_type -> L_BRACE type R_BRACE
Rule 66    container_items -> container_items COMMA container_item
Rule 67    container_items -> container_item
Rule 68    container_item -> expression
Rule 69    container_item -> empty
Rule 70    bool -> TRUE
Rule 71    bool -> FALSE
Rule 72    condition -> bool
Rule 73    comment -> single_comment
Rule 74    single_comment -> COMMENT_LINE
Rule 75    empty -> <empty>

【问题讨论】:

    标签: python parsing compiler-construction grammar ply


    【解决方案1】:

    似乎它需要一个分号,并且它有输入结束。不看语法很难说更多。

    语法的相关部分:

     (2) statement -> definition SEMICOLON
    (14) definition -> fn_def
    

    这些是仅有的 fn_defdefinition 出现在右侧的作品。

    显然definition 只能在前瞻令牌为SEMICOLON 时减少为statement。由于fn_def只能出现在有效程序中可以立即简化为definition的地方(唯一的产生是单元产生),fn_def后面必须跟SEMICOLON。所以你的解析器是正确的,你的示例输入是不合语法的。

    fn_def 只有一个产品:

    (16) fn_def -> DEFN ID ARROW type invariants statement
    

    很明显fn_def 中的最后一项是statement。某些语句(definitionexpression)必须以 ; 结尾;如果fn_defstatement 是其中之一(可能是一个表达式,因为它看起来不像单个定义会产生有趣的函数体),那么fn_def 将必须用两个分号编写。我怀疑这是否是你想要的。

    definitionstatement(如果是fn_def)或expression(如果是var_def)结尾。您已尝试定义 statement 以便它是自定界的(即,如果它不以终止 compound_statement} 结尾,则以分号结尾。所以 fn_def 已经以分号结尾或右大括号,并且不需要另一个分号。另一方面,var_def 以表达式结尾,因此也是如此。因此一种解决方案是将右分号推入 var_def

    编辑评论,与所问的具体问题无关:

    事实上,除了你自己的审美之外,没有明显的理由需要将循环体或条件体限制为复合语句;如果您允许 lambda 主体成为非复合语句,则没有明显的理由限制 for 循环。语法可以以任何一种方式工作。

    【讨论】:

    • 我已经编辑了我的语法,但它又长又丑。是什么让您认为它需要分号?
    • @sdasdadas:因为状态 113 表示只有在前瞻为分号时才会减少
    • 感谢您的回答和最后的评论。你对我所有关于语法的问题都提供了难以置信的帮助。关于您的评论,我看到程序员在控制结构中使用单个语句然后附加另一条语句弹出一些错误,认为它也将在控制结构中。但我没有远见或经验知道这是否会对我的语法产生任何影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2013-10-21
    • 2021-04-11
    相关资源
    最近更新 更多