in reply to Re: Parse::Recdescent optional subrule commit
in thread Parse::Recdescent optional subrule commit

Hello! It becomes clear now that I have some problems in speaking my thoughts :)

the failure of an optional subrule means that it is not present

That is the way Parse::RecDescent thinks of it indeed. But from a human point of view we can say that failure of a rule can also mean that it IS present but contains some errors that prevent it from matching. And using a <commit> directive is a good way to inform the parser that "This production is present, I'm sure of it. If it will not match then it apparently contains an error, and you should fail without trying other alternatives as they will not match a fortiori". The only problem with <commit> is that it only works on other productions of the same rule and has no effect on subrules. That trick in FAQ is a try to extend the power of <commit> on subrule calls.

You are now saying, as I think you always intended to be saying, that the grammar must match one of the available alternatives, or declare that an error has occurred. I do not think that you actually mean for the rule to be “optional” at all

I'm sorry for my question being so ambiguous. Once again, as you can see in FAQ, that is not a try to question mysubrule's optionality but to avoid obligatory subsequent conditions that could be very hard to write in complicated grammars. I totally understand how does this grammar from my example work. It works correctly. I just want to tweak it in such a manner that discovering an 'ID' would mean that this optional mysubrule is actually present and its failure would definitely indicate a mistake in the text being parsed.

  • Comment on Re^2: Parse::Recdescent optional subrule commit

Replies are listed 'Best First'.
Re^3: Parse::Recdescent optional subrule commit
by locked_user sundialsvc4 (Abbot) on May 01, 2012 at 14:27 UTC

    It offhand seems to me that the behavior you might be seeking is one thing that a recursive-descent parser really does not do:   it does not “back up.”   A parser that is based, say, on Yacc or Bison-type technology can explore an avenue, find it to be fruitless, and then fall back several levels in quest of something else.   An RD parser does that sort of thing with much more difficulty, or not at all.   In particular, if you have used commit then you have cut-off any fallback beyond that point; even if the grammar-rule containing it subsequently “fails.”   The call has already been made:   its presence in the grammar is not a so-called “promise,” but an actual reality that occurs when the element is encountered.

    There are other parser technologies available in the Perl environment, and it may well be that your particular requirements would be more suitable to one of them.   Otherwise, the grammar structures that you must use (such as ones which I suggested) may not entirely represent your conceptual notion of how the language is put together ... but are, in part, shaped by the characteristics of the RD parser.   I encountered this many times in my previously mentioned major parsing project.

      I thought backtracking is exactly how RecDescent does selection between multiple alternatives.

      But anyway, I don't see this as an obstacle here. The desired behaviour could already be achieved if there was some way to write an action that would only be executed in case the rule it is placed in is committed.

      And I don't see any way to do so. I thought of using the $commit variable but it shows the state of commitment to the current production, not the whole rule.