为什么Python';在$end标记处停止解析吗?

为什么Python';在$end标记处停止解析吗?,python,parsing,compiler-construction,grammar,ply,Python,Parsing,Compiler Construction,Grammar,Ply,我正在根据语法运行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 .

我正在根据语法运行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>
规则0s'->程序
规则1程序->语句列表
规则2语句->定义分号
规则3语句->表达式分号
规则4语句->控制语句
规则5语句->复合_语句
规则6语句->注释
规则7语句->空分号
规则8语句列表->语句列表语句
规则9语句列表->语句
规则10控制语句->循环
规则11控制\u语句->如果\u语句
规则12复合语句->卷曲打开语句列表卷曲关闭
规则13复合语句->卷曲打开卷曲关闭
规则14定义->fn_定义
规则15定义->变量定义
规则16 fn_def->DEFN ID箭头类型不变量语句
规则17变量定义->类型分配
规则18分配->ID分配表达式
规则19循环->for_循环
规则20循环->foreach\u循环
规则21循环->平铺循环
规则22 for_循环->for语句复合_语句
规则23 foreach_循环->表达式复合_语句中的foreach ID
规则24 tilde_循环->语句tilde常量tilde
规则25 if_语句->if条件复合_语句
规则26 if_语句->if条件复合_语句其他列表
规则27 if_语句->if条件复合_语句elseif_列表else
规则28 if_语句->三元
规则29 elseif_列表->elseif条件复合_语句
规则30 elseif_列表->elseif条件复合_语句elseif_列表
规则31 else->else复合语句
规则32三元->条件问号表达式冒号表达式
规则33不变量->不变量不变量
规则34不变量->不变量
规则35不变量->无
规则36不变量->类型ID冒号不变量\u测试
规则37不变测试->不变测试逗号测试
规则38不变量测试->测试
规则39测试->ID运算符常量
规则40测试->星
规则41表达式->声明符
规则42表达式->赋值
规则43表达式->容器
规则44表达式->测试
规则45表达式->常量
规则46类型->整数
规则47类型->数据库
规则48类型->结构
规则49类型->列表类型
规则50操作员->燃气轮机操作
规则51运算符->LT_OP
规则52操作员->GTE_操作
规则53运营商->LTE\u运营商
规则54运算符->等式运算
规则55操作员->NEQ_操作
规则56常量->整数
规则57常量->DBL
规则58常量->STR
规则59声明符->ID L\u参数fn\u参数R\u参数
规则60声明符->ID
规则61 fn_args->fn_args逗号表达式
规则62 fn_args->expression
规则63容器->列表
规则64列表->左大括号容器项目右大括号
规则65列表类型->左大括号类型右大括号
规则66容器项目->容器项目逗号容器项目
规则67集装箱项目->集装箱项目
规则68容器项->表达式
规则69容器\项目->空
规则70布尔->真
规则71布尔->假
规则72条件->布尔
规则73注释->单个注释
规则74单注释->注释行
规则75空->

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

语法的相关部分:

 (2) statement -> definition SEMICOLON
(14) definition -> fn_def
这些是唯一出现在右侧的
fn_def
definition
产品

显然,
定义
只能在先行标记为分号时被简化为
语句
。由于
fn_def
只能出现在有效程序中的某个位置,该位置可以立即简化为
definition
fn_def
),因此
fn_def
后面必须跟一个
分号。因此,您的解析器是正确的,您的示例输入是不合语法的

fn_def
只有一个产品:

(16) fn_def -> DEFN ID ARROW type invariants statement
其中很明显,
fn_def
中的最后一项是
语句
。某些语句(
定义
表达式
)必须以
结尾;如果
fn_def
语句是其中的一个(可能是一个表达式,因为它看起来不像一个单一的定义构成一个有趣的函数体),那么
fn_def
必须用两个分号来编写。我怀疑那是否是你想要的

定义
语句
(如果是
fn_def
)或
表达式
(如果是
var_def
)结尾。您试图定义
语句
,使其具有自定界性(也就是说,如果它不以
}
结尾,它就以分号结尾,而
}
终止了一个
复合_语句。因此
fn_def
已经以分号或右括号结尾,不需要另一个分号。另一方面,var_def
以表达式结尾,因此有一个解决方案是将结束分号插入
var\u def

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

事实上,除了您自己的aes之外,没有明显的理由需要将循环或条件体限制为复合语句