help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Grammar failing single lookahead


From: Tim Van Holder
Subject: Re: Grammar failing single lookahead
Date: Wed, 30 May 2007 12:55:25 +0200
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

Frans Englich wrote:
> The intent of the grammar is to enforce that declarations appear in a certain 
> order(FirstProlog, SecondProlog), that the declarations are optional, and 
> they take the form of "declare <statically known keyword>".
> 
> This is something that naturally leads to a shift/reduce conflict. As far as 
> I 
> know, this can be solved in two ways:
> 
> * Tokenize "declare foo" into one token, instead of two(the conflict goes 
> away).
> * Generate a GLR parser. The conflict stays, but the parser survives it.
> 
> For the user, I think the latter is a better alternative since it will yield 
> better error reporting(since the token granularity is higher).
> 
> But is it solvable in some other way? For instance, can the grammar be 
> rewritten in some way such that it can be parsed as LR(1)? I doubt it.

Try moving semantic checks like this out of the actual grammar
definition; often conflicts like this can be avoided by doing so.
Simply allow a sequence of any type of declaration, and do the
are-they-in-an-acceptable-order check on the AST. You could do this in
actions during the parse, or as part of a dedicated semantic check phase
on the full AST once it's constructed by yyparse().
You only need a GLR parser when it's not an error condition, i.e. if
DECLARE A should be parsed differently if it's after DECLARE B.

So instead of:

foo
: mul_declare_a mul_declare_b rest_of_program
;

mul_declare_a
:
| mul_declare_a declare_a
;

mul_declare_b
:
| mul_declare_b declare_b
;

declare_a
: DECLARE A rest_of_a_decl
;

declare_b
: DECLARE B rest_of_b_decl
;

You could simply have:

foo
: mul_declaration rest_of_program
  {
    // Alernative 1 - validate list in its entirety
    if (!validate_declaration_order($1))
      YYABORT;
  }
;

mul_declaration
:
| mul_declaration declaration
  {
    // Alternative 2 - check when adding to the list
    if ($1 != 0 && !validate_declaration_order($1->last_one, $2))
      YYABORT;
  }
;

declaration
: DECLARE A rest_of_a_decl
| DECLARE B rest_of_b_decl
;

(note about my rule naming: I use plus_ and mul_ prefixes to indicate
the equivalents of + and * regex operators)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]