我想使用 ANTLR 解析一个简单的类似 matlab 的 for 循环。
循环就像:
for i=1:8
y(i) = a(i) + i;
end
我想解析循环并解析8次y(i) = a(i) + i
语句,以便对每个语句执行一些操作。
我的规则如下(操作在 C# 中描述):
forloop
@init
{
string c = "";
int mark = input.Mark();
}
@after
{
if (constants[c] < $i2.value) {
SetConst(c, constants[c] + 1);
input.Rewind(mark);
}
}
: 'for' IDENT '=' i1=constant ':' i2=constant NEWLINE
{
c = $IDENT.text;
if (!IsConst(c)) {
AddConst(c, $i1.value);
}
}
statements?
'end'
;
实际上,当ANTLR解析statements
规则,它会触发一些操作。所以,在这里,我告诉 ANTLRi is a constant which value is 1
首先,然后我想重申一下statements
解析,同时增加我的i
持续的。
重申一下,我使用了 input.Mark() 和 input.Rewind(),但它没有按我的预期工作,并且 ANTLR 引发了一些错误,告诉我一些“NEWLINE”标记不存在于“for”处关键词。
如果我想触发一些操作直到循环结束,我该如何处理循环解析?
我找到了解决方案。
实际上,input.Rewind()
不像goto
,正如我最初预期的那样。它只是简单地将输入缓冲区恢复到之前的状态,定义为input.Mark()
.
因此,当到达 for 循环末尾时,如果条件仍然为真,我将整个 for 循环重新注入输入缓冲区。
但 !在另一条规则中,我告诉 ANTLR for 循环后面必须跟有 NEWLINE。在我的例子中,通过重新注入,第一遍 for 循环后面紧接着第二遍 for 循环,从而产生以下结构:
for i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
endfor i=1:8
y(i) = a(i) + i;
end
当然,既然没有NEWLINE
进行到第7个循环后,ANTLR报错。
解决方案是简单地告诉 ANTLR for 循环后面不需要跟着NEWLINE
。它就像一个魅力,但我对这个结果不太满意......
最终的 for 循环规则如下所示(这只是代码清理):
forloop
@init {int mark = input.Mark();}
: 'for' IDENT '=' i1=constant ':' i2=constant NEWLINE
{
string c = $IDENT.text;
if (!IsConst(c)) {
AddConst(c, $i1.value);
}
}
statements? 'end'
{
if (constants[c] < $i2.value) {
SetConst(c, constants[c] + 1);
input.Rewind(mark);
}
}
;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)