Antlr 在范围和语法错误中使用浮动?
我正在尝试使用ANTLR将LALR语法转换为LL,但遇到了一些问题。到目前为止,我认为将表达式转换为自上而下的方法对我来说是很简单的。问题是当我将范围(1..10)和(1.0..10.0)包含在浮动中时 我试着使用这里找到的答案,但不知何故,我的代码甚至不能正确运行,更不用说解决一系列的浮点,即(float..float)。 附件是我的语法样本,只关注这个问题Antlr 在范围和语法错误中使用浮动?,antlr,antlr3,Antlr,Antlr3,我正在尝试使用ANTLR将LALR语法转换为LL,但遇到了一些问题。到目前为止,我认为将表达式转换为自上而下的方法对我来说是很简单的。问题是当我将范围(1..10)和(1.0..10.0)包含在浮动中时 我试着使用这里找到的答案,但不知何故,我的代码甚至不能正确运行,更不用说解决一系列的浮点,即(float..float)。 附件是我的语法样本,只关注这个问题 grammar Test; options { language = Java; output = AST; } pars
grammar Test;
options {
language = Java;
output = AST;
}
parse: 'in' rangeExpression ';'
;
rangeExpression : expression ('..' expression)?
;
expression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
;
addingExpression : multiplyingExpression (('+'|'-') multiplyingExpression)*
;
multiplyingExpression : unaryExpression
(('*'|'/'|'div') unaryExpression)*
;
unaryExpression: ('+'|'-')* primitiveElement;
primitiveElement : literalExpression
| id ('.' id)?
| '(' expression ')'
;
literalExpression : NUMBER
| BOOLEAN_LITERAL
| 'infinity'
;
id : IDENTIFIER
;
// L E X I C A L R U L E S
Range
: '..'
;
NUMBER
: (DIGITS Range) => DIGITS {$type=DIGITS;}
| (FloatLiteral) => FloatLiteral {$type=FloatLiteral;}
| DIGITS {$type=DIGITS;}
;
// fragments
fragment FloatLiteral : Float;
fragment Float
: DIGITS ( options {greedy = true; } : '.' DIGIT* EXPONENT?)
| '.' DIGITS EXPONENT?
| DIGITS EXPONENT
;
BOOLEAN_LITERAL : 'false'
| 'true'
;
IDENTIFIER : LETTER (LETTER | DIGIT)*;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
或
提前谢谢 以下情况不正确:
- 您从未在
规则中匹配literalExpression
FloatLiteral
- 在
的每个备选方案中,您都在更改令牌的类型,因此将永远不会创建NUMBER
令牌NUMBER
11..22
和1.1..2.2
:
...
literalExpression : INT
| BOOLEAN_LITERAL
| FLOAT
| 'infinity'
;
id : IDENTIFIER
;
// L E X I C A L R U L E S
Range
: '..'
;
INT
: (DIGITS Range)=> DIGITS
| DIGITS (('.' DIGITS EXPONENT? | EXPONENT) {$type=FLOAT;})?
;
BOOLEAN_LITERAL : 'false'
| 'true'
;
IDENTIFIER : LETTER (LETTER | DIGIT)*;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment FLOAT : ;
有关处理
(1.0..10.0)
的问题:
请注意,解析器规则primitiveElement
将替代项定义为'(“expression”)
,但规则expression
永远无法到达规则rangeExpression
考虑重新定义表达式
和范围表达式
如下:
expression : rangeExpression
;
rangeExpression : compExpression ('..' compExpression)?
;
compExpression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
;
expression:rangeExpression
;
范围表达式:compExpression(“..”compExpression)?
;
compExpression:addingExpression((“==”|“!=”|“)addingExpression)*
;
这确保了
表达式
规则位于所有形式的表达式之上,并将在括号中按预期工作。感谢快速修复!但我相信如果我没有弄错的话,这不能解决(在10..10;),也就是一个数字范围,我不知道为什么我在输入一个指数后会得到这个:required(…)+循环与字符“e”处的任何内容都不匹配。。。谢谢你的帮助@安德姆,不知道你说的“放入指数”是什么意思。你的意思是给解析器“输入”一个指数吗?这不起作用,因为这是一个片段规则。如果没有,你能提供失败的输入吗?@AndyM,请注意我稍微改变了INT规则,也许这就是你的意思……我现在的方法实际上捕获(10.0),但永远不会捕获(10.0..20.0)。一旦我切换到您的代码,ANTLR v3抱怨说规则“('expression')将永远无法达到。@AndyM(10.0)
被原始语法捕获,因为括号中不包含范围,而范围是它在括号中唯一不接受的表达式。我没有从ANTLR v3.5中得到任何警告,更改显示在我的答案中。确保primitiveElement
仍有可选的“(“表达式”)”
。这是你得到的唯一警告吗?一旦我做了@Bart更改,它就成功了!谢谢你注意到这个错误
...
literalExpression : INT
| BOOLEAN_LITERAL
| FLOAT
| 'infinity'
;
id : IDENTIFIER
;
// L E X I C A L R U L E S
Range
: '..'
;
INT
: (DIGITS Range)=> DIGITS
| DIGITS (('.' DIGITS EXPONENT? | EXPONENT) {$type=FLOAT;})?
;
BOOLEAN_LITERAL : 'false'
| 'true'
;
IDENTIFIER : LETTER (LETTER | DIGIT)*;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
fragment EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
fragment FLOAT : ;
expression : rangeExpression
;
rangeExpression : compExpression ('..' compExpression)?
;
compExpression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
;