Используя 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