AFAIK是不可能的。 但是,您可以延长<代码>。 Unbuffered TokenStream to change thecode>channel during parsing. 页: 1 Common TokenStream 因为它缓冲了数量可变的象征性物(而且缓冲区内可能会有象征性的症状!) 请注意:至少需要《公约》第三条第3款:在以前的版本中,<代码> Unbuffered TokenStream wasn t included yet.
请允许我说,你想要打平(和显示)低级或高级案件信。 上一份个案信载于<编码>HIDDEN。 渠道,如聋.,只有少发的个案信才会平价。 然而,当主人对一个较低案例(q>>
) st时,我们要改写。 HIDDEN
频道。 在<代码>上一栏 频道,我们希望<代码>Q>使我们回到<代码>。 DEFAULT_CHANNEL/code>。
因此,如果将源代码<>aAbBcqCdDQeE>、1a>、b>
和c>
印刷,那么该频道就会发生变化,然后改为C>
和D>
>>,则该频道将再次变更,最后<代码>e><<>_>><>e>><>>><>>><>>
Here s an ANTLR grammar that does this:
ChannelDemo.g
grammar ChannelDemo;
@parser::members {
private void handle(String letter) {
if("Q".equals(letter)) {
((ChangeableChannelTokenStream)input).setChannel(Token.DEFAULT_CHANNEL);
}
else if("q".equals(letter)) {
((ChangeableChannelTokenStream)input).setChannel(HIDDEN);
}
else {
System.out.println(letter);
}
}
}
parse
: any* EOF
;
any
: letter=(LOWER | UPPER) {handle($letter.getText());}
;
LOWER
: a .. z
;
UPPER
: A .. Z {$channel=HIDDEN;}
;
这里的习惯是:
ChangeableChannelTokenStream.java
import org.antlr.runtime.*;
public class ChangeableChannelTokenStream extends UnbufferedTokenStream {
public ChangeableChannelTokenStream(TokenSource source) {
super(source);
}
public Token nextElement() {
Token t = null;
while(true) {
t = super.tokenSource.nextToken();
t.setTokenIndex(tokenIndex++);
if(t.getChannel() == super.channel) break;
}
return t;
}
public void setChannel(int ch) {
super.channel = ch;
}
}
And a small Main class to test it all:
Main.java
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("aAbBcqCdDQeE");
ChannelDemoLexer lexer = new ChannelDemoLexer(in);
ChangeableChannelTokenStream tokens = new ChangeableChannelTokenStream(lexer);
ChannelDemoParser parser = new ChannelDemoParser(tokens);
parser.parse();
}
}
最后,产生备选案文/备选案文(1),汇编所有来源档案(2),管理主类(3):
1
java -cp antlr-3.3.jar org.antlr.Tool ChannelDemo.g
2
javac -cp antlr-3.3.jar *.java
3 (*nix)
java -cp .:antlr-3.3.jar Main
3 (Windows)
java -cp .;antlr-3.3.jar Main
将向议会印发以下文件:
a
b
c
C
D
e
EDIT
You can include the class in your grammar file like this:
grammar ChannelDemo;
@parser::members {
private void handle(String letter) {
if("Q".equals(letter)) {
((ChangeableChannelTokenStream)input).setChannel(Token.DEFAULT_CHANNEL);
}
else if("q".equals(letter)) {
((ChangeableChannelTokenStream)input).setChannel(HIDDEN);
}
else {
System.out.println(letter);
}
}
public static class ChangeableChannelTokenStream extends UnbufferedTokenStream {
private boolean anyChannel;
public ChangeableChannelTokenStream(TokenSource source) {
super(source);
anyChannel = false;
}
@Override
public Token nextElement() {
Token t = null;
while(true) {
t = super.tokenSource.nextToken();
t.setTokenIndex(tokenIndex++);
if(t.getChannel() == super.channel || anyChannel) break;
}
return t;
}
public void setAnyChannel(boolean enable) {
anyChannel = enable;
}
public void setChannel(int ch) {
super.channel = ch;
}
}
}
parse
: any* EOF
;
any
: letter=(LOWER | UPPER) {handle($letter.getText());}
| STAR {((ChangeableChannelTokenStream)input).setAnyChannel(true);}
;
STAR
: *
;
LOWER
: a .. z
;
UPPER
: A .. Z {$channel=HIDDEN;}
;
上文图表中产生的教区将可在所有渠道查阅>*
。 ∗∗∗∗∗∗∗
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("aAbB*cCdDeE");
ChannelDemoLexer lexer = new ChannelDemoLexer(in);
ChannelDemoParser.ChangeableChannelTokenStream tokens =
new ChannelDemoParser.ChangeableChannelTokenStream(lexer);
ChannelDemoParser parser = new ChannelDemoParser(tokens);
parser.parse();
}
}
原文如下:
a
b
c
C
d
D
e
E