DeCaf中的ANTLR歧义-教授不确定错误在哪里
我正在为学校做一个项目,将BNF格式的Decaf规范转换为上下文无关语法,并在ANTLR中构建它。我已经做了几个星期了,当我陷入困境时,我会去找教授,但我最终遇到了他说不应该导致错误的东西。这是我语法中孤立的部分,expr是起点。在此之前,我有一个问题 在语法中,如果我的lexer规则出现在解析器规则之前,或者它们通过语法文件间歇性地混合在一起,这有关系吗DeCaf中的ANTLR歧义-教授不确定错误在哪里,antlr,antlrworks,Antlr,Antlrworks,我正在为学校做一个项目,将BNF格式的Decaf规范转换为上下文无关语法,并在ANTLR中构建它。我已经做了几个星期了,当我陷入困境时,我会去找教授,但我最终遇到了他说不应该导致错误的东西。这是我语法中孤立的部分,expr是起点。在此之前,我有一个问题 在语法中,如果我的lexer规则出现在解析器规则之前,或者它们通过语法文件间歇性地混合在一起,这有关系吗 calloutarg: expr | STRING; expr: multexpr ((PLUS|MINUS) multe
calloutarg: expr | STRING;
expr: multexpr ((PLUS|MINUS) multexpr)* ;
multexpr : atom ((MULT|DIVISION) atom)*
;
atom : OPENPAR expr CLOSEPAR | ID ((OPENBRACKET expr CLOSEBRACKET)? | OPENPAR ((expr (COMMA)* )+)? CLOSEPAR)|
CALLOUT OPENPAR STRING (COMMA (calloutarg)+ COMMA)? CLOSEPAR | constant;
constant: INT | CHAR | boolconstant;
boolconstant: TRUE|FALSE;
这种难看的格式是因为他对调试的部分建议是采用单独的规则,并在模糊之处将其分解,以查看错误从何处开始。在本例中,它说问题出在长ID部分,Open括号和OPENPAR是原因。如果你有任何想法,我非常感激。谢谢你,很抱歉我发布的代码的格式太糟糕了
在语法中,如果我的lexer规则出现在解析器规则之前,这有关系吗
不,那没关系
问题在于,在您的atom
规则中,ANTLR无法在这三种变体之间做出选择:
ID(…
ID[…
ID
(…)=>…
)来解决它。语法谓词只不过是一个“前瞻”,如果这个“前瞻”成功,它会选择那个特定的路径
您当前的atom
规则可以重写如下:
atom
: OPENPAR expr CLOSEPAR
| ID OPENPAR ((expr (COMMA)* )+)? CLOSEPAR
| ID OPENBRACKET expr CLOSEBRACKET
| ID
| CALLOUT OPENPAR STRING (COMMA (calloutarg)+ COMMA)? CLOSEPAR
| constant
;
使用谓词时,它将如下所示:
atom
: OPENPAR expr CLOSEPAR
| (ID OPENPAR)=> ID OPENPAR ((expr (COMMA)* )+)? CLOSEPAR
| (ID OPENBRACKET)=> ID OPENBRACKET expr CLOSEBRACKET
| ID
| CALLOUT OPENPAR STRING (COMMA (calloutarg)+ COMMA)? CLOSEPAR
| constant
;
这应该会起作用
注意:不要使用ANTLRWorks来生成或测试解析器!它不能处理谓词(很好)。最好在命令行中执行
另见:
编辑 让我们为
atom
规则从A
到F
的六个不同“分支”贴上标签:
atom // branch
: OPENPAR expr CLOSEPAR // A
| ID OPENBRACKET expr CLOSEBRACKET // B
| ID OPENPAR ((expr COMMA*)+)? CLOSEPAR // C
| ID // D
| CALLOUT OPENPAR STRING (COMMA calloutarg+ COMMA)? CLOSEPAR // E
| constant // F
;
现在,当(未来)解析器应该像这样处理输入时:
ID OPENPAR expr CLOSEPAR
ANTLR不知道解析器应该如何处理它。它可以用两种不同的方式进行解析:
D
后接分支A
C
A
、C
或D
,错误就会消失
希望有帮助
在语法中,如果我的lexer规则出现在解析器规则之前,这有关系吗
不,那没关系
问题在于,在您的atom
规则中,ANTLR无法在这三种变体之间做出选择:
ID(…
ID[…
ID
(…)=>…
)来解决它。语法谓词只不过是一个“前瞻”,如果这个“前瞻”成功,它会选择那个特定的路径
您当前的atom
规则可以重写如下:
atom
: OPENPAR expr CLOSEPAR
| ID OPENPAR ((expr (COMMA)* )+)? CLOSEPAR
| ID OPENBRACKET expr CLOSEBRACKET
| ID
| CALLOUT OPENPAR STRING (COMMA (calloutarg)+ COMMA)? CLOSEPAR
| constant
;
使用谓词时,它将如下所示:
atom
: OPENPAR expr CLOSEPAR
| (ID OPENPAR)=> ID OPENPAR ((expr (COMMA)* )+)? CLOSEPAR
| (ID OPENBRACKET)=> ID OPENBRACKET expr CLOSEBRACKET
| ID
| CALLOUT OPENPAR STRING (COMMA (calloutarg)+ COMMA)? CLOSEPAR
| constant
;
这应该会起作用
注意:不要使用ANTLRWorks来生成或测试解析器!它不能处理谓词(很好)。最好在命令行中执行
另见:
编辑 让我们为
atom
规则从A
到F
的六个不同“分支”贴上标签:
atom // branch
: OPENPAR expr CLOSEPAR // A
| ID OPENBRACKET expr CLOSEBRACKET // B
| ID OPENPAR ((expr COMMA*)+)? CLOSEPAR // C
| ID // D
| CALLOUT OPENPAR STRING (COMMA calloutarg+ COMMA)? CLOSEPAR // E
| constant // F
;
现在,当(未来)解析器应该像这样处理输入时:
ID OPENPAR expr CLOSEPAR
ANTLR不知道解析器应该如何处理它。它可以用两种不同的方式进行解析:
D
后接分支A
C
A
、C
或D
,错误就会消失
希望这能有所帮助。谢谢你的帮助!我有一个问题,为什么我的左保理不能处理ID | ID[| ID(问题?)@Nick,请查看我答案的编辑。谢谢你的帮助!我有一个问题,为什么我的左保理不能处理ID | ID[| ID(问题?@Nick,请查看我答案的编辑。