help-bison
[Top][All Lists]
Advanced

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

Re: x + (y) + z


From: Derek M Jones
Subject: Re: x + (y) + z
Date: Tue, 08 Mar 2005 13:28:56 +0000

Frank,

>> Your grammar contained a single %merge.  I thought at
>> least two are required?
>
>All the involved (top-level) rules must have a `%merge'. In the
>original example, both happened to be the same rule.

Thanks for a great example.  It looks like the implementation of
%merge is different from that of %dprec (big mistaken assumption
on my part).  After reading the source I still don't understand why
yyparse handles them differently.

My expression parsing problems are now solved.

>The second example works and shows all four trees (after fixing a
>few precedences in the grammar) with another `%merge' -- in the
>final grammar you might need some more.

This is a great example (the attached version tries to be visually
simpler).  It ought to be included in the bison documentation to
show how the details of %merge differ from those of %dprec.
Or perhaps %dprec should be made as general as %merge.
 
%glr-parser
%token ID

%{
#include <ctype.h>
#include <stdio.h>

static const char *input = "(x)+(y)+z";

#define YYSTYPE char *

static void yyerror (const char *s)
{
  printf ("%s\n", s);
}

static YYSTYPE stmtMerge (YYSTYPE a, YYSTYPE b)
{
  char *s;
  asprintf (&s, "\n{ %s %s }\n", a, b);
  return s;
}

static int yylex ();
%}

%%

main: add_expr { puts ($1); };

add_expr: mult_expr              %merge <stmtMerge>
        | add_expr '+' mult_expr %merge <stmtMerge>
                                 { asprintf (&$$, "[b+ %s %s]", $1, $3); }
        | add_expr '-' mult_expr { asprintf (&$$, "[b- %s %s]", $1, $3); }
        ;

mult_expr: factor
         | mult_expr '*' factor  { asprintf (&$$, "[b* %s %s]", $1, $3); }
         | mult_expr '/' factor  { asprintf (&$$, "[b/ %s %s]", $1, $3); }
         ;

factor: '(' add_expr ')'         { asprintf (&$$, "(%s)", $2); }
      | '(' ID ')' factor        { asprintf (&$$, "<%s>%s", $2, $4); }
      | '+' factor               { asprintf (&$$, "u+%s", $2); }
      | '-' factor               { asprintf (&$$, "u-%s", $2); }
      | ID
      ;
%%

static int yylex ()
{
  char c = *input ? *input++ : 0;
  asprintf (&yylval, "%c", c);
  return isalnum (c) ? ID : c;
}

int main ()
{
  printf ("%i\n", yyparse ());
}
derek

--
Derek M Jones                                     tel: +44 (0) 1252 520 667
Knowledge Software Ltd                         mailto:address@hidden
Applications Standards Conformance Testing   http://www.knosof.co.uk


reply via email to

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