views:

177

answers:

0

Hi everyone,

I want to build parser with CUP tool... I've built LALR(1) grammar from language specification but it seems that I've done it wrong. When CUP generates parser it shows many shift-reduce conflicts that unfortunately causes faulty notifications of syntax errors... I guess that resolving SF conflicts in favor of shift causes the problems...

I've already tried to remove right recursions as musch as possible nad include precedence rules in .cup file....

Can someone help me out what am I doing wrong? Probably i make same mistakes in whole grammar... Thx in advance...

Grammar:

program ::= CLASS prog_id declaration_list main_class method_declaration_list RBRACE;
prog_id ::= IDENTIFIKATOR  {: inc(0); :};
main_class ::= LBRACE {: set_global(); :} ;

declaration_list ::=    declaration_list declaration_part
   |
                        declaration_part
                        |
                        /* epsilon */;

declaration_part ::= const_decl {: inc(2); :}
   |
   var_decl
   |
   class_decl {: inc(0); :} ;


type  ::= IDENTIFIKATOR;

rhs  ::=             NUMBER
                        |
                        CHAR_CONST;

const_decl ::= FINAL type IDENTIFIKATOR EQUAL rhs SEMI
                        |
                        error SEMI:l
                        {: parser.report_error("Izvrsen oporavak do ; u liniji "+lleft,null); :};
var_decl ::= type var_list SEMI
                        |
                        error SEMI:l
                        {: parser.report_error("Izvrsen oporavak do ; u liniji "+lleft,null); :};
var_list  ::= var_list COMMA var_part
                                 |
                                 var_part;

var_part ::=            IDENTIFIKATOR {: if(get_global()) inc(1);
                                         else if (get_in_main()) inc (5); :}
                                 |
                        IDENTIFIKATOR LSQUARE RSQUARE {: if(get_global()) inc(4);
                                                         else if (get_in_main()) inc (5); :};

class_decl ::= CLASS IDENTIFIKATOR LBRACE local_field_list RBRACE
                |
                error RBRACE:l
                {: parser.report_error("Izvrsen oporavak do '}' u liniji "+lleft,null); :};

local_field_list ::=  local_field_list var_decl
    |
    var_decl
                                |
                                /* epsilon */
                                |
                        error LBRACE:l
                        {: parser.report_error("Izvrsen oporavak do '{' u liniji "+lleft,null); :};

method_declaration_list ::= method_declaration_list method_decl
    |
    method_decl
                                |
                                /* epsilon */;

return_type ::=  type | VOID;

method_decl      ::=      return_type method_id LPAREN form_pars RPAREN local_field_list LBRACE stmt_list RBRACE;
method_id       ::= IDENTIFIKATOR:id {: inc(3); if (id.equals("main")) set_in_main(); :};

form_pars ::= parameter parameter_list
   |
   parameter
                        |
                        /* epsilon */;

parameter  ::=  type IDENTIFIKATOR
   |
   type IDENTIFIKATOR LSQUARE RSQUARE;

parameter_list  ::= parameter_list SEMI parameter
   |
   parameter;

stmt_list ::= stmt_list statement
   |
   statement {: if (get_in_main()) inc(6); :}
                        |
          /* epsilon */;

statement  ::= matched
   |
   unmatched;


unmatched  ::= IF LPAREN condition RPAREN statement
   |
   IF LPAREN condition RPAREN matched ELSE unmatched
   |
   WHILE LPAREN condition RPAREN unmatched;



matched ::= dodela
  |
  designator LPAREN act_pars RPAREN SEMI {: inc(7); :}
  |
  designator INC SEMI
  |
  designator DEC SEMI
  |
  BREAK SEMI
  |
  RETURN SEMI
  |
  RETURN expr SEMI
  |
  READ LPAREN designator RPAREN SEMI {: inc(7); :}
  |
  PRINT LPAREN expr RPAREN SEMI {: inc(7); :}
  |
  PRINT LPAREN expr COMMA NUMBER RPAREN SEMI {: inc(7); :}
  |
  blok
  |
  IF LPAREN condition RPAREN matched ELSE matched
  |
  WHILE LPAREN condition RPAREN matched;

blok::= LBRACE stmt_list RBRACE
        error RBRACE:l
            {: parser.report_error("Izvrsen oporavak do '}' u liniji "+lleft,null); :};

dodela ::= designator EQUAL expr SEMI
            |
            error SEMI:l
            {: parser.report_error("Izvrsen oporavak do ; u liniji "+lleft,null); :};

designator ::=  IDENTIFIKATOR identexpr_list;


identexpr_list::=       identexpr_list DOT IDENTIFIKATOR
   |
   identexpr_list  indeks
   |
   /* epsilon */;

relop ::=  TEST_EQUAL | TEST_NOT_EQUAL | LESS | LESS_OR_EQUAL | GREATER | GREATER_OR_EQUAL;

addop ::=   PLUS | MINUS;

mulop ::=   TIMES | DIV | MOD;


act_pars ::=  expr_list
                         |
                        /* epsilon */
                         |
                         error RPAREN:l
            {: parser.report_error("Izvrsen oporavak do ')' u liniji "+lleft,null); :};
expr_list ::=  expr_list COMMA expr
   |
   expr;


expr ::=                  term_list
   |
   MINUS term_list;


term_list ::=  term_list addop term
   |
   term;
term     ::=  factor_list;

factor_list ::= factor_list mulop factor
   |
   factor;


factor ::=    designator LPAREN act_pars RPAREN {: inc(7); :}
    |
    designator
    |
    NUMBER
    |
    CHAR_CONST
    |
    NEW type
    |
    NEW type indeks
    |
    LPAREN expr RPAREN;

indeks::=LSQUARE expr RSQUARE
        |
        error RSQUARE:l
        {: parser.report_error("Izvrsen oporavak do ']' u liniji "+lleft,null); :};

condition ::=  condterm orcondterm_list
    |
    condterm
                                |
                                error RPAREN:l
                                  {: parser.report_error("Izvrsen oporavak do ')' u liniji "+lleft,null); :};

orcondterm_list ::= orcondterm_list OR condterm
    |
    OR condterm;

condterm   ::=  condfact andcondfact_list
    |
    condfact;

andcondfact_list ::= andcondfact_list AND condfact
    |
    AND condfact;

condfact   ::=   expr relop expr;