Java ANTLR";“投入时无可行的替代方案”;分析SAS代码If Then Else时出错
我是ANTLR新手,正在研究一个解析器来解析SAS代码,该代码主要由if-then-else-if语句组成。我创建了以下语法来解析代码,但当我试图使用示例应用程序运行时,Intellij中出现了错误 创建的语法:Java ANTLR";“投入时无可行的替代方案”;分析SAS代码If Then Else时出错,java,parsing,sas,antlr4,parser-generator,Java,Parsing,Sas,Antlr4,Parser Generator,我是ANTLR新手,正在研究一个解析器来解析SAS代码,该代码主要由if-then-else-if语句组成。我创建了以下语法来解析代码,但当我试图使用示例应用程序运行时,Intellij中出现了错误 创建的语法: grammar SASDTModel; parse : if_block+ | score_block ; //Model // : If_block+ // | Score_block // ; if_block : (if_statement|if_in_block)
grammar SASDTModel;
parse
: if_block+
| score_block
;
//Model
// : If_block+
// | Score_block
// ;
if_block
: (if_statement|if_in_block)
| else_if_statement+
| else_statement
;
if_statement
: IF '(' if_condition ')' THEN Identifier'='Value ';'
| IF Identifier'='Value THEN Identifier'='Value ';'
;
else_if_statement
: ELSEIF '(' if_condition ')' THEN Identifier'='Value ';'
| ELSEIF Identifier'='Value THEN Identifier'='Value ';'
;
if_condition
: Value ComparisionOperators Identifier ComparisionOperators Value
| Value ComparisionOperators Value;
else_statement
: ELSE Identifier'='Value ';'
;
if_in_block
: IF Identifier IN '(' StringArray ')' THEN Identifier'='Value ';'
;
score_block
: Identifier'='Arithmetic_expression ';'
;
Arithmetic_expression:
| ( ArithmeticOperators '(' Value ')' )+
| ( ArithmeticOperators '(' Value ArithmeticOperators Identifier ')' )+
;
WS : ( ' ' | '\t' | '\r' | '\n' )-> channel(HIDDEN);
//WS : [ \t\n\r]+ -> channel(HIDDEN) ;
//WS : (' ' | '\t')+ -> channel(HIDDEN);
//COMMENT : '/*' .*? '*/' -> skip ;
//LINE_COMMENT : '*' ~[\r\n]* -> skip ;
ArithmeticOperators:
| '+'
| '-'
| '*'
| '/'
| '**'
;
ComparisionOperators
: '=='
| '<'
| '>'
| '<='
| '>='
;
IF: 'IF' | 'if' ;
ELSE: 'ELSE' | 'else' ;
ELSEIF: 'ELSE IF' | 'else if' ;
THEN: 'THEN' | 'then';
IN: 'IN' | 'in';
Value : INT
| DOUBLE
| '-'DOUBLE
| '-'INT
| Identifier
|'null';
INT : [0-9];
DOUBLE : INT+ PT INT+
| PT INT+
| INT+
;
PT : '.';
Identifier : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ;
StringArray : (('\'')(Value)('\''))+;
语法模型;
作语法分析
:if_块+
|记分块
;
//模型
//:If_块+
//|记分块
// ;
if_块
:(if_语句| if_在_块中)
|else\u if\u语句+
|else_声明
;
if_语句
:如果“(“IF_条件”)”则标识符“=”值“;”
|如果标识符“=”值,则标识符“=”值“;”
;
else\u if\u语句
:ELSEIF'('if_condition'),然后标识符'='Value';'
|ELSEIF标识符“=”值,然后标识符“=”值“;”
;
if_条件
:值比较运算符标识符比较运算符值
|值比较运算符值;
else_声明
:ELSE标识符“=”值“;”
;
如果_在_块中
:如果标识符位于“(“StringArray”)”中,则标识符“=”值“;”
;
记分块
:标识符“=”算术表达式“;”
;
算术表达式:
|(算术运算符“(“值”))+
|(算术运算符“(“值算术运算符标识符”))+
;
WS:(“|”\t“|”\r“|”\n')->频道(隐藏);
//WS:[\t\n\r]+->频道(隐藏);
//WS:(''|'\t')+->通道(隐藏);
//注释:'/*'.'*/'->跳过
//行注释:'*'~[\r\n]*->跳过;
算术运算符:
| '+'
| '-'
| '*'
| '/'
| '**'
;
比较运算符
: '=='
| ''
| '='
;
IF:“IF”|“IF”;
ELSE:“ELSE”|“ELSE”;
ELSEIF:“ELSE IF”|“ELSE IF”;
然后:‘然后’|‘然后’;
IN:'IN'|'IN';
值:INT
|双重的
|“——”双份
|'-'INT
|标识符
|“空”;
国际:[0-9];
双精度:INT+PT INT+
|PT INT+
|INT+
;
PT:';
标识符:('a'..'z'|'a'..'z'|'|'|')('a'..'z'|'a'..'z'|'|'|'0'..'9')*;
StringArray:(“\”)(值)(“\”)+;
输入:
if scored = null then scored = -0.05;
else if ( 0 < scored <= 300 ) then scored = -0.5;
else if ( 300 < scored <= 500 ) then scored = -0.4;
else if ( 500 < scored <= 800 ) then scored = -0.8;
else if ( 800 < scored <= 1000 ) then scored = 0.9;
else if ( scored > 1000 ) then scored = 1.735409628;
else scored = 0;
如果得分=空,则得分=-0.05;
否则,如果输入的语法不正确,则应使用==而不是=
更新:
此外,尽管INT和DOUBLE的语法应该可以工作,但最好这样表达:
INT : [0-9]+;
DOUBLE : INT PT INT
| PT INT
| INT
;
否则,300将被标识为DOUBLE,而不是INT
更新2
正如@Raven所评论的:
INT : [0-9]+;
DOUBLE : INT PT INT
| PT INT
;
输入的语法不正确:应使用==而不是=
更新:
此外,尽管INT和DOUBLE的语法应该可以工作,但最好这样表达:
INT : [0-9]+;
DOUBLE : INT PT INT
| PT INT
| INT
;
否则,300将被标识为DOUBLE,而不是INT
更新2
正如@Raven所评论的:
INT : [0-9]+;
DOUBLE : INT PT INT
| PT INT
;
以下是一些可能导致问题的因素:
- 通过使
StringArray:(('\'')(Value)('\'')+;
成为lexer规则,您将只匹配'foo123mu'
(不带空格的值)。您应该使StringArray
成为解析器规则(然后Value
也应该成为解析器规则)
- 您的
else-If
规则:ELSEIF:“else-If”|“else-If”
非常脆弱:每当else
和If
之间有2个或更多空格时,您的规则将不匹配。您应该删除此规则,并在解析器规则中使用现有的else
和If
规则
- 规则
算术运算符
和算术表达式
匹配临时字符串。Lexer规则决不能匹配空字符串(杠杆可以产生无限量的空字符串标记)
- 杠杆规则
算术表达式
应该是解析器规则:每当杠杆规则用于将其他标记“粘合”到彼此时,您应该将它们“升级”为解析器规则
- 您的lexer规则命名约定不一致:请使用
pascalasse
或大写字母
,不要同时使用两者
- 如前所述,
INT:[0-9];
应为INT:[0-9]+;
否则4
将标记为INT
,42
为DOUBLE
这些只是我在阅读你的问题时看到的一些事情,因此可能有更多的事情是不正确的。我建议你在尝试编写SAS语法之前,首先花时间学习更多的ANTLR。或者,更好的是,尝试为这种语言找到一个现有的(ANTLR)语法,而不是编写自己的语法
这里有一个你可以看一下的现有版本:(不知道它有多准确)以下是一些可能导致问题的东西:
- 通过使
StringArray:(('\'')(Value)('\'')+;
成为lexer规则,您将只匹配'foo123mu'
(不带空格的值)。您应该使StringArray
成为解析器规则(然后Value
也应该成为解析器规则)
- 您的
else-If
规则:ELSEIF:“else-If”|“else-If”
非常脆弱:每当else
和If
之间有2个或更多空格时,您的规则将不匹配。您应该删除此规则,并在解析器规则中使用现有的else
和If
规则
- 规则
算术运算符
和算术表达式
匹配临时字符串。Lexer规则决不能匹配空字符串(杠杆可以产生无限量的空字符串标记)
- 杠杆规则
算术表达式
应该是解析器规则:每当杠杆规则用于将其他标记“粘合”到彼此时,您应该将它们“升级”为解析器规则
- 您的lexer规则命名约定不一致:请使用
pascalasse
或大写字母
,不要同时使用两者
- 如前所述,
INT:[0-9];
应为INT:[0-9]+;
否则4
将标记为INT
,42
为DOUBLE