3

I am trying to compile a simple bison parser using a given prefix - as was resolved in this question. I'm using Bison version 2.4.1 and flex version 2.5.35 (I can't use bison 2.6). I have been running into a compiler error that has me running around in circles:

Namely:

make
Making all in src
make[1]: Entering directory `/stage/pool14/eholum/yacc_example/src'
/bin/sh ../ylwrap parcalc.y y.tab.c parcalc.c y.tab.h parcalc.h y.output parcalc.output -- bison -y  -d -p="calcYY"
...yacc_example/src/parcalc.y:27.7-13: warning: type clash on default action: <result> != <>
conflicts: 4 shift/reduce
updating parcalc.h
gcc -DPACKAGE_NAME=\"calculator\" -DPACKAGE_TARNAME=\"calculator\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"calculator\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"calculator\" -DVERSION=\"1.0\" -I.     -g -O2 -MT parcalc.o -MD -MP -MF .deps/parcalc.Tpo -c -o parcalc.o parcalc.c
parcalc.c:1053: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1061: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1064: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1067: error: expected identifier or ‘(’ before ‘=’ token
parcalc.c:1089: error: expected identifier or ‘(’ before ‘=’ token
parcalc.y:75:21: error: lexcalc.c: No such file or directory
make[1]: *** [parcalc.o] Error 1

I'm currently using automake, but I get the same error if I build using flex and bison then try compiling with c. Here's my Makefile.am:

bin_PROGRAMS = calculator
AM_YFLAGS = -d -p="calcYY"
calculator_SOURCES = parcalc.y lexcalc.l

Where the lex code is is in lexcalc.l (note I'm using %option to specify the prefix, but I get the same error when I use the cl flag):

%{
#include <stdio.h>
#include "parcalc.h"
%}

%option noyywrap
%option prefix="yy"

%%

[ \t] ; 

[0-9]+\.[0-9]+ { 
    yylval.flval = atof(yytext);
    return FLOAT;
}

[0-9]+ {
    yylval.inval = atoi(yytext);
    return INT;
}

- { return MINUS; }

\+ { return PLUS; }

\n {
    yylineno++; 
    return NEWLINE; 
}

. ;

%%

And the Bison code is in parcalc.y :

%{
#include <stdio.h>
%}

%token INT FLOAT PLUS MINUS NEWLINE;

%union {
    int inval;
    float flval;
    char oper;
    char result[100];
}

%type <inval> INT;
%type <flval> calc FLOAT
%type <oper> PLUS MINUS;
%type <result> line;

%%

lines:
     line lines
    | line
    ;

line:
      NEWLINE
    | calc NEWLINE {
        printf("Result = %f\n", $1);   
      }
    ;

calc :
      calc PLUS calc { 
        ($$ = $1 + $3);
      }
    | calc MINUS calc { 
        ($$ = $1 - $3); 
      }
    | INT { 
        ($$ = $1);
      }
    | FLOAT { 
        ($$ = $1); 
      }
    ;

%%

extern int calcYYparse();
extern FILE *calcYYin;

int main() {

    FILE *myfile = fopen("infile.txt", "r");

    if (!myfile) {
        fprintf(stderr, "can't open infile.txt\n");
        return 1;
    }

    calcYYin = myfile;

    do {
        calcYYparse();
    } while (!feof(calcYYin));

    return 0;
}

void calcYYerror(const char *s) {
    fprintf(stderr, "Unrecognized format\n");
}

I should note that everything seems to work fine when I discard the prefixes, so I'm guessing that there's something awry with how things are externally declared in the generated c files. Looking through those I haven't been able to figure it out yet. If anyone has messed around with multiple parsers and has some insight on how to make these things play nicely together I would really appreciate it.

Community
  • 1
  • 1
doggie_breath
  • 782
  • 1
  • 6
  • 21
  • 2
    Have you looked at the lines in the generated `parcalc.c` file about which the compiler complains? You shouldn't try to fix the problem by modifying that file, but the nature of the erroneous code may give you a clue as to what the problem is. – John Bollinger Sep 18 '15 at 21:07
  • 3
    I would start with `parcalc.c:1053: error: expected identifier or ‘(’ before ‘=’ token` . If you look at `parcalc.c` on/around line 1053 does it give you any hints as to what it might be associated with? Giving the output in your question for the 5 lines/before after line 1053 could help. – Michael Petch Sep 18 '15 at 21:08
  • 3
    Ah I just noticed one little thing that might be related. `AM_YFLAGS = -d -p="calcYY"` . In particular the `=` sign after `-p`. I believe it is literally turning the prefix to `=calcYY`. Try changing it to `-p"calcYY"`. – Michael Petch Sep 18 '15 at 21:37
  • Ah, I replaced the AM_YFLAGS with what you suggested, @Michael, and I also realized that I have to be careful about how I name functions, given that yyparse, yylex, yyerror, yynerrs, yylval, yylloc, yychar and yydebug are changed by the bison -p option. I now seem to have a different error with no helpful info included in the message (/bin/sh ../ylwrap lexcalc.l lex.yy.c lexcalc.c -- flex make[1]: *** [lexcalc.c] Error 1) I'll update if I figure it out. – doggie_breath Sep 18 '15 at 22:21
  • 1
    Have no idea if there are other issues, but figured at a minimum you ended up with variable names with `=` in it. – Michael Petch Sep 18 '15 at 22:23
  • @Erik - I also recommend that if there are other errors not related to the issue I observed then it might be more appropriate to start a new question rather than update this one. Sounds like `error: expected identifier or ‘(’ before ‘=’ token` issue has been resolved. – Michael Petch Sep 18 '15 at 22:45
  • @MichaelPetch I'll do that. Thanks for the help! I'll either update this with the new post or the solution if I figure it out. – doggie_breath Sep 18 '15 at 22:51

1 Answers1

2

Thanks to Michael for spotting the issue with the prefix flag being passed to the bison compiler. Namely

AM_YFLAGS = -d -p="calcYY"

versus

AM_YFLAGS = -d -p"calcYY"

Also slightly related is that the prefix only changes yyparse, yylex, yyerror, yynerrs, yylval, yylloc, yychar and yydebug. So yyin did not need to change.

doggie_breath
  • 782
  • 1
  • 6
  • 21