Операционная система UNIX. Руководство программиста

ВХОДНОЙ СИНТАКСИС YACC'А


В данном разделе в форме yacc-спецификации описывается входной синтаксис yacc'а. Не рассматриваются контекстные зависимости и аналогичные вопросы. Ирония заключается в том, что, хотя yacc

воспринимает LALR(1)-грамматики, сам входной язык спецификаций yacc'а наиболее естественным образом задается LR(2)-грамматикой: трудным оказывается случай, когда идентификатор идет сразу за действием. Если после идентификатора стоит двоеточие, то это начало следующего правила, в противном случае, это продолжение текущего правила, которое идет за внутренним действием. Реализация такова: лексический анализатор, обнаружив идентификатор, просматривает входной текст вперед и определяет, является ли следующая лексема двоеточием. Если является, лексический анали- затор возвращает C_IDENTIFIER. Если нет, возвращается IDENTIFIER. Литералы (в апострофах) также распознаются как IDENTIFIER, но не как C_IDENTIFIER.

/* грамматика yacc-спецификаций */

/* основные компоненты */ %token IDENTIFIER /* идентификаторы и литералы */ %token C_IDENTIFIER /* идентификатор (но не литерал), */ /* за которым следует двоеточие */ %token NUMBER /* [0-9]+ */

/* зарезервированные слова: %type=>TYPE %left=>LEFT и т.д.*/

%token LEFT RIGHT NONASSOC TOKEN PREC TYPE START UNION

%token MARK /* знак %% */ %token LCURL /* знак %{ */ %token RCURL /* знак %} */

/* ASCII-символы указываются непосредственно */

%%

spec : defs MARK rules tail ;

tail : MARK { В этом действии обрабатывается оставшаяся часть файла } | /* пусто: второй MARK необязателен */ ;

defs : /* пусто */ | defs def ; def : START IDENTIFIER | UNION { Копирование определения объединения в выходной файл } | LCURL { Копирование C-кода в выходной файл } RCURL | rword tag nlist ;

rword : TOKEN | LEFT | RIGHT | NONASSOC | TYPE ;

tag : /* пусто: тег необязателен */ | '<' IDENTIFIER '>' ;

nlist : nmno | nlist nmno | nlist ',' nmno ;

nmno : IDENTIFIER /* Замечание: литерал нельзя использовать с %type */ | IDENTIFIER NUMBER /* Замечание: нельзя использовать с %type */ ;

/* секция правил */

rules : C_IDENTIFIER rbody prec | rules rule ; rule : C_IDENTIFIER rbody prec | '|' rbody prec ;

rbody : /* пусто */ | rbody IDENTIFIER | rbody act ;

act : '{' { Копирование действия, обработка $$ и т.п. } '}' ;

prec : /* пусто */ | PREC IDENTIFIER | PREC IDENTIFIER act | prec ';' ;



Содержание раздела