Why cannot use brackets character in yacc/bison file?
<h2>source</h2>

<p>ini.l</p>

<pre><code>%option yylineno

%{
#include &lt;stdio.h&gt;
#include "ini.tab.h"

int yywrap(void) {
    return 1;
}

void yyerror(const char* s) {
    printf("%d: %s at %s\n", yylineno, s, yytext);
}

#if defined YYDEBUG
extern int yydebug;
#endif

#define CASE_RETURN(token) do { case token: return #token; } while(0)

char *get_tokenname(token) {
    switch(token) {
        CASE_RETURN( IDENTIFIER     );
        CASE_RETURN( BRACKETS_LEFT  );
        CASE_RETURN( BRACKETS_RIGHT );
        CASE_RETURN( EQ             );
        default: return "Unknown";
    }
}

int main(void) {
    int token;
#if defined YYDEBUG
    yydebug = 1;
    while ((token = yylex()) != 0)
        printf("Token: %d/%-20s (%s)\n", token, get_tokenname(token), yytext);
#else
    yyparse();
#endif
    return 0;
}
%}

%%

[_a-zA-Z0-9]+           { yylval.str = strdup(yytext); return IDENTIFIER; }
"["                     { return BRACKETS_LEFT; }
"]"                     { return BRACKETS_RIGHT; }
"="                     { return EQ; }
[ \t\r\n]               { }

%%
</code></pre>

<p>ini.y</p>

<pre><code>%{
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
%}

%union {
    char* str;    
}

%token &lt;str&gt; IDENTIFIER
%token BRACKETS_LEFT BRACKETS_RIGHT EQ

%%

input
    : /* empty */
    | input line
    | line
    ;

line
    : BRACKETS_LEFT section BRACKETS_RIGHT
    | key EQ value
    ;

section : IDENTIFIER { printf("section: %s\n" , $1); } ;
key     : IDENTIFIER { printf("key: %s, "     , $1); } ;
value   : IDENTIFIER { printf("value: %s\n"   , $1); } ;

%%
</code></pre>

<p>Makefile</p>

<pre><code>CC              = gcc
LEX             = flex
YACC            = bison

TARGET          = a.out

LEX_SRC         = $(wildcard *.l)
YACC_SRC        = $(wildcard *.y)
SRC             = $(patsubst %.y,%.tab.c,$(YACC_SRC)) $(patsubst %.l,%.yy.c,$(LEX_SRC))
INC             = $(patsubst %.y,%.tab.h,$(YACC_SRC)) $(patsubst %.l,%.yy.h,$(LEX_SRC))

DEBUG           = -DYYDEBUG -DYYERROR_VERBOSE
LDFLAGS         = -L/usr/local/opt/bison/lib \
                -L/usr/local/opt/flex/lib \
                -I/usr/local/opt/flex/include

all: $(SRC)
    $(CC) $(FLAGS) $(SRC) -o $(TARGET)

debug: $(SRC)
    $(CC) $(FLAGS) $(SRC) -o $(TARGET) $(DEBUG)

.PRECIOUS: %.yy.c

%.yy.c: %.l
    $(LEX) -t $&lt; &gt; $@

.PRECIOUS: %.tab.c

%.tab.c:%.y
    $(YACC) -o $@ -d $&lt;

clean:
    rm -rf $(TARGET) $(SRC) $(INC) *.output 
</code></pre>

<p>sample.ini</p>

<pre><code>[foobar]
foo=bar
</code></pre>

<h2>test</h2>

<pre><code>$ make clean &amp;&amp; make
$ ./a.out &lt; sample.ini
section: foobar
key: foo, value: bar
</code></pre>

<p>Everything looks fine</p>

<pre><code>$ make clean &amp;&amp; make debug
$ ./a.out &lt; sample.ini
Token: 259/BRACKETS_LEFT        ([)
Token: 258/IDENTIFIER           (foobar)
Token: 260/BRACKETS_RIGHT       (])
Token: 258/IDENTIFIER           (foo)
Token: 261/EQ                   (=)
Token: 258/IDENTIFIER           (bar)
</code></pre>

<p>Then i changed <code>BRACKETS_LEFT</code> to <code>'['</code></p>

<pre><code>$ git diff -U0
diff --git a/ini.l b/ini.l
index 2538353..12b2524 100644
--- a/ini.l
+++ b/ini.l
@@ -24 +23,0 @@ char *get_tokenname(token) {
-        CASE_RETURN( BRACKETS_LEFT  );
@@ -47 +45,0 @@ int main(void) {
-"["                     { return BRACKETS_LEFT; }
diff --git a/ini.y b/ini.y
index c605ea4..1498ff5 100644
--- a/ini.y
+++ b/ini.y
@@ -11 +11 @@
-%token BRACKETS_LEFT BRACKETS_RIGHT EQ
+%token BRACKETS_RIGHT EQ
@@ -22 +22 @@ line
-    : BRACKETS_LEFT section BRACKETS_RIGHT
+    : '[' section BRACKETS_RIGHT
</code></pre>

<p>The bison give me an error</p>

<pre><code>$ make clean &amp;&amp; make debug
$ ./a.out &lt; sample.ini
1: syntax error at [

$ make clean &amp;&amp; make debug
$ ./a.out &lt; sample.ini
[Token: 258/IDENTIFIER           (foobar)
Token: 259/BRACKETS_RIGHT       (])
Token: 258/IDENTIFIER           (foo)
Token: 260/EQ                   (=)
Token: 258/IDENTIFIER           (bar)
</code></pre>

<p>:(</p>