2
votes

a simple calculator support only + - * / and integer. I use GNU/Linux.

hoc1.l:

%{
#include "y.tab.h"
extern int yylval;
%}

%%
[ \t] { ; }
[0-9]+ { sscanf(yytext, "%d", &yylval); printf("\nget %d\n", yylval); return NUMBER; }
\n  {return 0;}
%%

int yywrap(void) {
    return 1;
}

hoc1.y

%{
#include<stdio.h>
#define YYSTYPE int
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
list:   
    | list '\n'
    | list expr '\n'  {printf("\t%d\n",$2);}
    ;
expr:   NUMBER        { $$ = $1; }
    |   expr '+' expr {$$ = $1+$3;}
    |   expr '-' expr {$$ = $1-$3;}
    |   expr '*' expr {$$ = $1*$3;}
    |   expr '/' expr {$$ = $1/$3;}
    ;
%%

int main(void)
{
    yyparse();
    return 0;
}

int yyerror(char *s) {
    fprintf(stderr, "*%s*\n", s);
    return 0;
}

runtime-error:

% ./hoc
8+9

get 8
+
get 9
*syntax error*

why and how to sovle it, thx!

1
Syntax error means bad input data, but the one thing you didn't provide is the input data. Is '\r' a possibility?david.pfx
@davidusrex I provide the input data at the bottom of this post ( after "runtime-error"... ) and I use linux so there is really '\n' instead of '\r' ? thx.songhir

1 Answers

3
votes

You forgot to include your operators in your lex file, and you should return nonzero on a successful token read: returning 0 intuitively means there was no match by yylex. Remove the line in your lex file handling the newline character and replace it with the following:

[-+*/\n] { return *yytext; }
. { yyerror("unrecognized character"); return 0; }

Now it should work. Returning *yytext allows your yacc grammar to parse an expression successfully, e.g. if you get a '+', return it to allow the grammar to parse properly.