在antlr中获取纯文本而不是令牌

在antlr中获取纯文本而不是令牌,antlr,antlr4,Antlr,Antlr4,我正在尝试使用antlr创建一个解析器。我的语法如下 code : codeBlock* EOF; codeBlock : text | tag1Ops | tag2Ops ; tag1Ops: START_1_TAG ID END_2_TAG ; tag2Ops: START_2_TAG ID END_2_TAG ; text: ~(START_1_TAG|START_2_TAG)+; START_1_TAG : '<%' ; END_1_TAG : '%>' ; STA

我正在尝试使用antlr创建一个解析器。我的语法如下

code : codeBlock* EOF;

codeBlock
: text
| tag1Ops
| tag2Ops
;

tag1Ops: START_1_TAG ID END_2_TAG ;

tag2Ops: START_2_TAG ID END_2_TAG ;

text: ~(START_1_TAG|START_2_TAG)+;

START_1_TAG : '<%' ;
END_1_TAG : '%>' ;
START_2_TAG : '<<';
END_2_TAG : '>>' ;

ID : [A-Za-z_][A-Za-z0-9_]*;
INT_NUMBER: [0-9]+;

WS :  ( ' ' | '\n' | '\r' | '\t')+ -> channel(HIDDEN);

SPACES: SPACE+;

ANY_CHAR : .;

fragment SPACE : ' ' | '\r' | '\n' | '\t' ;
code:code块*EOF;
代码块
:文本
|tag1Ops
|tag2Ops
;
tag1Ops:开始\u 1 \u标记ID结束\u 2 \u标记;
tag2Ops:开始标签ID结束标签;
文本:~(START_1_标记| START_2_标记)+;
开始\u 1\u标记:“”;
开始\u 2\u标记:“”;
识别号:[A-Za-z_u2;][A-Za-z0-9_2;]*;
国际单位编号:[0-9]+;
WS:(“|”\n“|”\r“|”\t')+->通道(隐藏);
空格:空格+;
任何字符:。;
片段空间:''|'\r'|'\n'|'\t';
除了各种标记外,我还需要实现一个规则来获取不在任何标记内的文本。在当前语法中,情况似乎很好,但由于“文本”规则属于Lexer端,因此输入的任何文本都被标记化,我得到一个标记列表,而不是单个字符串标记。intellij中的antlr探查器还显示对每个令牌的不明确调用

例如,“你好,你好吗?”,需要是单个标记,而不是由该语法生成的多个标记


我想我可能看错了角度,想知道是否还有其他方法来处理“文本”规则。

首先:你有一个
WS
规则,将空格字符放在隐藏通道上,但在语法中,你有一个
空格
规则。如果将此
空格
规则放在
WS
之后并完全匹配,则将永远不会匹配
空格
规则

例如,“你好,你好吗?”,需要是单个标记,而不是由该语法生成的多个标记

在当前设置中无法执行此操作。你能做的就是利用。快速演示:

//必须位于名为DemoLexer.g4的单独文件中
词法语法解词法;
开始标签:'>'->popMode;
空间:[\t\r\n]->通道(隐藏);
要测试此lexer语法,请运行以下类:

import org.antlr.v4.runtime.*;
公共班机{
公共静态void main(字符串[]args){
stringsource=“foobar456mu!”;
DemoLexer lexer=新的DemoLexer(CharStreams.fromString(source));
CommonTokenStream tokenStream=新的CommonTokenStream(lexer);
tokenStream.fill();
for(令牌t:tokenStream.getTokens()){
System.out.printf(“%-20s%s\n”,DemoLexer.词汇表.getSymbolicName(t.getType()),t.getText());
}
}
}
将打印:

START\u 1\u标签
文本FOO-BAR
开始\u 2\u标签>
文字456亩!
EOF
在单独的解析器语法中使用lexer语法,如下所示:

//必须位于名为DemoParser.g4的单独文件中
语法分析器;
选择权{
tokenVocab=解复用器;
}
代码
:代码块*EOF
;
...
编辑
[…]但我对文本有点困惑:(~[这种方法似乎有效…但我对文本有点困惑:(~[@john检查我的编辑谢谢你的解释。没问题,john。
(            # start group
  ~[<]       #   match any char other than '<'
  |          #   OR
  '<' ~[<%]  #   match a '<' followed by any char other than '<' and '%'
)+           # end group, and repeat it once or more