Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to create my own errors, but apparently, envoking yyerror() is not enough to tell parser that there is an error. I made a little example to describe my problem better.
So here is a parser that must check if a statement is two numbers with comma between them. And numbers can not start with 0.
input for yacc:
%token DIGIT
#include <stdio.h>
#include <stdlib.h>
void yyerror(char *s);
list: |
list stat ';' {printf("The statement is correct!\n\n");} |
list error ';' {printf("The statement is incorrect!\n\n");}
stat: number ',' number
number: DIGIT {if ($1==0) yyerror("number starts with 0");} |
number DIGIT {$$ = $1*10+$2;}
extern int linenum;
void yyerror(char *s) {
fprintf(stderr, " line %d: %s\n", linenum, s);
for lex:
#include <stdio.h>
#include "y.tab.h"
int linenum = 1;
[0-9] {
yylval = yytext[0] - '0';
return DIGIT;
[ \t\r]+ ;
\n ++linenum;
. return(yytext[0]);
Input for the parser:
34, 43;
32,fs;
03, 23;
And here is the output:
The statement is correct!
line 2: syntax error
The statement is incorrect!
line 3: number starts with 0
The statement is correct!
Even though the error on the 3rd line is found, parsing still continues. How can I fix it?
Upd: the problem was solved by using YYERROR;
If you want it to stop after detecting one error (why?), just return from the production concerned.
By default it will perform error recovery.
The parse is continuing because you have a rule with error
in it, which is an error recovery rule that tells the parser how to recover from an error and continue. If you don't want to continue after an error, remove the error recovery rule. Then yyparse
will immediately return (non-zero) after an error.
Seems to me yyerror()
just prints the error message, but does not set an error state in the parser. Possibly you can modify syntax a bit?
0 {
yylval = 0;
return ZERO;
[1-9] {
yylval = yytext[0] - '0';
return DIGITNOZERO;
yacc:
number: DIGITNOZERO |
number DIGITNOZERO {$$ = $1*10+$2;} |
number ZERO {$$ = $1*10;}
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.