相关文章推荐
老实的松鼠  ·  tkinter Label文字居中 - ...·  1 周前    · 
星星上的苦瓜  ·  Android ...·  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 begginer to Yacc programming and I have an easy task to write a program, which checks whether an input text file contains a sequence of correctly paired parentheses. Any incorrect sequence should be signaled as "Syntax error!". I use bison and flex.

Example correct data: (()()((())())()) is incorrect.

My problem is that I think it should work, but it seems like yyerror is not working. Maybe I'm doing something wrong, please correct me. Here's my code Yacc code:

int yylex(); void yyerror(char* x); S: S A A: '('S')' |'(' ')'

And the lex code:

#include "y.tab.h" [\(\)] return(yytext[0]); . {printf("%c - error!\n",yytext[0]);} void yyerror(char* x) printf("syntax error"); exit(1);

So the problem is that it doesn't fire a syntax error, it doesn't matter how much parentheses I write. edit: Here's how I compile it: screen

It is not the problem, because the exit(1) also doesn't work. It doesn't enter the yyerror method Filip Matuszczak Dec 28, 2017 at 22:20

You need to provide a main() function which (at the minimum) calls yyparse() . Otherwise, the main from libfl will be used. That main does not call yyparse() ; rather, it repeatedly calls yylex until an EOF is signalled. ( libfl is part of Flex, not bison, so it cannot rely on yyparse even existing.)

There is really no need to link with -lfl . The main() definition there is not useful to you and the only other thing in the library is a dummy definition of yywrap() . You don't define yywrap() , so the library function will be called; however, rather than depending on the library, you could simply add

%option noyywrap

to your flex code (just before the %%), and then the generated scanner will not call yywrap().

There is also no need to use the -y flag when you invoke bison. The only reason to use -y is to be able to process legacy yacc files with bison. I suppose you are using the flag so that that generated parser is called y.tab.c; without the flag, it would be called z5.tab.c (and the header file will be z5.tab.h); you could just use those names. (Or you could tell bison the precise filename you would like it to use, by using the -o flag.)

Finally, two notes about your lex file:

  • The pattern for parentheses could just be written:

    [()]  { return yytext[0]; }
    

    There is no need to backslash-escape parentheses inside a character class, because no characters other than ], - and \ have special meaning inside a character class.

  • The pattern . does not match a newline character, which is why the newline characters in your input are not producing error messages. In fact, none of your patterns match the newline character, so when you type a newline, the default rule is invoked. The default rule is equivalent to ECHO, which bison defines to be something like:

    fputs(yytext, yyout);
    

    (or fprintf(yyout, "%s", yytext);)

    That's why an extra newline is output when you type a newline.

  • I followed your advice and now I get the: undefined reference '@winmain16' after I use the gcc command. – Filip Matuszczak Dec 29, 2017 at 10:31 Ok so it wasn't working with %option noyywrap but when I added the int main() and yywrap it started working. I will post the working code and proper way of compiling. – Filip Matuszczak Dec 29, 2017 at 10:35 You need to provide main. %option noyywrap only means that you don't need to provide yywrap. Was that not clear in my answer? – rici Dec 30, 2017 at 5:38 Yywrap should return 1, not 0. 0 means that you have more input even though EOF was reported, because yyin has been changed to a different input stream. But you have not done that. Better to use %option noyywrap to avoid the need for yywrap. – rici Dec 30, 2017 at 5:43

    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.