LINUX.ORG.RU

[flex][bison] пример реинтерантного парсера

 ,


0

0

Ищу пример очень приметивного реинтерантного парсера на связке flex/bison. Что-нибудь очень простое, вроде того чтобы flex выхватывал из потока нужный токен, а бизон его бы печатал. Все найденные мной примеры в интернете либо достаточно сложны (и я не осиливаю отделить логику программы от парсера), либо сегфолтятся также как мой собственный парсер. Уже вторую неделю пытаюсь понять как оно работает и что-то слабо получается. Помогите кто чем сможет.

★★★★★

На сколько я помню реентеральные парсеры получаются при генерации flex'ом и bison'ом C++ классов

Torvus
()

В книжке «Flex&Bison» (John Levine, O'Reilly, 2009) есть не совсем примитивный, но простой и реально работающий пример.

Rarruga
()

в документации всё есть в scanner.l:

#define YY_DECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner, user_data * user_data )
%option reentrant

...

в parser.y


#define YY_DECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner, user_data * ptr )
#define YYLEX_PARAM yyscanner, ptr

YY_DECL;

%parse-param { yyscan_t yyscanner }
%parse-param { user_data * ptr }
%define api.pure
...


void parse(FILE * f)
{
	yyscan_t scanner;
	yylex_init( &scanner );
	yyset_in(f, scanner);
	while (yyparse(scanner, user_data));
	yylex_destroy (scanner);
}

Reset ★★★★★
()
Ответ на: комментарий от Rarruga

Я там несколько запутался в структурах. Точнее в понимании того где кончается суровая необходимость спецификации и начинаются детали решения задачи. Основная проблема у меня именно во взаимодействии flex'а с bison'ом и обмене данными между ними. К слову пример этот скомпилировать я не смог в виду довольно неожиданного заявления линкера что он понятия не имеет где взять sqrt, exp и log.

KblCb ★★★★★
() автор топика
Ответ на: комментарий от Reset

Хм... Вот scanner.l

%{
	#include "parser.h"
	#define YY_DECL int yylex( YYSTYPE* yylval, yyscan_t yyscanner )
	#include <string.h>
%}

%option reentrant noyywrap
%option outfile="scanner.c" header-file="scanner.h"
%option noansi-definitions

%%

[a-z]+  { yylval = strdup( yytext ); return WORD; }
[\n;]   { return EOL; }

%%
Вот parser.y
%{
    #include <stdio.h>
    #define YYSTYPE char*
    #include "scanner.h"    
    #define YY_DECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner )
    #define YYLEX_PARAM yyscanner
//    YY_DECL;
%}

%token EOL WORD
%parse-param { yyscan_t yyscanner } 
%define api.pure
%debug
%output "parser.c"

%%

input : 
      | input line
      ;

line  : EOL
      | atom EOL
      ;

atom  : WORD            { printf( "%s\n", $$ ); }
      ;

%%

int main( void )
{
    yyscan_t scanner; 
    yylex_init( &scanner ); 
    yyset_in( stdin, scanner ); 
    while ( yyparse( scanner )); 
    yylex_destroy( scanner ); 
}
А вот мнение gcc по поводу всего этого:
$ gcc scanner.c parser.c -c
test.l: В функции ‘yylex’:
test.l:13: предупреждение: несовместимый тип указателя в присваивании
parser.c: В функции ‘yyparse’:
parser.c:1231: ошибка: слишком много аргументов в вызове функции ‘yylex’
В чём я не прав?

KblCb ★★★★★
() автор топика
Ответ на: комментарий от KblCb
--- parser.y~   2010-03-14 12:30:27.000000000 +0300
+++ parser.y    2010-03-14 12:35:07.000000000 +0300
@@ -1,8 +1,8 @@
 %{
     #include <stdio.h>
     #define YYSTYPE char*
-    #include "scanner.h"
     #define YY_DECL int yylex( YYSTYPE * yylval, yyscan_t yyscanner )
+    #include "scanner.h"
     #define YYLEX_PARAM yyscanner
 //    YY_DECL;
 %}
--- scanner.l~  2010-03-14 12:39:51.000000000 +0300
+++ scanner.l   2010-03-14 12:38:05.000000000 +0300
@@ -1,4 +1,5 @@
 %{
+   #define YYSTYPE char *
    #include "parser.h"
    #define YY_DECL int yylex( YYSTYPE* yylval, yyscan_t yyscanner )
    #include <string.h>
@@ -10,7 +11,7 @@

 %%

-[a-z]+  { yylval = strdup( yytext ); return WORD; }
+[a-z]+  { *yylval = strdup( yytext ); return WORD; }
 [\n;]   { return EOL; }

 %%
Reset ★★★★★
()
Ответ на: комментарий от KblCb

в сгенеренные файлы полезно заглядывать, тогда сразу ясно становится что где надо поставить

Reset ★★★★★
()
Ответ на: комментарий от Reset

Вот же глупость. Просидел над этим хрен знает сколько. Ладно. Впредь буду умнее. Спасибо.

KblCb ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.