javagrammarsablecc

Problems With SableCC Grammar File


I seem to be having issues with SableCC generating the relevant lexer, node and parse stuff that it normally automatically generates from a grammar file. I'm not implementing an Abstract Syntax Tree at the moment.

When I try to run SableCC with the grammar file below, I get the following error:

[41,33] Redefinition of AFunctionHead.Id. I have know idea what the problem is, but it seems to be something in the productions area. Am I perhaps missing something?

Package Grammar_Specification;

Helpers

  digit = ['0'..'9'];
  letter = (['a'..'z'] | ['A'..'Z']);
  underscore = '_';
  plus = '+';
  minus = '-';
  mult = '*';
  div = '/';
  equals = '=';
  l_par = '(';
  r_par = ')';
  l_curly = '{';
  r_curly = '}';
  unicode_input_character = [0..0xffff];
  lf  = 0x000a;
  cr  = 0x000d;
  line_terminator =  lf | cr | cr lf;
  input_character = [unicode_input_character - [cr + lf]];
  not_star = [input_character - '*'] | line_terminator;            
  not_star_not_slash = [input_character - ['*' + '/']] | line_terminator;
  multi_line_comment = '/*' not_star+ '*'+ (not_star_not_slash not_star* '*'+)* '/';
  line_comment = '//' input_character* line_terminator?;

Tokens

  func = 'FUNC';
  id = (letter(letter | digit | underscore)* | underscore(letter | digit | underscore)*);
  float_literal = minus? digit (digit)* ('.' (digit)*)? (('e' | 'E') (plus | minus)? digit (digit)*)?;
  whitespace = (' ' | '\t' | '\n' | '\r')+;
  comment = multi_line_comment | line_comment;

Productions

  program = function_decl*statement*;

  function_decl = function_head function_body;

  function_head = func id l_par id r_par;

  function_body = l_curly statement* r_curly;

  statement = id equals expression;

  expression = expression plus term |
             expression minus term |
             term;

  term = term mult factor |
         term div factor |
         factor;

  factor = l_par expression r_par |
           identifier l_par expression r_par |
           float_literal |
           id;

Solution

  • This is explained in the SableCC documentation, aka Étienne Gagnon's master's thesis:

    Unlike alternatives, elements have an obvious candidate for name which is the identifier of the element itself. This will work, as long as an element does not appear twice in the same alternative. In that case the current version SableCC requires a name for at least one of the two elements. (For backward compatibility, one occurrence of the repeated element can remain unnamed). SableCC will issue an error if not enough names are provided. Element names are specified by prefixing the element with an identifier between square brackets followed by a colon.

    In other words, you can't use id twice in the production for function_head without giving at least one of them a name (whether or not you're generating an AST).

    Try something like this:

    function_head = func id l_par [parameter]:id r_par;