В этом разделе приведено описание синтаксиса yacc. Зависимость от контекста не рассматривается. Грамматика yacc лучше всего может быть описана как LR(2), основные трудности начинаются при обнаружении идентификатора в правиле, идущем непосредственно после действия. Если после идентификатора стоит двоеточие, это начало следующего правила, иначе это продолжение текущего правила, которое содержит встроенное действие. Реализован алгоритм, при котором лексический анализатор делает опережающий просмотр в поисках идентификатора и определяет, является ли следующая лексема двоеточием. Если да, то возвращается значение C_IDENTIFIER. Иначе возвращается IDENTIFIER. Литералы всегда возвращаются как IDENTIFIER и никогда как часть C_IDENTIFIER.

/*  grammar  for  the  input  to  Yacc  */
/*  basic  entities  */
%token IDENTIFIER     /*includes  identifiers   and  literals  */
%token C_IDENTIFIER   /*identifier  (but  not  literal) followed  by  colon    */
%token NUMBER         /*  [0-9]+  */
              /*reserved  words: %type => TYPE, %left => LEFT,etc.*/
%token LEFT  RIGHT  NONASSOC  TOKEN  PREC  TYPE  START  UNION
%token MARK          /*  the  %%  mark  */
%token LCURL         /*  the  %{  mark  */
%token RCURL         /*  the  %}  mark  */
             /*  ascii  character  literals  stand  for  themselves  */ 
% start    spec
%%
spec :   defs  MARK  rules  tail
         ;
tail :   MARK  {In this action, eat up the rest of the file}
         |    /*  empty:  the  second  MARK  is  optional  */
         ;
defs :   /*  empty  */
         |     defs  def
         ;
def  :   START  IDENTIFIER
         |     UNION  {  Copy union  definition  to  output  }
         |     LCURL  {  Copy  C  code  to  output  file   }  RCURL
         |     ndefs  rword  tag  nlist
         ;
rword :  TOKEN
         |     LEFT
         |     RIGHT
         |     NONASSOC
         |     TYPE
         ;
         tag   :      /*  empty:  union  tag  is  optional  */
                  |   '<'  IDENTIFIER  '>'
                  ;
         nlist :  nmno
                  |    nlist  nmno
                  |    nlist  ','  nmno
                  ;
         nmno  :  IDENTIFIER                 /*  NOTE:  literal  illegal  with  %type  */
                  |    IDENTIFIER  NUMBER    /*  NOTE:  illegal  with  %type  */
                  ;
                  /*  rules  section  */
         rules :  C_IDENTIFIER  rbody  prec
                  |    rules  rule
                  ;
         rule  :  C_IDENTIFIER  rbody  prec
                  |    '|'  rbody  prec
                  ;
         rbody :  /*  empty  */
                  |    rbody  IDENTIFIER
                  |    rbody  act
                  ;
         act   :  '{'  {  Copy  action,  translate  $$,  etc.  }  '}'
                  ;
         prec  :  /*  empty  */
                  |    PREC  IDENTIFIER
                  |    PREC  IDENTIFIER  act
                  |    prec  ';'
                  ;