Используя Flex и Bison вместе

Прежде всего, я должен прояснить, что я новичок в программировании гибких и зубровых программ.

Я пытаюсь написать код, распознающий определенную часть объявления. Его синтаксис и логику можно понять с помощью кода flex и bison, который я представляю ниже:

%{
#include <stdio.h>
%}
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}

Проблема заключается в компиляции. При компиляции на терминале я получаю следующие строки ошибок:

Что не так с моим кодом? Как я могу исправить ошибки?

Я с нетерпением жду ваших ответов!

1 ответ

Решение

Вы неправильно прочитали инструкцию по использованию этих инструментов!

Требуются два разных файла, а не один.

Файл, такой как exerc4.l, является входным flex который определяет отображение от лексем к токенам, и упражнение4.y будет входным bison который определяет порядок жетонов в грамматике. Чтобы использовать два инструмента вместе, мы должны объединить вывод flex (в этом случае lex.yy.c с грамматикой зубров, используя #include "lex.yy.x" директива; токены объявлены с %token декларация).

Исходя из вашего примера, мы можем перефразировать это в два файла:

упражнение 4.1:

%%
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%

Упражнение 4.y:

%{
#include <stdio.h>    
%}
%token VAR VAR_NAME REAL BOOLEAN INTEGER CHAR
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
/* yylex(); */
yyparse();
}
yyerror(char *s)  
{  
 printf("\nError\n");  
}
#include "lex.yy.c"

Теперь мы можем объединить их со следующими операциями командной строки:

C:\Users\Brian>flex exercise4.l    
C:\Users\Brian>bison exercise4.y    
C:\Users\Brian>gcc -o exercise4.exe exercise4.tab.c -lfl

и протестировать результирующий парсер:

C:\Users\Brian>.\exercise4
var a:integer;
^Z
Другие вопросы по тегам