I didn't send this to list. Trying again, sorry! On Feb 20, 2008 10:19 PM, <[EMAIL PROTECTED]> 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. _______________________________________________ help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison