С каждым правилом может быть связано действие, выполняемое при распознавании во входном потоке объекта, удовлетворяющего правилу. Эти действия могут возвращать значения и воспринимать значения, возвращаемые другими действиями. Более того, при желании лексический анализатор может возвращать значения для выделяемых лексем.
Действие - это произвольный оператор языка С. В нем можно выполнять ввод-вывод, вызывать подпрограммы и изменять внешние переменные или массивы. Действие указывается как один или несколько операторов в фигурных скобках. Например, следующие фрагменты представляют собой грамматические правила с действиями:

A:'('B')'       { hello(1, "abc"); }
XXX:YYYZZZ      { printf("a message\n"); flag=25;}

Для упрощения связи между действиями и анализатором операторы действий слегка изменяются. В качестве механизма сигнализации в этом контексте используется знак доллара. Для возврата значения действие обычно присваивает псевдопеременной $$ какое-либо значение. Например, действие, которое ничего не выполняет кроме возврата 1:

{$$=1;}

Для получения значений, возвращаемых предыдущими действиями и лексическим анализатором, действие может пользоваться псевдопеременными $1, $2, ..., которые соответствуют значениям, возвращаемым правой частью правила, слева направо. Тогда, если правило выглядит как

A:B C D               ;

то $2 - значение, возвращаемое C, $3 - значение, возвращаемое D.
В качестве более конкретного примера рассмотрим правило:

expr:'('expr')'       ;

Значение, возвращаемое этим правилом - выражение expr в скобках. Это можно указать как

expr :'('expr')'      {$$=$2;}

По умолчанию, значением правила служит значение его первого элемента ($1). Таким образом, грамматическое правило вида

A:B

может не содержать явных действий.
В приведенных примерах все действия указаны в конце соответствующих правил. Иногда требуется получить управление до завершения полного распознавания правила. Генератор позволяет записывать действия как в середине правила, так и в конце. Подразумевается, что правило возвращает значения посредством механизма $ через действия справа от знака. Но в свою очередь оно может получать значения, возвращаемые символами слева от этого знака. Таким образом, в правиле

A:B        { $$=1; }
C          { x=$2; y=$3; }
           ;

x получит значение 1, y - значение, возвращаемое C.
Действия, не завершающие правило, на самом деле обрабатываются созданием нового имени нетерминального символа и нового правила, связывающего это имя с пустой строкой. Внутреннее действие выполняется при распознавании этого правила. На самом деле предыдущий пример рассматривается следующим образом:

$ACT:     /*empty*/
          { $$=1;}
          ;
A:B $ACT C
          { x=$2 y=$3;}
          ;

В большинстве применений действия не выполняют непосредственного вывода. Обычно в памяти строится некоторая структура данных (например, дерево разбора), над которой и осуществляются преобразования. Особенно легко создавать деревья разбора при наличии функций построения и манипуляции древовидными структурами. Например, предположим, что существует функция node, следующий вызов которой

node(L, n1, n2)

создает узел с меткой L и потомками n1 и n2 и возвращает.P Для действий пользователь может определять дополнительные переменные. Объявления и определения помещаются в разделе объявлений между ограничителями %{ и %}. Эти объявления считаются глобальными, поэтому они известны всем действиям и лексическому анализатору. Например, строка

%{ int variable=0; %}

помещенная в раздел объявлений, делает переменную variable доступной для всех действий. Анализатор yacc использует только имена, начинающиеся с yy; пользователь должен избегать применения подобных имен. В приведенных примерах все значения имеют тип целый. Рассмотрение значений других типов проводится ниже.