2013-10-05 3 views
0

Как я могу сделать функцию yyparse читать ее входные данные из строки C?Использование Bison для синтаксического анализа из строки char *

Пробовал yy_scan_buffer (используя "FP" префикс вместо "уу"):

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... 
} 
+0

Знайте правильную маркировку. Flex используется для интерфейса Adobe/Apache. Flex-lexer используется для лексического анализатора. – JeffryHouser

+0

Проблема заключается в взаимодействии кода, который вы показали, и кода, который вы не показывали. Пожалуйста, создайте полный, автономный, вырезанный файл .y, который демонстрирует ту же проблему. – zwol

ответ

1

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

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

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

2

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

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

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

Смежные вопросы