Antlr 在范围和语法错误中使用浮动?

Antlr 在范围和语法错误中使用浮动?,antlr,antlr3,Antlr,Antlr3,我正在尝试使用ANTLR将LALR语法转换为LL,但遇到了一些问题。到目前为止,我认为将表达式转换为自上而下的方法对我来说是很简单的。问题是当我将范围(1..10)和(1.0..10.0)包含在浮动中时 我试着使用这里找到的答案,但不知何故,我的代码甚至不能正确运行,更不用说解决一系列的浮点,即(float..float)。 附件是我的语法样本,只关注这个问题 grammar Test; options { language = Java; output = AST; } pars

我正在尝试使用ANTLR将LALR语法转换为LL,但遇到了一些问题。到目前为止,我认为将表达式转换为自上而下的方法对我来说是很简单的。问题是当我将范围(1..10)和(1.0..10.0)包含在浮动中时

我试着使用这里找到的答案,但不知何故,我的代码甚至不能正确运行,更不用说解决一系列的浮点,即(float..float)。

附件是我的语法样本,只关注这个问题

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)*
               ;