Hi,
I would expect that the final value of "n" is 2. Here's why -- since
the code block within curly braces constitutes an action and that
action returns a value which determines whether the rule containing
the action is a match or not, the action *must* be executed.
Otherwise, how would you determine if the rule containing the action
is a match? That action of rule a in your example could have contained
code that returns null in some cases, and should therefore be executed
in order to determine whether rule a matches.
So, the way actions and predicates are defined now in PEGjs
(
http://pegjs.majda.cz/documentation) - I think that actions should be
executed as the parser reaches them i.e. I don't think it is OK to
delay execution of actions for later. I would suggest that, if such
behavior is needed, that another type of code blocks is defined, let's
call it "delayed action". This "delayed action" would be defined with
a special syntax. Example:
{ var n = 0; }
start = (a "b") / (a "c") { return n; }
a = "a" ${ n++; }
In this case, the action in rule a ( {n++; } ) is defined as a
"delayed action" ($) and is therefore never executed when the parser
arrives upon it. Rather, the parser assumes that the action will
return a non-null value, stores the action and resumes parsing. If an
alternative of a rule is not matched, the actions stored for that
alternative (and all nested rules that were parsed) are discarded and
the other alternative of the rule is used for parsing, and the actions
for that alternative are stored in the same way. However, if the
parser successfully parses the whole input - it goes back and runs the
stored actions in the right sequence.
In the example -- the parser will try to match the first alternative
of rule start ("ab"), it will successfully match rule a and it will
store (not execute) the action in rule a. However, the parser will
discard the stored action once it detects that there is no "b" to
match the alternative. Next, the parser will try to match the second
alternative of rule start ("ac"), the action of rule a will be stored
again, the whole alternative "ac" will successfully match, and
therefore the stored action will be executed and n will be 1.
Best,
Ivan