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.
>
>