antlr4 除运算符外的所有单词
antlr4 all words except the operators
grammar TestGrammar;
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WORD : [a-z0-9._#+=]+(' '[a-z0-9._#+=]+)* ;
WS : [ \t\r\n]+ -> skip ;
quotedword : DQUOTE WORD DQUOTE;
expression
: LPAREN expression+ RPAREN
| expression (AND expression)+
| expression (OR expression)+
| expression (NOT expression)+
| NOT expression+
| quotedword
| WORD;
我已经为 antlr4 实现了上面的语法。
我还有很长的路要走,但现在我的问题是,
我怎样才能使 WORD
通用?基本上我希望这个 [a-z0-9._#+=]
是除运算符 (AND
、OR
、NOT
、LPAREN
、RPAREN
、DQUOTE
, SPACE
).
词法分析器将使用可以匹配给定输入的第一条规则。只有当那个规则不能匹配它时,它才会尝试下一个。
因此,您可以使用以下语法使 WORD
规则通用:
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WS : [ \t\r\n]+ -> skip ;
WORD: .+? ;
确保在这种情况下使用非贪婪运算符 ?
因为一旦调用 WORD
规则将消耗所有后续输入。
由于最后指定了 WORD
,只有在所有先前的词法分析器规则(所有已在上面源代码中定义的规则)都失败的情况下,才会尝试使用输入。
编辑:如果您不希望您的WORD
规则匹配任何 输入,那么您只需修改我提供的规则。但我的回答的本质是,在词法分析器中,只要源代码中的顺序正确,你就不必担心两条规则可能匹配相同的输入。
试试这样的语法:
grammar TestGrammar;
...
WORD : Letter+;
QUOTEDWORD : '"' (~["\\r\n])* '"' // disallow quotes, backslashes and crlf in literals
WS : [ \t\r\n]+ -> skip ;
fragment Letter :
[a-zA-Z$_] // these are the "java letters" below 0x7F
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;
expression:
...
| QUOTEDWORD
| WORD+;
也许您想在 QUOTEDWORD
中使用转义序列,然后查看 this example 如何执行此操作。
此语法允许您:
- 将引用的单词解释为字符串文字(保留其中的所有空格)
- 用空格分隔多个单词(忽略)
grammar TestGrammar;
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WORD : [a-z0-9._#+=]+(' '[a-z0-9._#+=]+)* ;
WS : [ \t\r\n]+ -> skip ;
quotedword : DQUOTE WORD DQUOTE;
expression
: LPAREN expression+ RPAREN
| expression (AND expression)+
| expression (OR expression)+
| expression (NOT expression)+
| NOT expression+
| quotedword
| WORD;
我已经为 antlr4 实现了上面的语法。
我还有很长的路要走,但现在我的问题是,
我怎样才能使 WORD
通用?基本上我希望这个 [a-z0-9._#+=]
是除运算符 (AND
、OR
、NOT
、LPAREN
、RPAREN
、DQUOTE
, SPACE
).
词法分析器将使用可以匹配给定输入的第一条规则。只有当那个规则不能匹配它时,它才会尝试下一个。
因此,您可以使用以下语法使 WORD
规则通用:
AND : 'AND' ;
OR : 'OR'|',' ;
NOT : 'NOT' ;
LPAREN : '(' ;
RPAREN : ')' ;
DQUOTE : '"' ;
WS : [ \t\r\n]+ -> skip ;
WORD: .+? ;
确保在这种情况下使用非贪婪运算符 ?
因为一旦调用 WORD
规则将消耗所有后续输入。
由于最后指定了 WORD
,只有在所有先前的词法分析器规则(所有已在上面源代码中定义的规则)都失败的情况下,才会尝试使用输入。
编辑:如果您不希望您的WORD
规则匹配任何 输入,那么您只需修改我提供的规则。但我的回答的本质是,在词法分析器中,只要源代码中的顺序正确,你就不必担心两条规则可能匹配相同的输入。
试试这样的语法:
grammar TestGrammar;
...
WORD : Letter+;
QUOTEDWORD : '"' (~["\\r\n])* '"' // disallow quotes, backslashes and crlf in literals
WS : [ \t\r\n]+ -> skip ;
fragment Letter :
[a-zA-Z$_] // these are the "java letters" below 0x7F
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;
expression:
...
| QUOTEDWORD
| WORD+;
也许您想在 QUOTEDWORD
中使用转义序列,然后查看 this example 如何执行此操作。
此语法允许您:
- 将引用的单词解释为字符串文字(保留其中的所有空格)
- 用空格分隔多个单词(忽略)