Python 我语法中的歧义在哪里?

Python 我语法中的歧义在哪里?,python,compiler-construction,grammar,ply,shift-reduce-conflict,Python,Compiler Construction,Grammar,Ply,Shift Reduce Conflict,我有以下含糊不清的语法,其中大写字母规则适用于简单的词汇标记: program : function | function program function : FN ID ARROW TYPE invariants DASH block fn_call : ID L_PAREN CONSTANT R_PAREN invariants : invariant | invariant invariants invariant : TYPE ID COLON invariant_tests in

我有以下含糊不清的语法,其中大写字母规则适用于简单的词汇标记:

program : function | function program
function : FN ID ARROW TYPE invariants DASH block
fn_call : ID L_PAREN CONSTANT R_PAREN


invariants : invariant | invariant invariants
invariant : TYPE ID COLON invariant_tests
invariant_tests : test | test COMMA invariant_tests
test : OPERATOR CONSTANT | STAR


block : expression | expression block
expression : loop | fn_call | assignment | def | constant
loop : FOR def IN CONSTANT COLON block
assignment : ID ASSIGN CONSTANT | ID ASSIGN ID
def : TYPE assignment
我收到8个shift/reduce错误(使用Python2.7和PLY时)


歧义是否是我如何定义“一个或多个”的结果,例如
block:expression | expression block

问题在于我如何定义
循环

循环:用于常量冒号块中的def

因为解析器不知道该块是属于循环还是属于函数


基本上,悬挂else问题的另一个变体。

正如前面一位发言者所说,您必须区分“块用法”。 例如,尝试:

loop : FOR def IN CONSTANT COLON block END FOR

前一位发言者是我,但由于我有几天不能接受我的答案,我将接受你的正确答案。谢谢只是出于好奇;为什么要使用PLY(基于旧的Lex和Yacc构建)而不是Flex和Bison?@nic我对Python更熟悉,而不是C。因为这是我的第一个语法,我想我应该呆在家里。使用Flex/Bison有巨大的好处吗?据说Flex比Lex快得多(尽管lexing是一项快速的任务,因为它可能很好地知道),并且是在Berkeley许可下发布的(Lex是在某些AT&T许可下发布的)。。我相信野牛要比亚克稳定得多。PLY是建立在旧版本上的,这很奇怪。。我认为只要在L&Y附近玩就和F&B一样好,如果你需要的话,很容易做出转换。