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 关注
- 117 浏览
添加回答
举报