在范围和语法错误中使用浮点数?

时间:2013-02-21 16:10:19

标签: antlr antlr3

我正在尝试使用ANTLR将LALR语法转换为LL,我遇到了一些问题。到目前为止,我认为将表达式转换为自上而下的方法对我来说是直截了当的。问题是当我包含带浮点数的Range(1..10)和(1.0..10.0)时。

我试图使用这里找到的答案,不知何故它甚至没有正确运行我的代码,更不用说解决一系列的浮点数,即(float..float)。 Float literal and range parameter in ANTLR

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

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')+ ;

任何原因,甚至没有采取:

in 10;

in 10.0;

提前致谢!

2 个答案:

答案 0 :(得分:2)

以下情况不正确:

  • 您永远不会在FloatLiteral规则
  • 中匹配literalExpression
  • NUMBER的每个替代项中,您正在更改令牌的类型,因此永远不会创建NUMBER令牌

这样的内容适用于11..221.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 :(得分:1)

关于处理(1.0 .. 10.0)

的问题

请注意,解析器规则primitiveElement将替代定义为'(' expression ')',但规则expression永远不会达到规则rangeExpression

请考虑重新定义expressionrangeExpression,如下所示:

expression : rangeExpression
           ;

rangeExpression : compExpression ('..' compExpression)?
                ;

compExpression : addingExpression (('=='|'!='|'<='|'<'|'>='|'>') addingExpression)*
               ;

这可确保expression规则位于所有表达形式之上,并在括号中按预期工作。