我正在开发一个玩具'语言学习antlr。
我的for
循环构造看起来像这样。
for(4,10){
//program expressions
};
我认为我的语法很有用,但它有点难看。具体来说,我不确定我是否已经很好地处理了语义上不重要的令牌。
例如,中间的逗号显示为令牌,但它对解析器不重要,它只需要2和3作为循环边界。这意味着当我看到child()
令牌部分的loop
元素时,我必须跳过不重要的部分。
如果您检查ANTLR查看器并查看解析树,您可能会看到这一点。红色箭头指向我认为多余的代币。
感觉我应该比{I}更多地使用skip()
功能,但是我无法在这个级别上看到如何插入令牌的语法。
loop: 'for(' foridxitem ',' foridxitem '){' (programexpression)+ '}';
foridxitem: NUM #ForIndexNumÌ
|
var #ForIndexVar;
答案 0 :(得分:1)
简短的回答是Antlr会生成一个解析树,因此在走树时总是会有一些绊倒或者忽略。
更长的答案是,在词法分析器中跳过残余与产生有限句法价值的令牌之间存在紧张关系,这对于编写明确的规则是必要的。
例如,您将for(
标识为跳过的候选者,但可能在语法上是必需的。相反,参数逗号可能真的没有句法意义。所以,你可以这样在词法分析器(和解析器)中清理它:
FOR: 'for(' -> pushMode(params) ;
ENDLOOP: '}' ;
WS: .... -> skip() ;
mode params;
NUM: .... ;
VAR: .... ;
COMMA: ',' -> skip() ;
ENDPARAMS: '){' -> skip(), popMode() ;
P_WS: .... -> skip() ;
然后你的削皮器规则变为
loop: FOR foridxitem* programexpression+ ENDLOOP ;
foridxitem: NUM | VAR ;
programexpression: .... ;
那应该清理一下树。