2

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

我尝试使用此处找到的答案,但不知何故,它甚至无法正确运行我的代码,更不用说解决一系列浮点数,即(float..float)。 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;

提前致谢!

4

2 回答 2

2

以下几点是不正确的:

  • 您永远不会匹配规则FloatLiteral中的aliteralExpression
  • 在你的每一个选择中,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 : ;
于 2013-02-21T17:32:09.283 回答
1

关于处理的问题(1.0 .. 10.0)

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

考虑重新定义expressionrangeExpression像这样:

expression : rangeExpression
           ;

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

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

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

于 2013-02-21T17:58:06.147 回答