Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 用ANTLR解析循环_Loops_Antlr - Fatal编程技术网

Loops 用ANTLR解析循环

Loops 用ANTLR解析循环,loops,antlr,Loops,Antlr,我想使用ANTLR解析一个简单的类似matlab的for循环 循环如下所示: for i=1:8 y(i) = a(i) + i; end 我想解析循环并解析8次y(I)=a(I)+I语句,以便对每个语句执行一些操作 我的规则如下(操作在C中描述): forloop @初始化 { 字符串c=“”; int-mark=input.mark(); } @之后 { if(常数[c]

我想使用ANTLR解析一个简单的类似matlab的for循环

循环如下所示:

for i=1:8
    y(i) = a(i) + i;
end
我想解析循环并解析8次
y(I)=a(I)+I
语句,以便对每个语句执行一些操作

我的规则如下(操作在C中描述):

forloop
@初始化
{
字符串c=“”;
int-mark=input.mark();
}
@之后
{
if(常数[c]<$i2.值){
SetConst(c,常数[c]+1);
输入。倒带(标记);
}
}
:'对于'IDENT'=“i1=常量”:'i2=常量换行符
{
c=$IDENT.text;
如果(!IsConst(c)){
AddConst(c$i1.值);
}
}
声明?
“结束”
;
实际上,当ANTLR解析
语句
规则时,它会触发一些操作。因此,在这里,我告诉ANTLR,
I是一个常量,首先它的值是1,然后我想重复
语句
解析,同时增加我的
I
常量

重申一下,我使用了input.Mark()和input.Rewind(),但它并没有像我预期的那样工作,并且ANTLR引发了一些错误,告诉我一些“换行符”标记在“for”关键字处不存在

如果我想触发一些操作直到循环结束,我如何处理循环解析?

我找到了解决方案。 实际上,
input.Rewind()
的行为不像我第一次预料的那样。它只是简单地将输入缓冲区恢复到以前的状态,由
input.Mark()
定义

因此,当到达for循环的末尾时,如果条件仍然为true,我将整个for循环重新注入输入缓冲区

但是!在另一条规则中,我告诉ANTLR 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
当然,由于前7个循环后面没有换行符,所以ANTLR报告了一个错误

解决方案是简单地告诉ANTLR for循环后面不需要紧跟
换行符
。它像一个魅力,但我不太满意这个结果

最终的for循环规则如下所示(这只是一个代码清理):

forloop
@init{int mark=input.mark();}
:'对于'IDENT'=“i1=常量”:'i2=常量换行符
{
字符串c=$IDENT.text;
如果(!IsConst(c)){
AddConst(c$i1.值);
}
}
声明?”结束'
{
if(常数[c]<$i2.值){
SetConst(c,常数[c]+1);
输入。倒带(标记);
}
}
;

但是,每次倒带后,用这种方法倒带不会将c循环计数器重新初始化为$1.5的值?
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
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);
            }
        }
    ;