0
votes

I am pretty new to lex and yacc. I was trying out a grammar that creates matrices and performs some operations like adition,multiplication etc.

Here is the grammar I am using

 program:     block ENDS
 block:       stmt | block ENDS stmt
 stmt:        defn_stmt | init_stmt | print_stmt | oper_stmt
 defn_stmt:   DEF definitions
 definitions: MATID OPENSQ NUMBER COMMA NUMBER CLOSEQ ENDS | 
              definitions COMMA MATID OPENSQ NUMBER COMMA NUMBER CLOSEQ ENDS
 init_stmt:   INIT MATID [mat_contents]
 mat_contents: NUMBER | mat_contents COMMA mat_contents | mat_contents RANGE mat_contents
 print_stmt:  PRINT MATID
 oper_stmt:   MATID mat_operator inputs | MATID CMUL inputs
 mat_operator: ADD | MMUL
 inputs: MATID COMMA MATID

But for the following input am getting syntax error at second DEF.

 DEF A [2,3]; // defines a 2X3 Matrix A.
 DEF I [2,3]; // defines a 2X3 Matrix A.
 DEF BA[2,3],C[2,3], D[3,4], E[2,4];

ALso while running yacc its showing conflicts: 4 shift/reduce.

What causes the syntaxerror here? How can I correct it?

2
There's not really enough information there to tell - the definitions for all your terminals are missing. However, it does seem that your grammer doesn't include anything at all for dealing with the semicolons in your input... - twalberg
@twalberg ENDS is for semicolon - Amrith Krishna
In that case, your definitions expects to end with an ENDS, but then you also expect your stmts to be separated by an ENDS... Maybe DEF A [2,3];; DEF I [2,3];; would avoid the syntax error... - twalberg

2 Answers

2
votes

definitions must end with ENDS (;, apparently), which means that defn_stmt must end with ;. However, a stmt must always be followed by a ;. So the grammar insists that a definition be followed by two semicolons.

You should remove the ENDS from the defn_stmt productions. Also, you might want to factor out the two occurrences of MATID OPENSQ NUMBER COMMA NUMBER CLOSEQ; that's not the cause of your problems, though.

One obvious ambiguity (actually, two) is in the productions:

mat_contents: NUMBER
            | mat_contents COMMA mat_contents
            | mat_contents RANGE mat_contents

since it is (exponentially) ambiguous how to parse:

NUMBER COMMA NUMBER COMMA NUMBER RANGE NUMBER COMMA NUMBER

You could solve this with precedence declarations, or you could be more precise in your grammar.

1
votes

should be something like this, Not verified.

program:       block ; 
block:         stmt | block ; stmt 
stmt:          defn_stmt | init_stmt | print_stmt | oper_stmt 
defn_stmt:     DEF   definitions
definitions:   MATID  [NUMBER,NUMBER]  |  definitions,  MATID [NUMBER,NUMBER]
init_stmt:     INIT MATID [mat_contents] 
mat_contents:  NUMBER |  mat_contents ,  mat_contents |  mat_contents :  mat_contents 
print_stmt:    PRINT MATID 
oper_stmt:     MATID mat_operator inputs |  MATID CMUL  inputs
mat_operator:  ADD | MMUL 
inputs:        MATID, MATID