I’m trying to implement a simple basic, but I’m afraid the operation of Bison is not clear for me. To implement a ‘while’ loop the examples I found uses the construction below (or similar):
while ‘(‘ expression ‘)’ statement { $$ = opr(WHILE, 2, $3, $5); }
But actually there are two hidden jumps I ought to assign tokens to. I mean as follows:
while // no token assigned
( expression ) // take appropriate sequence of tokens
jump back if not met // insert a conditional jump token - a jump to expression checking
statement // take appropriate sequence of tokens
jump unconditionally // insert a token to jump to expression checking
However neither the expression length, nor the statement length is not known, I can record the address the ‘while’ keyword is entered, so last jump can be calculated. But what will provoke Bison to insert a conditional jump token?
It’s not clear what you are trying to do exactly but a while statement is often “compiled” into something like
What I usually did with interpreters I wrote is to have a phase that solves all labels after the parsing so that just jumps and labels with dummy names are emitted while parsing the syntax tree, then it’s possible to caculate the address of each label and adjust all of them, so for example you would have
This can be done easily by using also a simple
std::mapto store all the labels so that after generating the parsing tree you just go through the code, computes all addresses of labels (which disappears from the AST) and then insert correct addresses in the jumps.Just to make clearer what I usually do:
Now, in my case I generate ASM text output of a lower level language because I have then another parser which parses this sort of ASM code into binary but you can just join these two steps. What happens in the ASM parser is the following:
That does:
This because the assembler knows the internal state of the assembling code and knows the current offset from the beginning of the program.
At the end of assembling phase all labels are solved:
As you can see I brutally copy the address of the jump inside some bytes that I reserved when I assembled JUMP calls.