添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
爱玩的牙膏  ·  PostgreSQL ...·  10 月前    · 
憨厚的熊猫  ·  The value of "offset" ...·  1 年前    · 
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;}
                Your solution doesn't help since i still need to tell the parser about error somehow. But thank you anyway!
– user5537584
                Nov 18, 2015 at 20:35
                By the way, the problem was solved by using YYERROR like this: number: DIGIT {if ($1==0) {yyerror("number starts with 0"); YYERROR;}}
– user5537584
                Nov 18, 2015 at 20:38
                This kind of thing should certainly be done in the lexer, and it doesn't solve the problem. It's ridiculous to use shift-reduce parsing to implement atoi().
– user207421
                Nov 18, 2015 at 21:06
        

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.