不带空格的Antlr3匹配令牌
给定输入不带空格的Antlr3匹配令牌,antlr,whitespace,tokenize,antlr3,Antlr,Whitespace,Tokenize,Antlr3,给定输入“term>1”,数字(1)和比较运算符(>)应在AST中生成单独的节点。如何做到这一点 在我的测试中,只有当“c”和“1”之间用空格分隔时,匹配才会发生,如“术语注) (和?a=notEx->^(和节点$andEx$a))*; 俄勒冈州:安第斯山脉(或安第斯山脉)*; countExpression:COUNT LPARENTHESIS WORD RPARENTHESIS relationship number->^(COUNT WORD relationship number); n
“term>1”
,数字(1)和比较运算符(>)应在AST中生成单独的节点。如何做到这一点
在我的测试中,只有当“c”和“1”之间用空格分隔时,匹配才会发生,如“术语<1
”
当前语法:
startExpression : orEx;
expressionLevel4
: LPARENTHESIS! orEx RPARENTHESIS! | atomicExpression;
expressionLevel3
: (fieldExpression) | expressionLevel4 ;
expressionLevel2
: (nearExpression) | expressionLevel3 ;
expressionLevel1
: (countExpression) | expressionLevel2 ;
notEx : (NOT^)? expressionLevel1;
andEx : (notEx -> notEx)
(AND? a=notEx -> ^(ANDNODE $andEx $a))*;
orEx : andEx (OR^ andEx)*;
countExpression : COUNT LPARENTHESIS WORD RPARENTHESIS RELATION NUMBERS -> ^(COUNT WORD RELATION NUMBERS);
nearExpression : NEAR LPARENTHESIS (WORD|PHRASE) MULTIPLESEPERATOR (WORD|PHRASE) MULTIPLESEPERATOR NUMBERS RPARENTHESIS -> ^(NEAR WORD* PHRASE* ^(NEARDISTANCE NUMBERS));
fieldExpression : WORD PROPERTYSEPERATOR WORD -> ^(FIELDSEARCH ^(TARGETFIELD WORD) WORD );
atomicExpression
: WORD
| PHRASE
;
fragment NUMBER : ('0'..'9');
fragment CHARACTER : ('a'..'z'|'A'..'Z'|'0'..'9'|'*'|'?');
fragment QUOTE : ('"');
fragment LESSTHEN : '<';
fragment MORETHEN: '>';
fragment EQUAL: '=';
fragment SPACE : ('\u0009'|'\u0020'|'\u000C'|'\u00A0');
fragment UNICODENOSPACES: ('\u0021'..'\u0027'|'\u0030'..'\u0039'|'\u003B'..'\u007E'|'\u00A1'..'\uFFFF');
//fragment UNICODENOSPACES : ('\u0021'..'\u0039'|'\u003B'..'\u007E'|'\u00A1'..'\uFFFF');
LPARENTHESIS : '(';
RPARENTHESIS : ')';
AND : ('A'|'a')('N'|'n')('D'|'d');
OR : ('O'|'o')('R'|'r');
ANDNOT : ('A'|'a')('N'|'n')('D'|'d')('N'|'n')('O'|'o')('T'|'t');
NOT : ('N'|'n')('O'|'o')('T'|'t');
COUNT:('C'|'c')('O'|'o')('U'|'u')('N'|'n')('T'|'t');
NEAR:('N'|'n')('E'|'e')('A'|'a')('R'|'r');
PROPERTYSEPERATOR : ':';
MULTIPLESEPERATOR : ',';
WS : (SPACE) { $channel=HIDDEN; };
RELATION : LESSTHEN? MORETHEN? EQUAL?;
NUMBERS : (NUMBER)+;
PHRASE : (QUOTE)(CHARACTER)+((SPACE)+(CHARACTER)+)+(QUOTE);
WORD : (UNICODENOSPACES)+;
startExpression:orEx;
表达水平4
:LPARENTHESIS!orEx RPARENTHESIS!|原子表达;
表达水平3
:(字段表达式)|表达式级别4;
表达级别2
:(近表达式)|表达式级别3;
表达水平1
:(countExpression)| expressionLevel2;
注十:(非^)?表达水平1;
安第斯:(注->注)
(和?a=notEx->^(和节点$andEx$a))*;
俄勒冈州:安第斯山脉(或安第斯山脉)*;
countExpression:COUNT LPARENTHESIS WORD RPARENTHESIS relationship number->^(COUNT WORD relationship number);
nearExpression:nearlparenthesis(单词|短语)多运算符(单词|短语)多运算符数RPARENTHESIS->^(nearword*短语*^(近距离数));
字段表达式:WORD属性操作员WORD->^(字段搜索^(目标字段WORD)WORD);
原子表达式
:字
|词组
;
片段编号:('0'..'9');
片段字符:('a'..'z'|'a'..'z'|'0'..'9'|'*'|'?');
片段引号:(“”);
片段LESSTHEN:“”;
片段相等:'=';
片段空间:('\u0009'|'\u0020'|'\u000C'|'\u00A0');
片段空间:('\u0021'..'\u0027'|'\u0030'..'\u0039'|'\u003B'..'\u007E'|'\u00A1'..\uFFFF');
//片段空间:('\u0021'..'\u0039'|'\u003B'..'\u007E'|'\u00A1'..'\uFFFF');
LPARENTHESIS:'(';
RPARENTHESIS:“)”;
和:('A'|'A')('N'|'N')('D'|'D');
或者:('O'|'O')('R'|'R');
而不是:('A'|'A')('N'|'N')('D'|'D')('N'|'N')('O'|'O')('T'|'T');
不是:('N''N')('O''O')('T''T');
计数:('C'|'C')('O'|'O')('U'|'U')('N'|'N')('T'|'T');
近:('N''N')('E''E')('A''A')('R''R');
属性运算符:':';
多重运算符:',';
WS:(空格){$channel=HIDDEN;};
关系:LESSTHEN?MORETHEN?EQUAL?;
数字:(数字)+;
短语:(引号)(字符)+(空格)+(字符)++(引号);
WORD:(unicodespace)+;
这是因为您的WORD
规则匹配太多:它也匹配“>”
,因此当>1“
一起写入时,这两个字符被标记为单个WORD
-标记
每当我不确定我的lexer在做什么时,我就简单地让解析器匹配任何类型的零个或多个标记,并打印所有标记的类型和文本:
parse
: (t=. {System.out.printf("\%-15s '\%s'\n", tokenNames[$t.type], $t.text);})* EOF
;
当您让上述规则与您的输入相匹配时,将打印以下内容:
WORD 'term'
RELATION '>'
WORD '1'
这是无法避免的:当lexer可以匹配2个(或更多)字符(单词规则)时,它将选择该路径,而不是之前定义的只匹配单个字符的规则(关系规则)
还要注意您的关系
规则:
RELATION : LESSTHEN? MORETHEN? EQUAL?;
可能与空字符串匹配。请确保每个lexer规则至少匹配1个字符,否则您的lexer可能会进入无限循环
最好这样做:
RELATION
: (LESSTHEN | MORETHEN)? EQUAL // '<=', '>=', or '='
| (LESSTHEN | MORETHEN) // '<' or '>'
;
关系
:(LESSTHEN | MORETHEN)?等于/“=”,或“=”
|(LESSTHEN | MORETHEN)/“”
;
谢谢!再次强调,WORD必须进行调整。看到AntlWorks一步一步地解析术语,然后却找不到关系(这是我的pov中的关系),这真的与我想象中的过程背道而驰。这是不是(排除WORD中的每个字符)真的是这样吗?单词永远不会匹配那些被排除在外的术语,因为它们使用了其他字符。@ThomAS,我不知道您的具体要求,但如果可以,让单词
至少以字母开头(而不是
或(
等)。这应该可以解决这个问题(可能还有其他问题)。让每个匹配规则至少匹配一个字符和保护单词的开头是两个非常好的提示!再次感谢(再次)帮助我!
RELATION
: (LESSTHEN | MORETHEN)? EQUAL // '<=', '>=', or '='
| (LESSTHEN | MORETHEN) // '<' or '>'
;