title: Java CC issue - "Expansion within "(...)*" can be matched by empty string"
body: <p>We've been given a grammar to patch up and parse using Java CC. One of the problems with it is several occurrences of "expansion within "(...)*" can be matched by empty string. I understand this error is caused when something can be matched zero or more times <em>inside</em> something else that can be matched zero or more times. </p>
  
  <p>What I don't understand is how to fix it. (Our instructor hasn't been saying much, "You have to be careful how you word it." </p>
  
  <p>The problem area of the grammar, along with its associated Java CC code is shown below. Any ideas or advice would be greatly appreciated. </p>
  
  <pre><code>program := ( decl )*
             ( function ) *
             main_prog
  
  decl := ( var_decl | const_decl )*
  
  var_decl := var ident_list : type ( , ident_list : type)* ;
  
  const_decl := const identifier : type = expression ( , identifier : type = expression)* ;
  
  function :=
              type identifier ( param_list)
              ( decl )*
              ( statement ; )*
              return ( expression | e ); //e is greek epsilon character
  
  main_prog := 
              main
              ( decl ) *
              (statement ; )*
  </code></pre>
  
  <p>The issue is with the way decl is declared I think. It is declared here in actual Java CC code: </p>
  
  <pre><code>void decl():{}
  {
  ( var_decl() | const_decl())*
  }
  </code></pre>
  
  <p>If I change that Kleene closure above to + , all the other errors caused by this go away. However the instructor says the star should remain, and we need to be careful how we word it. I've found lots of resources on left factoring, left recursion removal and the like, but scant little on this particular issue. The above code doesn't actually have an error in Java CC, but is the cause of further ones as below: </p>
  
  <pre><code>void program():{}
  {
  ( decl() )* //error here - Expansion within "(...)*" can be matched by empty string
  ( function() )*
  main_prog()
  }
  
  void main_prog(): {}
  {
  &lt; MAIN &gt;
  ( decl() )* //same error on this line
  (statement() &lt; SCOLON &gt;)*
  }
  
  void function(): {}
  {
  type() &lt; ID &gt; &lt;LPARENT &gt; param_list() &lt; RPARENT &gt;
  ( decl() )* //same error on this line
  ( statement() &lt; SCOLON &gt; )*
  &lt; RET&gt; ( expression() | {} ) &lt;SCOLON &gt; // {} is epsilon
  }
  </code></pre>
  
  <p>Any ideas on how to go about fixing this would be very much appreciated. </p>