我正在創建自己的語法,到目前為止我只有原始型別。但是,現在我想通過參考添加一個新型別,陣列,其格式類似于 Java 或 C#,但我遇到了無法使其與 ANTLR 一起使用的問題。
我正在使用的代碼示例類似于:
VariableDefinition
{
id1: string;
anotherId: bool;
arrayVariable: string[5];
anotherArray: bool[6];
}
MyMethod()
{
temp: string[3];
temp2: string;
temp2 = "Some text";
temp[0] = temp2;
temp2 = temp[0];
}
詞法分析器包含:
BOOL: 'bool';
STRING: 'string';
fragment DIGIT: [0-9];
fragment LETTER: [[a-zA-Z\u0080-\u00FF_];
fragment ESCAPE : '\\"' | '\\\\' ; // Escape 2-char sequences: \" and \\
LITERAL_INT: DIGIT ;
LITERAL_STRING: '"' (ESCAPE|.)*? '"' ;
OPEN_BRACKET: '[';
CLOSE_BRACKET: ']';
COLON: ':';
SEMICOLON: ';';
ID: LETTER (LETTER|DIGIT)*;
我的 Parser 將是這個的擴展(有更多的規則和其他運算式,但我不認為與這種情況有關系):
global_
: GLOBAL '{' globalVariables =variableDefinition* '}'
;
variableDefinition
: name=ID ':' type=type_ ';'
;
type_
: referenceType # TypeReference
| primitiveType # TypePrimitive
;
primitiveType
: BOOL # TypeBool
| CHAR # TypeChar
| DOUBLE # TypeDouble
| INT # TypeInteger
| STRING # TypeString
;
referenceType
: primitiveType '[' LITERAL_INT ']' # TypeArray
;
expression_
: identifier=expression_ '[' position=expression_ ']' # AccessArrayExpression
| left=expression_ operator=( '*' | '/' | '%') right=expression_ # ArithmeticExpression
| left=expression_ operator=( ' ' | '-' ) right=expression_ # ArithmeticExpression
| value=ID # LiteralID
我試過了:
- 在示例程式中的不同詞位之間放置空格,以防詞法分析器出現問題。(沒有改變)。
- 在 type_ 中創建一個名為 arrayType 的規則,并在 arrayType 參考 type_ 中創建一個規則(由于左遞回而失敗:ANTLR 顯示以下錯誤
The following sets of rules are mutually left-recursive [type_, arrayType] - 將原始型別和參考型別放在一個規則中。
type_
: BOOL # TypeBool
| CHAR # TypeChar
| DOUBLE # TypeDouble
| INT # TypeInteger
| STRING # TypeString
| type_ '[' LITERAL_INT ']' # TypeArray
;
- 結果: · 用空格分隔陣列 (
temp: string [5] ;)。
line 23:25 missing ';' at '[5'
line 23:27 mismatched input ']' expecting {'[', ';'}
· 沒有空格 ( temp: string[5];)。
line 23:18 mismatched input 'string[5' expecting {BOOL, 'char', 'double', INT, 'string'}
line 23:26 mismatched input ']' expecting ':'
編輯 1:這就是嘗試生成我給出的示例時樹的樣子: Parse tree Inspector
uj5u.com熱心網友回復:
想要靈活使用空格的語言通常有一個規則,如下所示:
WS: [ \t\r\n] -> skip; // or channel(HIDDEN)
它應該解決您的問題。
這會將空白空間轉移到一邊,因此您不必在決議器規則中關注它。
如果沒有這種方法,您仍然需要定義一個空白規則(與上面的模式相同),但是,如果您不這樣做skip(或將其發送到吃HIDDEN頻道),您將不得不將它包含在您想要的任何地方通過插入一個WS?. 顯然,這有可能變得相當乏味(并為您的語法和生成的決議樹增加很多“噪音”)。
uj5u.com熱心網友回復:
fragment LETTER: [[a-zA-Z\u0080-\u00FF_];
您允許[作為字母(因此作為識別符號中的字符),因此 instring[5]被string[5解釋為識別符號,這使決議器認為后續]沒有匹配的[. 同樣在string [5],[5被解釋為一個識別符號,這使得決議器看到兩個連續的識別符號,這也是不允許的。
要解決此問題,您應該洗掉[from LETTER。
作為一般提示,當遇到您不理解的決議錯誤時,您應該嘗試查看正在生成哪些令牌以及它們是否符合您的預期。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/417910.html
標籤:
上一篇:給定一個索引,相應地交換陣列元素
下一篇:如何從陣列創建表?
