1
votes

How can I print the line number on which an error occurred. I tried using yylineno in the yyerror() function and writing %option yylineno in the .l file but after compiling it gives me an error "yylineno undeclared (first use in this function)" and if I initialize yylineno as 1 it gives me this error:

error: redefinition of yylineno
lex.yy.c:273: note: previous definition of yylineno was here
2
It would be helpful if you provided a bit more detail. yyerror is invoked by the bison skeleton; yylineno is provided by flex (and it's usually a macro). You probably have not arranged for the yylineno definition to be visible in the compilation unit of which yyerror is a part (particularly easy if you're using C++, but easy enough with the normal C arrangement as well.) What other flex options are you using? (For example, have you asked for re-entrancy?)rici

2 Answers

2
votes

There is a second way to ask flex to provide the global variable yylineno: the command line switch -l. If that doesn't work for you, you can manage your own global, as Levine et al. suggests. Increment it in any rule that matches a newline.

%{
    int mylineno = 1;
%}
%%
* * * 
\n  { mylineno++; }
1
votes

There are a number of ways you could be running into issues, but which one is relevant is hard to guess.

  1. You have the variable defined in the Flex source (.l file and the object file created from the source), but you don't declare it in the Bison grammar (.y file) or a header, so it is undeclared when you compile the grammar.

  2. You do have it declared in the grammar, but you still run into issues. The order of the fragments in the .c file generated from the grammar or lexical analyzer may not be what you expect, so you end up referencing the variable before it is declared. The code referencing it might appear in a %{ ... %} block, it might appear after the second %% section marker, it might appear in one of the grammar (or lexical analyzer) action blocks, or it might appear at some other location in the source. If each of these that references the yylineno variable has a pure declaration in the block (preferably via a header), then the code should be OK. You try to eliminate duplication, but at the risk of repeating yourself (which shouldn't be a big problem if your headers are idempotent), you can ensure it is declared in all the appropriate sections.

Note that a grammar does not include information from the lexical analyzer by default; you have to ensure that shared information is appropriately declared and defined.