Использование Bison для разбора строки char *

0

Как я могу заставить функцию yyparse читать ее ввод из строки C?

Tried yy_scan_buffer (используя префикс "fp" вместо "yy"):

extern YY_BUFFER_STATE fs_scan_string ( const char *str );

struct fs *parse(char *s)
{
fp_scan_buffer(s);
int r = fpparse();
return r == 0 ? AST : NULL;

}

Но:

h1.cpp:27: error: ‘YY_BUFFER_STATE does not name a type
h1.cpp: In function ‘fs* parse(char*):
h1.cpp:32: error: ‘fp_scan_buffer was not declared in this scope

Пробовал использовать yy_delete_buffer, тот же результат: не был объявлен в этой области.

fp.y

%{
#include "ft.h"
#include <map>
#include <iostream>

int fplex(); 
int fperror(char *p);
int fperror(char *p) { }

using namespace std;

struct fs *AST;
bool fpworking = true;
%}

%union {
    struct fs *f;
    struct ts *t;
    std::list<struct ts *> *tl;
    std::string *s;
}

%token END_OF_FILE
MORE TOKEN HERE...

%%

s : formula '\n'    { AST = $1; fpworking = true; YYACCEPT; }
MORE RULE HERE...

fp.l

%{
#include <iostream>
#include <list>
using namespace std;
#include "fp.tab.h"
%}

%option noyywrap

%%
[a-z][a-zA-Z0-9]*       { fplval.s = new std::string(fptext); return (TERM_ID); }
MORE PATTERN HERE...

h1.cpp

#include <iostream>
#include <list>
#include <string>
#include <map>
#include <stdlib.h>
#include <fstream>
#include "ft.h"

int fpparse();
int signparse();

extern bool fpworking;
extern struct fs *AST;

int main(int argc, char **argv)
{
    MORE CODE HERE...
}
Теги:
parsing
bison
flex-lexer

2 ответа

1
Лучший ответ

Чтобы использовать различные гибкие символы (такие как YY_BUFFER_STATE и yy_scan_buffer), код, который делает это, должен быть помещен в 3-й раздел файла.l.

Проблема в том, что эти символы определены только в файле lex.yy.c, а не в любом заголовочном файле, который можно #include другом месте.

Итак, все, что вам нужно сделать, это поместить ваш parse (первый блок выше) в конец.l файла (после второй строки %%) и вызвать его из main и он должен работать нормально.

2

Парсер, созданный bison не выполняет ввода-вывода. Ответственность за считывание (или иное получение) вводится сканеру, который часто генерируется (f)lex. Функции управления буфером, которые вы называете, являются частью flex структуры. Они не экспортируются ни в какой заголовок, поэтому вам нужно либо использовать их в коде, вставленном в файл ввода flex, либо явно добавить его в свой собственный заголовочный файл.

Традиционное использование flex и bison (или, вообще, производных lex и yacc) в значительной степени основывалось на глобальных переменных состояния, что затрудняло интеграцию нескольких парсеров и/или сканеров в один исполняемый файл. Изменение префикса yy самом деле не решает эту проблему, но позволяет разрешить несколько синглетонов. Более поздние версии генераторов кода позволяют генерировать pure парсеры и сканеры, которые в качестве дополнительного аргумента принимают структуру, содержащую состояние. Можно добавить свое собственное состояние в эти структуры или даже объединить их в единую структуру. Это может создать более элегантный интерфейс, но инструменты не помогут вам в разработке API. В любом случае, с чистыми анализаторами и сканерами, доступ к внешнему виду может быть менее доступным.

Короче говоря, вы, вероятно, должны добавить свой собственный API управления буфером в свой файл flex, экспортировать его интерфейсы в свой собственный заголовочный файл и импортировать этот файл в свой сканер, ваш парсер и своих потребителей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню