Parsing a loop with ANTLR

I want to parse a simple matlab-like for-loop using ANTLR.

The loop is like:

for i=1:8
    y(i) = a(i) + i;
end

      

I want to parse the loop and parse the instruction 8 times y(i) = a(i) + i

to do some actions for each statement.

My rule looks like this (actions are described in 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'
;

      

Actually, when ANTLR analyzes a rule statements

, it triggers some action. So, here I will tell ANTLR what is i is a constant which value is 1

for starters, and then I want to repeat the parsing statements

, increasing the constant i

.

I repeat, I am using input.Mark () and input.Rewind (), but it does not work as I expect and some error is thrown by ANTLR, telling me that some NEWLINE tokens are missing for the "for" keyword.

How can I handle the par-syntax if I want to trigger some actions until the loop ends?

+2


a source to share


1 answer


I found a solution. In fact, it input.Rewind()

does not act goto

as I expected. It just simply restores the input buffer to the previous state defined input.Mark()

.

So when you reached the end of my for loop, if the condition was still true, I re-integrated the entire for loop into the input buffer.

BUT! In another rule, I told ANTLR that the loop MUST be followed by a NEWLINE. And in my case, through a re-install, the first pass for the loop was immediately followed by a loop of the second pass, resulting in this construct:

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

      



Of course, since no NEWLINE

followed the first 7th cycle, ANTLR reported an error.

The solution was to just tell ANTLR not to follow for the for loop NEWLINE

. It works like a charm, but I'm not that satisfied with this result ...

The last rule of the for-loop looks like (this is just a code cleanup):

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);
            }
        }
    ;

      

+2


a source







All Articles