help-bison
[Top][All Lists]
Advanced

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

Fwd: Newbie requestion on operator precedence and how to resolve an s/r


From: Arlen Cuss
Subject: Fwd: Newbie requestion on operator precedence and how to resolve an s/r conflict correctly.
Date: Wed, 20 Feb 2008 22:43:33 +1100

I didn't send this to list. Trying again, sorry!

On Feb 20, 2008 10:19 PM, <address@hidden> wrote:

> > A shift/reduce conflict occurs where `obj.method(args)' is seen by my
> > parser. Instead of reducing when it sees the upcoming `.', it shifts,
> and
> > it
> > ends up with the whole `obj.method(args).another_method' on the stack.
>
> It may not be what you want, but it looks like correct behavior to me,
> according to your description.
>
> However, it's not clear to me how `yyparse' is supposed to know that
> `obj.method(args)' is an object that can be used in a call to a member
> function.  I don't know Ruby, but couldn't the return value be any type?

In Ruby, everything is an object, and all functions return objects (even if
it's `nil'). This makes it easy for us, since we assume (or rather, we know)
that all functions return objects and hence can have methods called on them.



> This may be a case where you would have to extract this information in an
> action and make it available to the parser somehow, perhaps by "faking" a
> token (as I've described on this list ad nauseum).

The problem isn't so much semantic as it is parsing. It's not reducing a(b),
instead going ahead to shift more tokens and then reducing (b).c to a single
expr.

Something that might help you with precedence is the idea of using a
> hierarchy of expressions, as Donald Knuth did in his METAFONT language.
> He didn't use Bison (or yacc), but I've used this idea for the parser for
> GNU 3DLDF, if you want an example.  Here's an extract from `parser.output'
> to give you the idea:
>
>  1238 numeric_single: LEFT_PARENTHESIS numeric_expression
> RIGHT_PARENTHESIS
>
>  1110 numeric_atom: numeric_variable
>  1111             | numeric_token_atom
>  1112             | numeric_single
>
> ....


Declaring the grammar with precedence inherit is a great idea, and I can see
that could help the situation, at least by making the grammar more clear.
(sometimes reading the parser output is worrying..) I'll give you an idea of
the situation:

expr:           funccall { $$ = static_cast<Expr *>($1); }
              | IDENTIFIER      { $$ = static_cast<Expr *>($1); }
              | FUNCTION_CALL { $$ = new FuncCallExpr(NULL, $1, NULL, NULL);
}
              | IDENTIFIER block { $$ = new FuncCallExpr(NULL, $1, NULL,
$2); }
              | FUNCTION_CALL block { $$ = new FuncCallExpr(NULL, $1, NULL,
$2); }
...
              | expr '.' funccall { $$ = $3; dynamic_cast<FuncCallExpr
*>($$)->target = $1; }
              | expr '.' IDENTIFIER  { $$ = new FuncCallExpr($1, $3, NULL,
NULL); }
              | expr '.' FUNCTION_CALL  { $$ = new FuncCallExpr($1, $3,
NULL, NULL); }
...
              | expr '-' expr   { $$ = new FuncCallExpr($1, new
IdentifierExpr("-"), new ArgListExpr($3), NULL); }
              | expr '*' expr   { $$ = new FuncCallExpr($1, new
IdentifierExpr("*"), new ArgListExpr($3), NULL); }
...
              | '(' expr ')'    { $$ = $2; }

funccall:       IDENTIFIER arglist      { $$ = new FuncCallExpr(NULL, $1,
$2, NULL); }
              | IDENTIFIER arglist block        { $$ = new
FuncCallExpr(NULL, $1, $2, $3); }
              | FUNCTION_CALL arglist   { $$ = new FuncCallExpr(NULL, $1,
$2, NULL); }
              | FUNCTION_CALL arglist block     { $$ = new
FuncCallExpr(NULL, $1, $2, $3); }
              | IDENTIFIER '(' ')'      { $$ = new FuncCallExpr(NULL, $1,
NULL, NULL); }
              | IDENTIFIER '(' ')' block        { $$ = new
FuncCallExpr(NULL, $1, NULL, $4); }
              | IDENTIFIER '(' arglist ')'      { $$ = new
FuncCallExpr(NULL, $1, $3, NULL); }

The semantic values construct an AST. Ruby's syntax is (much to the dismay
of the parser) very flexible; parentheses around arguments to method calls
are optional, which is where much of the woe here comes from. Method names
can end in `!' or `?', which is a FUNCTION_CALL token, otherwise we assume
any identifier could legitimately be a function call (that has to wait until
runtime).

We'll see. :)

Thanks for your consideration, and I'll look through that parser output.

Cheers,
Arlen.


reply via email to

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