title: How do I set yylval when using Flex and Bison in C++
body: <p>I am using Flex and Bison in C++. In the C version of both, yylval is a global union variable that stores information about the token.</p>
  <p>In Bison C++, yylval is called semantic_type and it is a class member variable. How can I set the semantic information for the tokens from Flex C++? In Flex C++, the lexer is also a class and it does not have the semantic_type as a member variable.</p>
  <p>I want to do something like this:</p>
  <pre><code>   &quot;)&quot;                          { return create_token(TOK_RPAREN, yytext, start_line, start_column);     }
  &quot;{&quot;                          { return create_token(TOK_LBRACE, yytext, start_line, start_column);     }
  &quot;}&quot;                          { return create_token(TOK_RBRACE, yytext, start_line, start_column);     }
  [A-Za-z][A-Za-z0-9]*         { return create_token(TOK_IDENTIFIER, yytext, start_line, start_column); }
  [0-9]+                       { return create_token(TOK_NUM, yytext, start_line, start_column);        }
  [ \t\n]+
  &quot;,&quot;                          { return create_token(TOK_COMMA, yytext, start_line, start_column);       }
  &quot;;&quot;                          { return create_token(TOK_SEMICOLON, yytext, start_line, start_column);   }
  .                            { yyerror(&quot;Unknown character: %c\n&quot;, yytext[0]); }
  
  %%
  
  void lexer_set_source_file(const char *filename) {
    g_srcfile = xstrdup(filename);
  }
  
  int CppLexer::create_token(yy::parseint tag, const char *lexeme, int line, int col) {
      struct SourceInfo info;
      info.filename = g_srcfile;
      info.line = line;
      info.col = col;
    
      if (tag == TOK_NUM) {
          nodeval.num_node = createNumberNode(lexeme, info);
      } else if (IsOperation(tag)) {
          nodeval.op_node = createOperationNode(tag, lexeme, info);
      } else if (tag == TOK_IDENTIFIER) {
          yylval.id_node = createIdentifierNode(lexeme, info);
      } else {
          nodeval.node = createCppNode(tag, lexeme, info);
      }
      
      return tag;
  }&quot;)&quot;                          { return create_token(TOK_RPAREN, yytext, start_line, start_column);     }
  &quot;{&quot;                          { return create_token(TOK_LBRACE, yytext, start_line, start_column);     }
  &quot;}&quot;                          { return create_token(TOK_RBRACE, yytext, start_line, start_column);     }
  [A-Za-z][A-Za-z0-9]*         { return create_token(TOK_IDENTIFIER, yytext, start_line, start_column); }
  [0-9]+                       { return create_token(TOK_NUM, yytext, start_line, start_column);        }
  [ \t\n]+
  &quot;,&quot;                          { return create_token(TOK_COMMA, yytext, start_line, start_column);       }
  &quot;;&quot;                          { return create_token(TOK_SEMICOLON, yytext, start_line, start_column);   }
  .                            { yyerror(&quot;Unknown character: %c\n&quot;, yytext[0]); }
  
  %%
  
  void lexer_set_source_file(const char *filename) {
    g_srcfile = xstrdup(filename);
  }
  
  int CppLexer::create_token(yy::parseint tag, const char *lexeme, int line, int col) {
      struct SourceInfo info;
      info.filename = g_srcfile;
      info.line = line;
      info.col = col;
    
      if (tag == TOK_NUM) {
          nodeval.num_node = createNumberNode(lexeme, info);
      } else if (IsOperation(tag)) {
          nodeval.op_node = createOperationNode(tag, lexeme, info);
      } else if (tag == TOK_IDENTIFIER) {
          yylval.id_node = createIdentifierNode(lexeme, info);
      } else {
          nodeval.node = createCppNode(tag, lexeme, info);
      }
      
      return tag;
  }
  </code></pre>