title: Bison, Flex and compiling my compiler error with parser.y
body: <p>I'm getting an error on compiling my compiler and I have no idea why. I'm running OS X 10.9.1 and the latest Xcode. </p>
  
  <p>parser.y:1.1-5: invalid directive: `%code'
  parser.y:1.7-9: syntax error, unexpected identifier</p>
  
  <p>Here is the code of my parser.y</p>
  
  <pre><code>%code top {
  
  #include "frontend.h"
  #include "type.h"
  #include "ast.h"
  #include "env.h"
  #include &lt;glib.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  extern int yylex(void);
  extern int yyerror(const char*);
  
  }
  
  %code requires {
  
  #include "type.h"
  #include "ast.h"
  #include &lt;glib.h&gt;
  
  }
  
  %union {
        char* id;
        char* str;
        int num;
        GList* list;
        Type* type;
        struct exp* exp;
        struct decl* decl;
        struct stmt *stmt;
        struct GList *stmts_list;
  };
  
  %type &lt;exp&gt; exp
  %type &lt;exp&gt; aexp
  %type &lt;exp&gt; bexp
  %type &lt;exp&gt; obj_lit
  %type &lt;exp&gt; lvalue
  %type &lt;exp&gt; fun_call
  
  %type &lt;list&gt; decls
  %type &lt;list&gt; var_decls
  %type &lt;decl&gt; decl
  %type &lt;decl&gt; var_decl
  %type &lt;decl&gt; fun_decl
  %type &lt;decl&gt; type_decl
  %type &lt;type&gt; type
  
  
  /* Ids could be types or exps. */
  %token &lt;id&gt; T_ID
  %token &lt;str&gt; T_STR
  %token &lt;num&gt; T_NUM
  
  %token T_LT_EQ "&lt;="
  %token T_GT_EQ "&gt;="
  %token T_EQ "=="
  %token T_NOT_EQ "!="
  
  %token T_VAR T_TYPE T_FUNCTION
        T_FOR T_TO T_WHILE T_IF T_ELSE T_RETURN
        T_NIL T_TRUE T_FALSE
        T_INT T_BOOL
        T_UNKNOWN
  
  %left '|'
  %left '&amp;'
  %left "==" "!="
  %left '&lt;' '&gt;' "&lt;=" "&gt;="
  %left '+' '-'
  %left '*' '/' '%'
  %left T_UMINUS T_UPLUS '!'
  
  %start program
  
  %%
  
  // ian start
  
  program:
        decls {
              done_parsing($1);
        }
  
  decls:
        { GList* declsList = NULL; $$ = declsList; }
      | decls decl {
              $$ = g_list_append($1, $2);
        }
  
  decl: var_decl {
              $$ = $1;
        }
        | fun_decl {
              $$ = $1;
        }
        | type_decl {
              $$ = $1;
        }
  
  var_decls: 
        { GList* declsList = NULL; $$ = declsList; } | var_decls var_decl {
              $$ = g_list_append($1, $2);
        }
  
  var_decl: 
        T_VAR T_ID ':' type ';' {
              Symbol varName = symbol_var($2);
              $$ = decl_new(varName, $4, NULL, NULL, NULL);
        }
        | T_VAR T_ID ':' type '=' exp ';' {
              Symbol varName = symbol_var($2);
              $$ = decl_new(varName, $4, $6, NULL, NULL);
        }
  
  type_decl: 
        T_TYPE T_ID ':' type ';' {
              Symbol typeName = symbol_typename($2);
              $$ = decl_new(typeName, $4, NULL, NULL, NULL);
        }
  
  // ian end
  
  // adam start
  
  param_decl: 
        T_ID ':' type
  
  param_decls: 
        param_decl
        | param_decls ',' param_decl
  
  field_decl: 
        T_ID ':' type
  
  field_decls: 
        field_decl
        | field_decls ',' field_decl
  
  type: 
        T_INT
        | T_BOOL
        | T_ID
        | '[' type ']'
        | '{' field_decls '}'
  
  fun_decl: 
        T_FUNCTION T_ID '(' param_decls ')' ':' type '{' var_decls stmts '}'
        | T_FUNCTION T_ID '(' param_decls ')' '{' var_decls stmts '}'
        | T_FUNCTION T_ID '(' ')' ':' type '{' var_decls stmts '}'
        | T_FUNCTION T_ID '(' ')' '{' var_decls stmts '}'
  
  // adam end
  
  // vv IAN
  exp:
        aexp {
              $$ = $1;
        }
        | bexp {
              $$ = $1;
        }
        | obj_lit {
              $$ = $1;
        }
        | fun_call {
              $$ = $1;
        }
        | lvalue {
              $$ = $1;
        }
        | '(' exp ')' {
              $$ = $2;
        }
  
  aexp: 
        T_NUM {
              exp_num_new($1);
        }
        | '+' exp %prec T_UPLUS {
              $$ = exp_binop_new(AST_EXP_MUL, exp_num_new(1), $2);
        }
        | '-' exp %prec T_UMINUS {
              $$ = exp_binop_new(AST_EXP_MUL, exp_num_new(-1), $2);
        }
        | exp '+' exp {
              $$ = exp_binop_new(AST_EXP_PLUS, $1, $3);
        }
        | exp '-' exp {
              $$ = exp_binop_new(AST_EXP_MINUS, $1, $3);
        }
        | exp '/' exp {
              $$ = exp_binop_new(AST_EXP_DIV, $1, $3);
        }
        | exp '%' exp {
              $$ = exp_binop_new(AST_EXP_MOD, $1, $3);
        }
        | exp '*' exp {
              $$ = exp_binop_new(AST_EXP_MUL, $1, $3);
        }
  
  bexp: 
        T_TRUE {
              $$ = exp_new(AST_EXP_TRUE);
        }
        | T_FALSE {
              $$ = exp_new(AST_EXP_FALSE);
        }
        | '!' exp {
              $$ = exp_not_new($2);
        }
        | exp '|' exp {
              $$ = exp_binop_new(AST_EXP_OR, $1, $3);
        }
        | exp '&amp;' exp {
              $$ = exp_binop_new(AST_EXP_AND, $1, $3);
        }
        | exp '&lt;' exp {
              $$ = exp_binop_new(AST_EXP_LT, $1, $3);
        }
        | exp "&lt;=" exp {
              $$ = exp_binop_new(AST_EXP_LT_EQ, $1, $3);
        }
        | exp '&gt;' exp {
              $$ = exp_binop_new(AST_EXP_GT, $1, $3);
        }
        | exp "&gt;=" exp {
              $$ = exp_binop_new(AST_EXP_GT_EQ, $1, $3);
        }
        | exp "==" exp {
              $$ = exp_binop_new(AST_EXP_EQ, $1, $3);
        }
        | exp "!=" exp {
              $$ = exp_binop_new(AST_EXP_NOT_EQ, $1, $3);
        }
  
  // jon start
  
  obj_lit: array_lit | struct_lit
        | T_NIL
  
  array_lit:
        '[' exps ']'
        | T_STR
  
  exps: 
        exp
        | exps ',' exp
  
  struct_lit:
        '{' field_inits '}'
  
  field_init: 
        T_ID '=' exp
  
  field_inits: 
        field_init
        | field_inits ',' field_init
  
  fun_call:
        T_ID '(' exps ')'
        | T_ID '(' ')'
  
  lvalue: 
        T_ID
        | struct_exp '.' T_ID
        | array_exp '[' exp ']'
  
  array_exp: array_lit | fun_call | lvalue
  struct_exp: struct_lit | fun_call | lvalue
  
  // jon end
  
  // patrick start
  
  stmts:               { GList *stmts_list = NULL; stmts_list = $$; }
          | stmts stmt { $$ = g_list_append($1, $2); }
  
  stmt:
      exp ';' { $$ = stmt_exp_new($2); }
      | lvalue '=' exp ';' { $$ = stmt_assign_new($1 , $3); }
      | T_IF '(' exp ')' block T_ELSE block { $$ = stmt_if_new($3, $5, $7); }
      | T_IF '(' exp ')' block { $$ = stmt_if_new($3, $5, NULL); }
      | T_WHILE '(' exp ')' block { $$ = stmt_while_new($3, $5); }
      | T_FOR '(' lvalue '=' exp T_TO exp ')' block { $$ = stmt_for_new($3, $5, $7, $9); }
      | T_RETURN '(' exp ')' ';' { $$ = stmt_return_new($3); }
      | T_RETURN ';' { $$ = stmt_return_new(NULL); }
  
  block:
      '{' stmts '}' { $$ = $2; }
  
  //patrick end
  
  %%
  
  int yyerror(const char *p) {
        fprintf(stderr, "Error: %s\n", p);
        return 0;
  }
  </code></pre>