Search code examples
lex

lexer.l program throwing error while trying to return a token


I'm trying to build a lexer.l and parser.l program that will scan the following sample input and produce sample output. enter image description here

For this I wrote lexer.l and parser.l as follow:

lexer.l

%option noyywrap

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "parser.tab.h"
    extern FILE *yyin;
    extern FILE *yyout;

    int lineno = 1; // initialize to 1
    void ret_print(char *token_type);
    void yyerror();
%}

digit     "0"[0-1]

%%
[ \t\r\f]+      {}
{digit}         { yylval.int_val   = atoi(yytext); return BINARY; }
"\n"            { lineno += 1; }
.               { yyerror("Unrecognized character"); }
%%

parser.y

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    extern FILE *yyin;
    extern FILE *yyout;
    extern int lineno;
    extern int yylex();
    void yyerror();
%}

/* YYSTYPE union */
%union{
    int int_val;
}

%token<int_val> BINARY
%token<int_val> ADDOP

%start program

%%
program: {printf("started\n");} ;
%%

void yyerror ()
{
fprintf(stderr, "Syntax error at line %d\n", lineno);
exit(1);
}

int main (int argc, char *argv[])
{
    int flag;
    flag = yyparse();

    printf("Parsing finished!\n");  
    return flag;
}

my Makefile

no3:parser.y lexer.l
        bison -d parser.y  
        flex lexer.l  
        gcc -o a.out parser.tab.c lex.yy.c  
        ./a.out

clear: 
        rm *.txt, *.tab.h 

Now it keeps throwing errors when I'm trying to return a token.

make no3
bison -d parser.y  
flex lexer.l  
gcc -o a.out parser.tab.c lex.yy.c  
./a.out
started
r
Syntax error at line 1
make: *** [Makefile:5: no3] Error 1

I would be grateful if you can please help me on this point. Thanks a lot in advance.


Solution

  • r does not match any lexical rule other than the fallback rule at the end, which calls yyerror. That would have been clearer if your implementation of yyerror printed the error message passed as the first parameter.

    Your definition of yyerror does not take any parameters, so it's actually undefined behaviour to call it with an argument. Your compiler would have told you about that had you declared yytext consistently: in C, you declare a function with no parameters as

    void yyerror(void);
    

    because

     void yyerror();
    

    declares a function without specifying what or how many parameters it has. You're allowed to do that for backwards compatibility, but you really shouldn't.

    You should also always compile with -Wall (at least) to give your compiler a chance to warn you about things which are not technically errors but are probably not what you wanted to write. Unfortunately, gcc would not have warned you about this particular error (although future versions probably will). See this answer.