ANTLR - 如何在 'for' 循环中跳过丢失的标记
ANTLR - how to skip missing tokens in a 'for' loop
我正在开发一种 'toy' 语言来学习 antlr。
我的 for
循环构造如下所示。
for(4,10){
//program expressions
};
我有一个我认为可行的语法,但它有点难看。具体来说,我不确定我是否很好地处理了语义上不重要的标记。
例如,中间的逗号作为标记出现,但它对解析器并不重要,它只需要循环边界的 2 和 3。这意味着当我看到 loop
标记部分的 child()
元素时,我必须跳过不重要的元素。
如果您检查 ANTLR 查看器并查看解析树,您可能会看得最清楚。红色箭头指向我认为多余的token。
感觉我应该比现在更多地使用 skip()
功能,但我不知道如何在这个级别插入标记的语法。
loop: 'for(' foridxitem ',' foridxitem '){' (programexpression)+ '}';
foridxitem: NUM #ForIndexNumÌ
|
var #ForIndexVar;
简短的回答是 Antlr 会生成一个解析树,因此在遍历树时总会有需要跳过或以其他方式忽略的问题。
更长的答案是,在词法分析器中跳过 cruft 和生成语法价值有限的标记之间存在紧张关系,而这些标记对于编写明确的规则仍然是必需的。
例如,您将 for(
确定为跳过的候选者,但在语法上可能是必需的。相反,参数逗号可能真的没有句法意义。因此,您可以通过这种方式在词法分析器(和解析器)中清理它:
FOR: 'for(' -> pushMode(params) ;
ENDLOOP: '}' ;
WS: .... -> skip() ;
mode params;
NUM: .... ;
VAR: .... ;
COMMA: ',' -> skip() ;
ENDPARAMS: '){' -> skip(), popMode() ;
P_WS: .... -> skip() ;
您的 parer 规则将变为
loop: FOR foridxitem* programexpression+ ENDLOOP ;
foridxitem: NUM | VAR ;
programexpression: .... ;
这应该会稍微清理一下树。
我正在开发一种 'toy' 语言来学习 antlr。
我的 for
循环构造如下所示。
for(4,10){
//program expressions
};
我有一个我认为可行的语法,但它有点难看。具体来说,我不确定我是否很好地处理了语义上不重要的标记。
例如,中间的逗号作为标记出现,但它对解析器并不重要,它只需要循环边界的 2 和 3。这意味着当我看到 loop
标记部分的 child()
元素时,我必须跳过不重要的元素。
如果您检查 ANTLR 查看器并查看解析树,您可能会看得最清楚。红色箭头指向我认为多余的token。
感觉我应该比现在更多地使用 skip()
功能,但我不知道如何在这个级别插入标记的语法。
loop: 'for(' foridxitem ',' foridxitem '){' (programexpression)+ '}';
foridxitem: NUM #ForIndexNumÌ
|
var #ForIndexVar;
简短的回答是 Antlr 会生成一个解析树,因此在遍历树时总会有需要跳过或以其他方式忽略的问题。
更长的答案是,在词法分析器中跳过 cruft 和生成语法价值有限的标记之间存在紧张关系,而这些标记对于编写明确的规则仍然是必需的。
例如,您将 for(
确定为跳过的候选者,但在语法上可能是必需的。相反,参数逗号可能真的没有句法意义。因此,您可以通过这种方式在词法分析器(和解析器)中清理它:
FOR: 'for(' -> pushMode(params) ;
ENDLOOP: '}' ;
WS: .... -> skip() ;
mode params;
NUM: .... ;
VAR: .... ;
COMMA: ',' -> skip() ;
ENDPARAMS: '){' -> skip(), popMode() ;
P_WS: .... -> skip() ;
您的 parer 规则将变为
loop: FOR foridxitem* programexpression+ ENDLOOP ;
foridxitem: NUM | VAR ;
programexpression: .... ;
这应该会稍微清理一下树。