Грамматики и YACC
Генератор анализаторов YACC
Генератор синтаксических анализаторов YACC (Yet Another Compilers' Compiler) - это программа, которая строит LALR- анализаторы. Он был разработан в начале 70-х годов прошлого века. Эта программа создана для большинства наиболее распространенных операционных систем, а именно, для UNIX, Windows, OS/2. На самом деле, YACC - это имя генератора в операционной системе UNIX, в остальных операционных системах программа называется PCYACC.
Входом программы является грамматика языка и некоторая дополнительная информация, выход - программа на языке C. Более точно, на вход YACC получает файл со спецификациями (этот файл должен иметь имя с расширением y, например, name.y). Выходом являются файлы name.yy.c (name.c для PCYACC'a) и, возможно, name.yy.h (name.h) и y.output (yy.lrt). Первый из этих файлов содержит сгенерированную YACC'ом программу анализатора. Второй файл, который создается при задании параметра -h , - описания, которые также генерирует YACC. Третий файл содержит протокол, т.е. представление управляющей таблицы анализатора.
Файл name.y должен быть устроен следующим образом:
Секция описаний %% Секция грамматических правил %% Секция процедур
Секция описаний
Секция описаний содержит:
- описания переменных языка C, которые используются при описании грамматики. Эти описания заключаются в скобки %{ … }% , они будут перенесены в текст результирующей программы без изменения.
Например,
%{ int myCount; }%
- определения типов, значения которых возвращаются как значения семантик. Эти типы определяются как элементы объединенного типа
%union { type1 id1; ... }
- объявления терминальных символов (лексических классов, tokens ) грамматики в форме %token lc1 lc2 ...
Например,
%token MINUS_LC PLUS_LC TIMES_LC %token PLUS_TO_LC TIMES_TO_LC
Лексические классы нумеруются либо пользователем, либо самим YACC'ом. В последнем случае лексические классы получают номера, начиная с 257.
- объявления нетерминальных символов грамматики в форме %type <id> name
Например,
%type <id1> conditional_stmt
- определения ассоциативности и приоритетов операций в форме
- %left op1 op2 ...
- %right op3 op4 ...
- %nonassoc op5 op6 ...
Эти определения должны размещаться в порядке увеличения проиритетов.
Например,
%nonassoc PLUS_TO_LC /* операция += */ %left MINUS_LC PLUS_LC /* бинарные операции плюс и минус */ %left TIMES_LC /* операция умножения */