我有一个非常简单的语法来解析语句。
以下是需要解析的语句类型的示例:
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)
;
答案 0 :(得分:2)
您在Number
解析器规则中引用了不存在的规则arrayNotation
。
词法分析器中确实存在Digit
规则,但它只匹配一位数字。例如,1
是Digit
,但10
是两个单独的Digit
令牌,因此a[10]
与arrayAccesor
规则不匹配。您可能希望分两部分来解决这个问题:
创建一个由一个或多个数字组成的Number
令牌。
Number
: Digit+
;
将Digit
标记为片段规则,以表明它本身不构成标记,但仅用于从其他词法规则引用。
fragment // prevents a Digit token from being created on its own
Digit
: ...
您无需更改arrayNotation
,因为它已经引用了您在此处创建的Number
规则。
答案 1 :(得分:0)
呸,浪费空间。我在数组声明中使用了Number而不是Digit。