help-bison
[Top][All Lists]
Advanced

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

When %dprec and %merge aren't enough...


From: Marcel Laverdet
Subject: When %dprec and %merge aren't enough...
Date: Mon, 10 Nov 2008 23:10:19 -0800


Hello. I'm writing a parser for ECMAScript (http://www.mozilla.org/js/language/E262-3.pdf ) in Bison right now and I'm having some problems dealing with ambiguities in the language. The relevant portions of my grammar are as follows:

statement_list:
        source_element
|       statement_list source_element
;

source_element:
        statement
|       function_declaration
;

statement:
        block
|       expression_statement
|       empty_statement
<...>
;

block:
        t_LCURLY statement_list t_RCURLY
|       t_LCURLY t_RCURLY
;

expression_statement:
        expression_statement t_SEMICOLON
;

empty_statement:
        t_SEMICOLON
;

expression:
        object_literal
<...>
;

object_literal:
        t_LCURLY t_RCURLY
|       t_LCURLY property_name_and_value_list t_RCURLY
;


Sorry for so much grammar but it's the best way I can convey what's going on here. Basically ECMAScript implements an ObjectLiteral expression which is similar to, for instance, a dictionary in Python.

var foo = {};

would create a new empty ObjectLiteral. This syntax can be ambiguous with Blocks, for example:

if(1){};

It's unclear here whether the child of the if statement should be an empty Block or an empty ObjectLiteral. The ECMAScript spec addresses this simply: "Note that an ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block."

Unfortunately there doesn't seem to be any way to express this in Bison. Additionally it doesn't seem like I can use a %dprec directive since a Block doesn't reduce the semicolon. Basically it gets a conflict of

statement -> block -> t_LCURLY t_RCURLY
and
statement -> expression_statement -> object_literal t_SEMICOLON

In the Block case, the leftover semicolon is parsed as an empty_expression. So I end up with a conflict between either two statement_list's or a source_element and a statement_list.

So far the only potential way I've discovered to resolve the conflict is to put a %merge directive on both expansions of statement_list and manually crawl up my parse tree to figure out which one I should pick. This solution is extremely cumbersome though and I really want to think that there's a better way.

Thanks for any help you can provide!



reply via email to

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