flex-bison-in-action/tutorial/test.y

68 lines
2.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
extern int yylex();
extern FILE *yyin;
%}
// %union задаёт все возможные типы значений, которые могут быть у токенов и нетерминалов.
%union {
char *str;
}
// Этот блок в Bison (%token) определяет терминальные символы (токены),
// которые лексический анализатор (Flex) передаёт парсеру (Bison)
%token <str> TEXT // <str> — указывает, что этот токен имеет ассоциированное значение типа str (как объявлено в %union).
%token LBRACE RBRACE // LBRACE и RBRACE — это токены без ассоциированного значения. Они просто возвращают символы {,}
%%
/* правило задающее блок - структуру вида {...}, разбирается как
открывающая скобка { (LBRACE)
затем content (содержимое внутри скобок),
затем закрывающая скобка } (RBRACE).*/
block:
LBRACE content RBRACE
;
/* правило, задающее content
если контент пустой, то ничего не происходит
если контент это контент и TEXT, то освобождается память выделенная под предыдущий результат
еще контент может быть блоком
*/
content:
/* пусто */
| content TEXT { printf("TOKEN ('%s')\n", $2); free($2); }
| content block
;
%%
// 3. Как работает разбор на примере { A { B } C }
// Лексер (Flex) разбивает вход на токены:
// LBRACE ({), TEXT (A), LBRACE ({), TEXT (B), RBRACE (}), TEXT (C), RBRACE (})
// Парсер (Bison) применяет правила:
// Видит { → начинает block.
// Внутри block ожидается content.
// content может быть TEXT (A).
// Затем content может включать block ({ B }).
// Затем ещё TEXT (C).
// Закрывается } → конец block.
int main(int argc, char **argv) {
if (argc > 1) {
FILE *f = fopen(argv[1], "r");
if (!f) {
perror("Fail open file");
return 1;
}
yyin = f;
}
yyparse();
return 0;
}