1 回答

TA貢獻1111條經驗 獲得超0個贊
您可以通過引入一個詞法模式來解決這個問題,只要您匹配一個EQ
記號,您就會進入該詞法模式。一旦進入該詞法模式,您要么匹配一個(
,)
要么匹配一個空格(在這種情況下您會跳出詞法模式),或者繼續匹配您的NOT_SPECIAL
字符。
通過使用詞法模式,您必須在自己的文件中定義詞法分析器和解析器規則。請務必使用lexer grammar ...
andparser grammar ...
而不是grammar ...
您在組合.g4
文件中使用的。
快速演示:
lexer grammar MdbLexer;
STRING
?: '"' ~[\r\n"]* '"'
?;
OPAR
?: '('
?;
CPAR
?: ')'
?;
AND
?: 'and'
?;
OR
?: 'or'
?;
NOT
?: 'not'
?;
NO
?: 'no'
?;
EVERY
?: 'every'
?;
EQ
?: '=' -> pushMode(NOT_SPECIAL_MODE)
?;
ID
?: VALID_ID_START VALID_ID_CHAR*
?;
DIGIT
?: [0-9]
?;
WS
?: [ \r\n\t]+ -> skip
?;
fragment VALID_ID_START
?: [a-zA-Z_]
?;
fragment VALID_ID_CHAR
?: [a-zA-Z_0-9]
?;
mode NOT_SPECIAL_MODE;
? OPAR2
? ?: '(' -> type(OPAR), popMode
? ?;
? CPAR2
? ?: ')' -> type(CPAR), popMode
? ?;
? WS2
? ?: [ \t\r\n] -> skip, popMode
? ?;
? NOT_SPECIAL
? ?: ~[ \t\r\n()]+
? ?;
您的解析器語法將像這樣開始:
parser grammar MdbParser;
options {
? ? tokenVocab=MdbLexer;
}
start
?: searchclause EOF
?;
// your other parser rules
我的 Go 有點生疏,但是一個小的 Java 測試:
String source = "Person Address=^%Street%%%$^&*@^()";
MdbLexer lexer = new MdbLexer(CharStreams.fromString(source));
CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.fill();
for (Token t : tokens.getTokens()) {
? System.out.printf("%-15s %s\n", MdbLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
}
打印以下內容:
ID? ? ? ? ? ? ? Person
ID? ? ? ? ? ? ? Address
EQ? ? ? ? ? ? ? =
NOT_SPECIAL? ? ?^%Street%%%$^&*@^
OPAR? ? ? ? ? ? (
CPAR? ? ? ? ? ? )
EOF? ? ? ? ? ? ?<EOF>
- 1 回答
- 0 關注
- 159 瀏覽
添加回答
舉報