苦苦挣扎解析数组表示法

时间:2013-07-19 10:30:37

标签: antlr4

我有一个非常简单的语法来解析语句。

以下是需要解析的语句类型的示例:

a.b.c 

a.b.c == "88" 

我遇到的问题是数组符号不匹配。例如,不起作用的事情:

a.b[0].c

a[3][4] 

我希望有人能指出我在这里做错了什么。 (我在ANTLRWorks中测试)

这是语法(generationUnit是我的切入点):

grammar RatBinding;

generationUnit: testStatement | statement;

arrayAccesor : identifier arrayNotation+;
arrayNotation:  '[' Number ']';

testStatement: 
    (statement | string | Number | Bool ) 

    (greaterThanAndEqual 
        | lessThanOrEqual  
        | greaterThan
        | lessThan | notEquals | equals)

    (statement | string | Number | Bool ) 
;

part: identifier | arrayAccesor; 

statement:  part  ('.' part )*;

string: ('"' identifier '"') | ('\'' identifier '\'');

greaterThanAndEqual: '>=';
lessThanOrEqual: '<=';
greaterThan: '>';
lessThan: '<';
notEquals : '!=';
equals: '==';
identifier:   Letter (Letter|Digit)*;


Bool : 'true' | 'false';

ArrayLeft: '\u005B';
ArrayRight: '\u005D';

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

Digit
    :  '\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'
   ;

WS  :   [ \r\t\u000C\n]+ -> channel(HIDDEN)
 ;

2 个答案:

答案 0 :(得分:2)

您在Number解析器规则中引用了不存在的规则arrayNotation

词法分析器中确实存在Digit规则,但它只匹配一位数字。例如,1Digit,但10是两个单独的Digit令牌,因此a[10]arrayAccesor规则不匹配。您可能希望分两部分来解决这个问题:

  1. 创建一个由一个或多个数字组成的Number令牌。

    Number
      : Digit+
      ;
    
  2. Digit标记为片段规则,以表明它本身不构成标记,但仅用于从其他词法规则引用。

    fragment // prevents a Digit token from being created on its own
    Digit
      : ...
    
  3. 您无需更改arrayNotation,因为它已经引用了您在此处创建的Number规则。

答案 1 :(得分:0)

呸,浪费空间。我在数组声明中使用了Number而不是Digit。