简单语法的输入没有可行的替代方案
no viable alternative at input for simple grammar
我正在尝试使用 ANTLR 4 为简单的 DSL 创建一个解析器。我从我的测试和 ANTLRWorks 中得到 "no viable alternative at input"。
语法:
grammar Test;
process: action ('|' action)* ;
action: (filter) | (transform) | (log);
transform: 'transform' '(' ( ('name' '=' transformName)|('regex' '=' regex)) ')' ;
transformName: NAME;
filter: 'filter' '(' ( ('name' '=' filterName)|('regex' '=' regex)) ')' ;
filterName: NAME;
regex: QUOTEDSTRING;
log: 'log' ('(' 'name' '=' logName (',' 'level' '=' logLevel)? ')')? ;
logName: NAME;
logLevel: NAME;
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
STRING : (~["])+ ;
QUOTEDSTRING: '"' STRING '"';
WS : [ \t\r\n\u000C]+ -> skip ;
输入:
log (name=mylog,level=debug)
感谢任何帮助!
我认为您混合了 ANTLR4 语法和 ANTLR3 语法(由 ANTLRWorks 支持)
试试这样的方法
grammar Test;
eval :process EOF;
process :action ('|' action)*;
action :(filter) | (transform) | (log);
transform :'transform' '(' ( ('name' '=' transformName)|('regex' '=' regex)) ')' ;
transformName :NAME;
filter :'filter' '(' ( ('name' '=' filterName)|('regex' '=' regex)) ')' ;
filterName :NAME;
regex :QUOTEDSTRING;
log :'log' ('(' 'name' '=' logName (',' 'level' '=' logLevel)? ')')? ;
logName :NAME;
logLevel:NAME;
WS
: (
' '
| '\r'
| '\t'
| '\u000C'
| '\n'
)
{
skip();
}
;
QUOTEDSTRING :'"' NAME '"';
NAME :('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
似乎是这样工作的
您的词法分析器标记不是分离的:
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
STRING : (~["])+ ;
QUOTEDSTRING: '"' STRING '"';
WS : [ \t\r\n\u000C]+ -> skip ;
ANTLR 首先对输入处理这些规则。令牌是与这些规则中的任何一个匹配的最长序列。由于 STRING
包含几乎所有内容(双引号除外):
log (name=mylog,level=debug)
匹配为 STRING,因为它匹配字符、空格、括号和等于运算符的序列。没有其他令牌类型获得如此长的匹配,因此首选 STRING。
要解决它,让你的词法分析器规则分离:
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
QUOTEDSTRING: '"' (~["])+? '"';
WS : [ \t\r\n\u000C]+ -> skip ;
QUOTEDSTRING 将只匹配以双引号开头和结尾的长序列。您的行将不包含任何 STRING。
我正在尝试使用 ANTLR 4 为简单的 DSL 创建一个解析器。我从我的测试和 ANTLRWorks 中得到 "no viable alternative at input"。
语法:
grammar Test;
process: action ('|' action)* ;
action: (filter) | (transform) | (log);
transform: 'transform' '(' ( ('name' '=' transformName)|('regex' '=' regex)) ')' ;
transformName: NAME;
filter: 'filter' '(' ( ('name' '=' filterName)|('regex' '=' regex)) ')' ;
filterName: NAME;
regex: QUOTEDSTRING;
log: 'log' ('(' 'name' '=' logName (',' 'level' '=' logLevel)? ')')? ;
logName: NAME;
logLevel: NAME;
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
STRING : (~["])+ ;
QUOTEDSTRING: '"' STRING '"';
WS : [ \t\r\n\u000C]+ -> skip ;
输入:
log (name=mylog,level=debug)
感谢任何帮助!
我认为您混合了 ANTLR4 语法和 ANTLR3 语法(由 ANTLRWorks 支持)
试试这样的方法
grammar Test;
eval :process EOF;
process :action ('|' action)*;
action :(filter) | (transform) | (log);
transform :'transform' '(' ( ('name' '=' transformName)|('regex' '=' regex)) ')' ;
transformName :NAME;
filter :'filter' '(' ( ('name' '=' filterName)|('regex' '=' regex)) ')' ;
filterName :NAME;
regex :QUOTEDSTRING;
log :'log' ('(' 'name' '=' logName (',' 'level' '=' logLevel)? ')')? ;
logName :NAME;
logLevel:NAME;
WS
: (
' '
| '\r'
| '\t'
| '\u000C'
| '\n'
)
{
skip();
}
;
QUOTEDSTRING :'"' NAME '"';
NAME :('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
似乎是这样工作的
您的词法分析器标记不是分离的:
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
STRING : (~["])+ ;
QUOTEDSTRING: '"' STRING '"';
WS : [ \t\r\n\u000C]+ -> skip ;
ANTLR 首先对输入处理这些规则。令牌是与这些规则中的任何一个匹配的最长序列。由于 STRING
包含几乎所有内容(双引号除外):
log (name=mylog,level=debug)
匹配为 STRING,因为它匹配字符、空格、括号和等于运算符的序列。没有其他令牌类型获得如此长的匹配,因此首选 STRING。
要解决它,让你的词法分析器规则分离:
NAME : [a-zA-Z][a-zA-Z0-9_.]* ;
QUOTEDSTRING: '"' (~["])+? '"';
WS : [ \t\r\n\u000C]+ -> skip ;
QUOTEDSTRING 将只匹配以双引号开头和结尾的长序列。您的行将不包含任何 STRING。