Yar*_*nov 6 antlr parser-generator
我有一个编写简单解析器生成器的任务,所以我编写了类似ANTLR的语法并试图解析像"foo:bar;"这样的简单文件,但得到了以下输出:
[@0,0:2='foo',<1>,1:0]
[@1,3:3=':',<16>,1:3]
[@2,4:6='bar',<1>,1:4]
[@3,7:7=';',<18>,1:7]
[@4,8:7='<EOF>',<-1>,1:8]
line 1:0 no viable alternative at input 'foo'
(rule foo : bar ;)
Run Code Online (Sandbox Code Playgroud)
我的语法看起来像
grammar parsGen;
gram : rule SEMICOLON (NEWLINE+ rule SEMICOLON)* ;
rule : lRule | pRule ;
lRule : LRULEID COLON lRule1 ;
lRule1 : (((LRULEID | STRING | SET) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;
pRule : PRULEID COLON pRule1 ;
pRule1 : (((LRULEID | PRULEID) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;
modificator : PLUS | ASTERISK | QUESTION ;
ID : LRULEID | PRULEID ;
LRULEID : UPPERLETTER (UPPERLETTER | LOWERLETTER | DIGIT)* ;
PRULEID : LOWERLETTER (UPPERLETTER | LOWERLETTER | DIGIT)* ;
STRING : ('\''.*?'\'') ;
SET : '\''.*?'\'..\''.*?'\'' ;
UPPERLETTER : [A-Z] ;
LOWERLETTER : [a-z] ;
DIGIT : [0-9] ;
NEWLINE : '\r\n'|'\n'|'\r' ;
PLUS : '+' ;
ASTERISK : '*' ;
QUESTION : '?' ;
LBRACE : '(' ;
RBRACE : ')' ;
SPACE : ' ' ;
COLON : ':' ;
PIPE : '|' ;
SEMICOLON : ';' ;
Run Code Online (Sandbox Code Playgroud)
那么我哪里可以犯错?我试图搜索到处(谷歌,SO等)错误"没有可行的选择",但它并没有真正帮助我.
Sam*_*ell 17
ANTLR词法分析器在使用解析器之前完全分配明确的令牌类型.当多个令牌类型可以匹配令牌时,出现在语法中的第一个令牌就是使用的令牌.对于您的语法,令牌不能同时具有类型ID和类型LRULEID.由于输入foo匹配这两个词法分析规则,第一个出现在语法使用,因此您的令牌是:ID,COLON,ID,SEMICOLON,<EOF>.
由于ID在解析器中从未实际引用令牌,因此我建议进行以下更改之一.这些选项中的任何一个都可以解决您所描述的问题,因此选择完全取决于最终语法的外观.
前言
您需要将空间引用更改SPACE+为SPACE*,或者规则将在和之间至少需要一个空格字符.bar;
选项1
ID完全删除词法分析器规则.
选项2
更改ID为解析器规则,因此它不会尝试将令牌类型分配ID给所有标识符.
id : LRULEID | PRULEID;
Run Code Online (Sandbox Code Playgroud)pRule1通过引用更新规则id.
pRule1 : ((id | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE+)+ ;
Run Code Online (Sandbox Code Playgroud)不相关的旁注
如果去掉最外层您的语法可能会更容易阅读+里面的封闭lRule和pRule1规则,而是将它们添加到规则引用自己,是这样的.请注意,我SPACE按照前言中的描述更改了引用.
lRule : LRULEID COLON lRule1+ ;
lRule1 : ((LRULEID | STRING | SET) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE* ;
pRule : PRULEID COLON pRule1+ ;
pRule1 : ((LRULEID | PRULEID) | LBRACE lRule1 PIPE lRule1 RBRACE) modificator? SPACE* ;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17321 次 |
| 最近记录: |