Question

I have to create grammar that recognizes this:

ifequal(exp1, exp2) 
    statement1
smaller
    statement2
larger
    statement3

statement1 is executed if two expressions are equal, second if first is smaller third if it is larger. I tried to make something similar to this solution but no luck. I must not use precedence so the grammar has to be changed properly. I am using cup tool for generating parser.

EDIT: smaller and larger parts are optional.

Was it helpful?

Solution

It's the ancient dangling if (if without an else) problem. if you write some code like

if (a == b) then
    if (b == c) then
        do_something;
    else
        do_something_else;

a parser will have problems deciding to which "if" the "else" belongs. One solution is to add a delimiter, like "endif". Example:

if (a == b) then
    if (b == c) then
        do_something;
    endif;
    else
        do_something_else;
endif;

Not confused by indentation any more (which I did wrong deliberately), it is clear what to do now.

That's why a grammar like the one outlined below doesn't work (it produces a lot of conflicts):

stmtlist: stmt
    | stmtlist stmt

stmt: ifequal
    | something_else

ifequal: IFEQUAL '(' expr ',' expr ')' stmtlist opt_lt_gt

opt_lt_gt:
    | SMALLER stmtlist
    | LARGER stmtlist
    | SMALLER stmtlist LARGER stmtlist

But as soon as the statement list is somehow separated from the IFEQUAL statement, e.g. by using braces, the problems vanish.

stmtlist: '{' stmtseq '}'

stmtseq: stmt
     |   stmtseq stmt

The other possibility is to prohibit incomplete statements in the stmtlist. This will more or less double your grammar. It could look like

fullifequal: IFEQUAL '(' expr ',' expr ')' fstmtlist SMALLER fstmtlist LARGER fstmtlist

fstmtlist: fullstmt
    |      fstmtlist fullstmt

fullstmt: fullifequal
    |     some_other

ifequal:  IFEQUAL '(' expr ',' expr ')' fstmtlist opt_lt_gt

opt_lt_gt:
     |     SMALLER fstmtlist
     |     LARGER  fstmtlist
     |     SMALLER fstmtlist LARGER fstmtlist

Personally I prefer the braces solution because it's easy to read, doesn't constrain the statements within an "ifequal" statement and the parser code will be shorter. But I guess you'll need the other solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top