以 Go 为目标匹配 ANTLR4 中任何可打印的类字母字符

这把我吓坏了,我就是找不到解决办法。我有一个搜索查询的语法,并且想匹配由可打印字母组成的查询中的任何搜索词,特殊字符“(”,“)”除外。引号中的字符串被单独处理并起作用。

问题是 searchterm 太受限制了。它应该匹配注释掉的 NOT_SPECIAL 中的任何字符,即,有效查询将是:

Person Name=%
Person Address=^%Street%%%$^&*@^

但是每当我尝试以任何方式将 NOT_SPECIAL 放入 searchterm 的定义中时,它都不起作用。我也尝试过将它逐字地放入规则中(注释掉 NOT_SPECIAL)和许多其他东西,但它就是行不通。在我的大多数尝试中,语法只是抱怨“=”之后的无关输入,并表示它期待 EOF。但我也不能将 EOF 放入 NOT_SPECIAL。

有什么方法可以简单地解析规则字段搜索中“=”之后的每个文本,直到出现空格或“)”、“(”?

注意 STRING 规则工作正常,但用户不应该每次都使用引号,因为这是一个命令行工具,他们需要转义。

目标语言是围棋。


偶然的你
浏览 119回答 1
1回答

catspeake

您可以通过引入一个词法模式来解决这个问题,只要您匹配一个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              PersonID              AddressEQ              =NOT_SPECIAL     ^%Street%%%$^&*@^OPAR            (CPAR            )EOF             <EOF>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go