1
votes

As I've stated in the title, I'm trying to write a parser using flex and bison. However, no matter how I modify the files, the error "syntax error in line 1" always appears.

So I decided to write a very simple example to see whether my method is right or not.

This is the simple file "c1.isc", which will be read:

1 nand
2 nor
3 nand
4 nor
5 xor

This is the token.l file:

%{
# include <stdio.h>
# include <string.h>
# include "parse.tab.h"


struct{
    char *symbol;
    int val;
} symtab[]={
"nand", 1,
"nor", 2,
"xor", 3,
"0",0
};

extern int yylval;

%}

DIGITS [0-9]+
BLANK [ \t\n]+
ALPHA [a-z]+

%%

{DIGITS} {yylval=atoi(yytext);return(NUM);}
{ALPHA} {yylval=lookup(yytext);return(TYPE);}
{BLANK} ;

%%
lookup(s)
char* s;
{int i;
for (i=0;symtab[i].val!=0;i++)
{
if(strcmp(symtab[i].symbol,s)==0)
break;
}
return(symtab[i].val);
}

This is the parse.y file

%{
# include <stdio.h>


extern FILE *yyin;

int gi;


%}

%token NUM TYPE

%%

parto: NUM
       {gi=$1;printf("num=%d\t",gi);}
       TYPE
       {gi=$3;printf("type=%d\n",gi);}
       ;

%%

yyerror(s)
char *s;
{
    extern int yylineno;
    extern char yytext[];

    fprintf(stderr, "%s in line %d near <%s>\n", s, yylineno, yytext);
    exit(-1);
}

main()
{FILE *x=fopen("c1.isc","r");
 yyin=x;
 yyparse();
} 

I think this is almost the easiest example, but still, the parser only outputs the first line as "num=1 gat=1" and then "syntax error near line 1".

I really don't know why. I'm sure the token file is right because I've tested it using the following way:

%{
# include <stdio.h>
# include <string.h>


struct{
    char *symbol;
    int val;
} symtab[]={
"nand", 1,
"nor", 2,
"xor", 3,
"0",0
};

int val;

%}

DIGITS [0-9]+
BLANK [ \t\n]+
ALPHA [a-z]+

%%

{DIGITS} {val=atoi(yytext);printf("num=%d\t",val);}
{ALPHA} {val=lookup(yytext);printf("type=%d\n",val);}
{BLANK} ;

%%
lookup(s)
char* s;
{int i;
for (i=0;symtab[i].val!=0;i++)
{
if(strcmp(symtab[i].symbol,s)==0)
break;
}
return(symtab[i].val);
}

main()
{
FILE *x=fopen("c1.isc","r");
yyin=x;
yylex();
}

And the yylex() could work.

My way of compiling is 1. flex token.l 2. bison -d parse.y 3. cc lex.yy.c parse.tab.c -lfl

Then I will get a.out and when I run a.out, the error appears.

I guess that's because my rules in parse.y file is not right but how could the error always appear in the very first line?

I've used the following rules to make it work.

parti: 
     | parti parto
     ;

parto: NUM
       {gi=$1;printf("num=%d\t",gi);}
       TYPE
       {gi=$3;printf("type=%d\n",gi);}
       ;
1
Please take care to tag questions properly. the Flex tag is used for the Adobe/Apache UI Framework. gnu-flex is used for the Lexical Analyzier.JeffryHouser
Thanks for helping me use the right tag!Michael

1 Answers

2
votes

Maybe I'm missing something here, but your grammar only says that the input should be a single NUM and a single TYPE. That's all. So you get an error on the second line of the input, when the parser finds more stuff.

You'll have to add a rule that handles several lines. Something like this:

lots_of_partos: parto lots_of_partos | /* empty */ ;