Как работает yacc, можете ли вы объяснить это раздел за разделом? - PullRequest
1 голос
/ 16 декабря 2010

Как работает эта крошечная программа yacc?

Что я знаю до сих пор:

%{...%} - это определение %% ... %% - это правило, но как его интерпретировать?и после %% указывается определение функции.Что такое раздел %token INTEGER между %} и %%?

%{
#include <stdlib.h>
int yylex(void);
void yyerror(char *);
%}
%token INTEGER
%left '+' '-'
%left '*' '/'
%%
program:
program expr '\n' { printf("%d\n", $2); }
|
;
expr:
INTEGER { $$ = $1; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
;
%%
void yyerror(char *s) {
printf("%s\n", s);
}
int main(void) {
yyparse();
return 0;
}

ОБНОВЛЕНИЕ

Чего я не понимаю:

program:
program expr '\n' { printf("%d\n", $2); }
|
;

Ответы [ 2 ]

1 голос
/ 17 декабря 2010

expr: означает, что expr - это одна из следующих опций, которые разделены | ниже. Если его можно рассматривать как токен INTEGER, то он берет первый. Если это может быть замечено как expr, сопровождаемый символом *, сопровождаемым expr, тогда это берет второй вариант и так далее. $$ - это возвращаемое значение по умолчанию, $1 - первый токен, $2 - второй токен.

Таким образом, если бы он анализировал 5 + 6, он видит его как expr '+' expr, поэтому он принимает 4-е определение. Он возвращает 11 как expr, поэтому он соответствует 11 как токен INTEGER и назначает 11 в качестве возвращаемого значения.

Если бы мы анализировали программный токен, за которым следовал 5 + 6, он бы сделал то же самое, чтобы получить программу 11, затем взять правило expr программы и вызвать код c, который выводился бы на экран.

Слева означает, что оператор является ассоциативным слева. Как в a + b + c = (a + b) + c. Операторы в одной строке имеют одинаковый приоритет, а операторы под ним имеют более низкий приоритет.

По общему признанию, я некоторое время не использовал yacc, поэтому не стесняйтесь сказать мне, что я совершенно не прав.

ОБНОВЛЕНИЕ:

yacc генерирует код на c, так что вы можете поместить свой собственный код прямо в него. Таким образом, во время синтаксического анализа, если он видит «выражение программы», он может напрямую ввести код в {} в сгенерированный код.

0 голосов
/ 08 ноября 2011

Всего существует пять фаз компилятора, а именно:

  1. лексический анализ
  2. синтаксический анализ
  3. семантический анализ (необязательный вариант генерации кода)
  4. Оптимизация кода
  5. Генерация кода

lex и YACC (еще один компилятор компилятора) являются утилитами Unix для генерации program.lexer, отвечающего за сопоставление слов в данномПрограмма и, когда совпадение найдено, сохраняет значения в yylex и возвращает их в виде лексеров.По сути, yacc - это синтаксический анализатор, который берет токены и строит из него дерево для проверки синтаксиса программы. Токены создаются лексером и объявляются в файле спецификации yacc.поэтому файл y.tab.h включен в программу lex.

Приведенная выше программа содержит токен INTEGER, который возвращается lexer.Программа yacc должна содержать начальное состояние ... "программа" - это начальное состояние, в котором каждая программа должна содержать по крайней мере одно начальное состояние ... Правила yacc находятся в правиле формата {action}. В приведенной выше программе "program expr '\ n«» означает, что программа может содержать выражение, а затем символ новой строки.то есть 5 + 4 «ключ ввода» представляет выражение, для которого мы написали expr «+» expr, здесь expr может быть целым числом в этом случае 5 и 4, поэтому мы включаем это правило также, записывая expr: INTEGER .... forдополнение или любая другая роль LHS выражения представлена ​​$$, а RHS - $ 1, $ 2, $ 3 ... и т. д. Затем expr: expr '+' expr {$$ = $ 1 + $ 3;} ......

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...