title: How to resolve a yylloc undeclared error?
body: <p>I'm new to flex and bison so bear with me. I'm trying to use yylloc in yyerror to print out where the error occurs along with the filename. I know that this requires me to redefine YYLTPYE to include a char* filename that I can use to keep track of the filename.  According to the Flex and Bison book I have, it recommends that I use the YY_USER_ACTION macro to initialize the YYLTYPE in the .l file, so I included the following in it, </p>
  
  <pre><code>#define YY_USER_ACTION yylloc.filename = filename; yylloc.hel = 0;  \
          yylloc.first_line = yylloc.last_line = yylineno;            \
          yylloc.first_column = yycolumn; yylloc.last_column = yycolumn+yyleng-1; \
          yycolumn += yyleng;
  </code></pre>
  
  <p>but when I try to compile the project, I get the error that yylloc is undeclared.</p>
  
  <p>I've tried the solution offered by Chris Dodd in this <a href="https://stackoverflow.com/questions/10386567/yylloc-undefined-in-this-scope">question</a>, but it hasn't helped me to resolve the issue. Any and all help in resolving this error is much apprecaited.</p>
  
  <p>Here's the full code in .l:</p>
  
  <pre><code>%option noyywrap nodefault yylineno case-insensitive
  %{
      #include "need.h"
      #include "numbers.tab.h"
  
      int yycolumn = 1;
  
      #define YY_USER_ACTION yylloc.filename = filename; yylloc.hel = 0;  \
          yylloc.first_line = yylloc.last_line = yylineno;            \
          yylloc.first_column = yycolumn; yylloc.last_column = yycolumn+yyleng-1; \
          yycolumn += yyleng;
  
  %}
  
  Integers    [-]?(0|[1-9][0-9]*)
  Float       [.][0-9]+
  Exp         [eE][-]?(0|[1-9][0-9]*)
  Octal       [-]?(00|0[1-7][0-7]*)
  Hexa        [-]?(0[xX][0-9A-F]+)
  tomsNotNumbers [^ \t\n\v\f\r]+
  
  %%
  
  {Integers}{Float}?{Exp}?    {
                                  printf("%s is a number.\n", yytext);
                                  possibleNumbers++;  // increment by 1 as an input was given -M
                                  actualNumbers++;    // increment by 1 as an input did match our pattern -M
                              }
  
  {Octal} {
              printf("%s is a number.\n", yytext);
              possibleNumbers++;  // increment by 1 as an input was given -M
              actualNumbers++;    // increment by 1 as an input did match our pattern -M
          }
  
  {Hexa}  {
              printf("%s is a number.\n", yytext);
              possibleNumbers++;  // increment by 1 as an input was given -M
              actualNumbers++;    // increment by 1 as an input did match our pattern -M
          }
  
  {tomsNotNumbers}    {
                      printf("%s is not a number.\n", yytext);
                      yyerror(warning, "This isn't a number.");
                      possibleNumbers++;  // increment by 1 as an input was given -M
                      failedNumbers++;    // increment by 1 as the input has failed to match our patterns -M
                  }
  
  [\n]    /*Do nothing for newline*/
  
  .   /*Do nothing for anything else*/
  
  %%
  </code></pre>
  
  <p>.y is just empty for now, only has an include for need.h and one for .tab.h</p>
  
  <p>The need.h:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdarg.h&gt;
  #include &lt;string.h&gt;
  
  int possibleNumbers = 0;
  int actualNumbers = 0;
  int failedNumbers = 0;
  
  typedef struct YYLTYPE
  {
      int first_line;
      int first_column;
      int last_line;
      int last_column;
      char *filename; /* use to keep track of which file we're currently in */
      int hel;    /* no errors = 0, warning = 1, error = 2, fatal = 3 */
  } YYLTYPE;
  
  char *name; /*using for test purposes*/
  
  # define YYLTYPE_IS_DECLARED 1
  
  # define YYLLOC_DEFAULT(Current, Rhs, N)                                                    \
      do                                                                                      \
          if (N)                                                                              \
          {                                                                                   \
              (Current).first_line = YYRHSLOC (Rhs, 1).first_line;                            \
              (Current).first_column = YYRHSLOC (Rhs, 1).first_column;                        \
              (Current).last_line = YYRHSLOC (Rhs, N).last_line;                              \
              (Current).last_column = YYRHSLOC (Rhs, N).last_column;                          \
              (Current).filename = YYRHSLOC (Rhs, 1).filename;                                \
              (Current).hel   = YYRHSLOC (Rhs, 1).hel;                                        \
          }                                                                                   \
          else                                                                                \
          { /* empty RHS */                                                                   \
              (Current).first_line = (Current).last_line = YYRHSLOC (Rhs, 0).last_line;       \
              (Current).first_column = (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \
              (Current).filename  = NULL;                                                     \
              (Current).hel = 0;                                                              \
          }                                                                                   \
      while (0)
  
  typedef enum errorSeverity
  {
      warning = 1, error, fatal
  } errorLevel;
  
  void yyerror(errorLevel errlvl, char *s, ...)
  {
      va_list ap;
      va_start(ap, s);
      char *errLvls[3] = {"Warning", "Error", "Fatal"};  
  
      fprintf(stderr, "%s: %s: , %n", name, errLvls[errlvl - 1], yylloc.first_line);
      vfprintf(stderr, s, ap);
      fprintf(stderr, "\n");
  }
  
  main(int argc, char **argv)
  {
      printf("argv[0] = %s, argv[1] = %s.\n", argv[0], argv[1]);
      if(argc &gt; 1)
      {
          if((yyin = fopen(argv[1], "r")) == NULL)
          {
              perror(argv[1]);
              exit(1);
          }
          name = argv[1];
      } else
          name = "(stdin)";
  
      printf("Filename1: %s", name);
      yylex();
      printf("Filename2: %s", name);
      // print out the report. -M
      printf("Out of %d possible numbers, there were %d numbers, and %d not numbers.\n", possibleNumbers, actualNumbers, failedNumbers);
  }
  </code></pre>