Re: Weird Rule Matching
tom2 <[email protected]> Thu, 7 Apr 2022 09:14:43 +0100
| Newsgroups | gmane.comp.parsers.bison.general |
|---|---|
| Message-ID | <[email protected]> |
Thanks for the reply Chris.
The full definition for my conditional rule is:
conditional:
IF comparison '{' END program '}' END {
F_CONDITIONAL_BLOCK -= 1;
std::cout << line_num << " F_CONDITIONAL_BLOCK: " << F_CONDITIONAL_BLOCK
<< std::endl;
if (F_CONDITIONAL_BLOCK > 0) {
F_CONDITIONAL_ELSE_BLOCK = PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.top();
PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.pop();
} else {
F_CONDITIONAL_ELSE_BLOCK = false;
}
link_with_parent();
}
| IF comparison '{' END program '}' END ELSE '{' END program '}' END {
F_CONDITIONAL_BLOCK -= 1;
if (F_CONDITIONAL_BLOCK > 0) {
F_CONDITIONAL_ELSE_BLOCK = PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.top();
PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.pop();
} else {
F_CONDITIONAL_ELSE_BLOCK = false;
} link_with_parent();
}
Which makes sense with your explanation.
Again, I am not sure if there is a better way to do this, I have mostly
been making it up as I go along...
It does actually cause an issue because I am rely on the idea that the
rule will be matched before the next if token is found, in order to have
nested conditionals.
I think I can figure out another, probably kuldgy, solution to this
problem though.
Thanks,
Tom.
On 4/7/22 06:52, Chris verBurg wrote:
> Tom,
>
> I'm thinking this is just the "LA" part of "LALR" parsing. Imagine if
> you had another rule for "if" that included an "else" clause. The
> parser would need to know if the token after '}' is an "else" or not,
> because it changes whether it reduces the if-else rule or the just-if
> rule.
>
> Even though that's not the situation here, I seem to recall bison
> always looks ahead one token. I think it's because only looking ahead
> when needed ended up creating performance problems.
>
> Is this causing actual problems, or is it just an oddity you saw?
>
> -Chris
>
>
> On Wed, Apr 6, 2022 at 2:22 PM Tom <[email protected]> wrote:
>
> Hi,
>
> Sorry if this is incorrect place to ask, this is my first time
> using a
> mailing list.
>
> I have a language that I would like to parse:
>
> if N == 2 {
>
> A = 100;
>
> }
>
> if N == 3 {
>
> B = 123;
>
> }
>
> To do this I have the relevant rules:
>
> program:
> statement program
> | statement
> ;
> statement:
> assignment
> | conditional
> | loop
> | END
>
> conditional:
> IF comparison '{' END program '}' END {
> std::cout << "F: " << line_num << std::endl;
> F_CONDITIONAL_BLOCK -= 1;
>
> if (F_CONDITIONAL_BLOCK > 0) {
> F_CONDITIONAL_ELSE_BLOCK =
> PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.top();
> PREVIOUS_F_CONDITIONAL_ELSE_BLOCK.pop();
> } else {
> F_CONDITIONAL_ELSE_BLOCK = false;
> }
>
> link_with_parent();
> }
> My rule to match the IF token is as follows:
>
> if {
> std::cout << "S: " << line_num + 1 << std::endl;
>
> /* some extra, non-related code */
>
> return IF;
> };
>
> For the above program, I get the following output:
>
> S: 1
>
> S: 4
>
> F: 3
>
> F: 6
>
> What is weird here is that IF token on line 4 is matched *before* the
> conditional rule is matched on line 3.
>
> I know I have probably done something wrong, I have mostly come up
> with
> this myself, but I am pulling my hair out here trying to figure the
> issue out.
>
> Tom.
>
>