The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
%{
=head1 SYNOPSIS

This grammar deals with the famous ambiguous PL/I phrase:

                if then=if then if=then

The (partial) solution uses C<YYExpect> in the lexical analyzer to predict the token
that fulfills the parser expectatives.

Compile it with:

               eyapp -C PLIConflictNested.eyp
               eyapp -P Assign2.eyp

Run it with:

               ./PLIConflictNested.pm -t -c 'if if=then then then=if'

for more detail:

               ./PLIConflictNested.pm -d -t -c 'if if=then then then=if'

and also

               ./PLIConflictNested.pm -t -i -c 'if then=if then if=then

The problem arises again

Also try:

                ./PLIConflictNested.pm -t -c 'if then=if then if a=b then c=d'

=cut

%}

%strict

%token then =  %/(then)\b/
# %token if =%/if\b/ !Assign2%
%token if   =  { 
                  my $pos = pos();
                  if (/\Gif\b/gc) { 
                    if ($self->expects('if')) {   
                       my $oldselfpos = $self->{POS};
                       $self->{POS} = pos();   
                       if ($self->YYPreParse('Assign2')) {
                         $self->{POS} = $oldselfpos;
                         return ('if', 'if'); 
                       }
                       else {
                         $self->{POS} = $oldselfpos;
                       }
                    }
                  }
                  pos($_) = $pos;
               }
%token ID  = /([a-zA-Z_]\w*)/

%tree bypass
%%
stmt: 
    ifstmt 
  | assignstmt
;

ifstmt: 
     %name IF
    if expr then stmt
;

assignstmt: 
    %name ASSIGN
    id '=' expr
;

expr:
    %name EQ
    id '=' id
  | id
;

id: 
    %name ID
    ID
;

%%