[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Weird Rule Matching
From: |
tom2 |
Subject: |
Re: Weird Rule Matching |
Date: |
Thu, 7 Apr 2022 09:14:43 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 |
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 <tom@tomflux.xyz> 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.