I'm trying to build a lexer.l and parser.l program that will scan the following sample input and produce sample output.
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.
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.