1.break可以这样使用:
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case BASE:
case PREFIX:
;
break;
default:
jj_la1[1] = jj_gen;
break label_1;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case BASE:
BaseDecl();
break;
case PREFIX:
PrefixDecl();
break;
default:
jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
}
即按照标签跳出,这样的好处是可以设定跳出深度。
2.预处理和实际处理都会使用jj_ntk标志位,看下面两个代码就可知道:
final public void Query() throws ParseException {
Prologue();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case SELECT:
SelectQuery();
break;
case CONSTRUCT:
ConstructQuery();
break;
case DESCRIBE:
DescribeQuery();
break;
case ASK:
AskQuery();
break;
default:
jj_la1[0] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
ValuesClause();
}
而预处理的代码是:
final public void Prologue() throws ParseException {
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case BASE:
case PREFIX:
;
break;
default:
jj_la1[1] = jj_gen;
break label_1;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case BASE:
BaseDecl();
break;
case PREFIX:
PrefixDecl();
break;
default:
jj_la1[2] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
}
}
可见jena的文本分析器使用了同样的算法结构,这里使用的这个jj_ntk应该是一个标记位,而jj_nt则是每次将文本分块后取出的一块的内容,不妨查看一下两部分的定义:
public Token jj_nt;
private int jj_ntk;
3.等号的传递性:
像下面这样的代码:
int a=0;
int b,c;
b=c=a;
System.out.println("a= "+a+"b= "+b+"c="+c);
的输出结果是:
a= 0b= 0c=0
因此,等号这样的传递其实等于先计算c=a,再计算b=c
4.小心在myeclipse的expression里放方法,比如说token.getnexttoken()之类的,这样的结果是这个方法被调用了一次,会修改一些东西,造成问题
5.Deque<Class> 是双向队列,可以从两端进行操作,在调试界面,其显示的模式是:
stack ArrayDeque<E> (id=89)
stackCurrentLabels ArrayDeque<E> (id=93)
stackPreviousLabels ArrayDeque<E> (id=94)
双端队列如果没有指定从哪一端操作,默认是从后面插入,比如下面这种方式:
stackPreviousLabels.push(previousLabels) ;
实际上插到了:
stackPreviousLabels ArrayDeque<E> (id=94)
elements Object[16] (id=150)
[0] null
[1] null
[2] null
[3] null
[4] null
[5] null
[6] null
[7] null
[8] null
[9] null
[10] null
[11] null
[12] null
[13] null
[14] null
[15] HashSet<E> (id=81)
head 15
tail 0