【问题标题】:ANTLR4 grammar conflicting rulesANTLR4 语法冲突规则
【发布时间】:2015-09-08 03:40:39
【问题描述】:

我必须首先说我是语法新手,并且我仍在学习有关 antlr 的方法。

我的语法允许以下操作:

grammar TEST;

file :  (varDecl | functionDcl)+    ;
varDecl :   type ID ('=' expression)?   ';'     ;
type :  'int' | 'float' | 'void'    ;
functionDcl :   type ID '(' formalParameters? ')' block ;
formalParameters :  formalParameter (',' formalParameter)*  ;   
formalParameter :   type ID     ;
block : '{' stat* '}'   ;
stat :  block
     |  varDecl
     |  'if' expression 'then' stat ('else' stat)?
     |  'return' expression? ';'
     |  expression '=' expression ';'
     |  expression ';'
     ;
expression : unaryExprNotPlusMinus (intervalOp unaryExprNotPlusMinus)? ;
unaryExprNotPlusMinus :  unaryOp expression  
                      |  INT 
                      |  FloatingPointLiteral
                      ;


unaryOp : '~' | '!' | 'not' | 'typeof' | 'statictypeof';
intervalOp : '..' | '|..' | '..|' | '|..|'  ;

INT : JavaIDDigit+ ;
ID : Letter (Letter|JavaIDDigit)* ;

fragment
Letter
    :  '\u0024' |
       '\u0041'..'\u005a' |
       '\u005f' |
       '\u0061'..'\u007a' |
       '\u00c0'..'\u00d6' |
       '\u00d8'..'\u00f6' |
       '\u00f8'..'\u00ff' |
       '\u0100'..'\u1fff' |
       '\u3040'..'\u318f' |
       '\u3300'..'\u337f' |
       '\u3400'..'\u3d2d' |
       '\u4e00'..'\u9fff' |
       '\uf900'..'\ufaff'
    ;

fragment
JavaIDDigit
    :  '\u0030'..'\u0039' |
       '\u0660'..'\u0669' |
       '\u06f0'..'\u06f9' |
       '\u0966'..'\u096f' |
       '\u09e6'..'\u09ef' |
       '\u0a66'..'\u0a6f' |
       '\u0ae6'..'\u0aef' |
       '\u0b66'..'\u0b6f' |
       '\u0be7'..'\u0bef' |
       '\u0c66'..'\u0c6f' |
       '\u0ce6'..'\u0cef' |
       '\u0d66'..'\u0d6f' |
       '\u0e50'..'\u0e59' |
       '\u0ed0'..'\u0ed9' |
       '\u1040'..'\u1049'
   ;

FloatingPointLiteral
    :   ('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
    |   '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
    |   ('0'..'9')+ Exponent FloatTypeSuffix?
    |   ('0'..'9')+ FloatTypeSuffix
    |   ('0x' | '0X') (HexDigit )*
        ('.' (HexDigit)*)?
        ( 'p' | 'P' )
        ( '+' | '-' )?
        ( '0' .. '9' )+
        FloatTypeSuffix?
    ;

fragment
Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
FloatTypeSuffix : ('f'|'F'|'d'|'D'|'bd'|'BD') ;

fragment
HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ;

COMMENT
    :   '/*' .*? '*/'    -> channel(HIDDEN) 
    ;
WS  :   [ \r\t\u000C\n]+ -> channel(HIDDEN)
    ;

LINE_COMMENT
    : '//' ~[\r\n]* '\r'? '\n' -> channel(HIDDEN)
    ;

我从我必须使用的其他语法中学到了一些东西。 我的主要问题是我的 expr 规则。 给定以下输入:int aaaa = 0..|9; 我的期望是解析树会找到..|规则,而是将 0. 解释为浮点数,并且不能正确解析其余部分。

如果我像这样在 0 后面加一个空格,效果很好:int aaaa = 0 ..|9;

我需要这个在没有空间的情况下工作。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: antlr grammar antlr4


    【解决方案1】:

    词法分析器在解析器执行之前对字符输入进行标记。解析器仅对令牌进行操作。将unaryOpintervalOp 规则转换为词法分析器规则,以便它们可以参与标记化过程。

    更新

    @CoronA 进行了有效的观察。仅建议的更改是不够的。将 unaryOpintervalOp 规则移动到词法分析器将 FloatingPointLiteral 规则更改为

    FloatingPointLiteral
        :   ('0'..'9')+ '.' ('0'..'9')+ Exponent? FloatTypeSuffix?
        ...
    

    (要求小数点后至少有一个数字)足以正确匹配带和不带空格的输入。有替代方案,但 OP 需要首先澄清是否需要允许使用裸小数。

    【讨论】:

    • 这无济于事。问题是标记化从“0”开始,然后尽可能多地使用标记(在这种情况下,“.”导致标记类型为 double)。
    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 2011-04-17
    相关资源
    最近更新 更多