简体   繁体   中英

JavaCC - How can I remove all choice-conflicts in this statement without lookahead?

I'm currently developing a parser to my grammar. My objective is to make it without lookaheads, and this is the one that I am really struggling with.

Here is a minified example that I believe is enough to demonstrate the problem i'm having.

void main() : {}
{
    (A())* (B())*
}

void A() : {}
{
    C() <ID>
}

void B() : {}
{
    <ID> Z()
}

void C() : {}
{
    <bah>
    | <bha>
    | <ID>
}

This is the output warning (I want to remove it)

Warning: Choice conflict in (...)* construct at line 200, column 23.
         Expansion nested within construct and expansion following construct
         have common prefixes, one of which is: <ID>
         Consider using a lookahead of 2 or more for nested expansion.

Really we need to know more about Z . I'll assume that L( Z ) (ie the language generated by Z ) does not contain the empty sequence and contains no sequences that start with an ID , bha , or bah . I'll also assume that the first token after main can't be ID , bha , or bah .

In this situation, I'd almost certainly use lookahead

void main() : {}
{
    AsBs()
}

void AsBs() : {}
{ 
  LOOKAHEAD( A() )
  A() AsBs() ;
|
  (B()*)
|
  {/*nothing*/}
}

with A , B , and C as in the original post.


However, the poster wants a solution without using lookahead. Here is one. I made the same assumptions as above.

void main() : {}
{
    AsBs()
}

void AsBs() : {}
{
    C1() <ID> AsBs()
|
    <ID>  // This ID might be the start of either A or B
    ( <ID> AsBs()  // That ID started an A
    | Z() (B())* ) // That ID started a B.
|
    {/*nothing*/}
}

void B() : {}
{
    <ID> Z()
}

void C1() : {}
{
    <bah>
    | <bha>
}

There is no need for A or C here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM