Compile flex & bison

P

pavel.orehov

Hi,

I am using flex and bizon to write HTTP parser.
I am passing well flex and bison tools but can't compile their output.

================= Flex file (http_parser.lpp) ==============

%{
#include <iostream>
#include "http_parser.tab.hpp"

#define ECHO yyerror("Parse error.")

%}

%x REQUEST
%x AFTER_METHOD
%x RESP_VERSION
%x AFTER_RESP_VERSION
%x RESP_CODE
%x AFTER_RESP_CODE
%x RESP_MSG
%x AFTER_RESP_MSG
%x REQ_HOST
%x REQ_AFTER_HOST
%x REQ_PORT_DELIMITER
%x REQ_PORT
%x REQ_PATH
%x AFTER_REQ_PATH
%x REQ_BEFORE_VERSION
%x REQ_VERSION
%x AFTER_REQ_VERSION
%x HEADER_NAME
%x HEADER_DELIMITER
%x HEADER_VALUE
%x AFTER_HEADER_VALUE

WS [\x20\t]+
CRLF (\r\n|\r|\n)
TOKEN [^\x80-\xFF\x7F\x00-\x1F\x20\x22\r\n\t]+
LETTER [a-zA-Z]
HEADER_NAME [-_a-zA-Z]+
DIGIT [0-9]
PROTOCOL (http:\/\/|ftp:\/\/)
HOST [^\x2F\x3A\x80-\xFF\x7F\x00-\x1F\x20\x22\r\n\t]+
PORT {DIGIT}+
METHOD {LETTER}+

%%

{METHOD}/{WS} {
BEGIN AFTER_METHOD;

std::cout << "REQUEST\n";
std::cout << "METHOD='" << YYText() << "'\n";

return T_REQ_METHOD;
}

<AFTER_METHOD>{WS} {
BEGIN REQUEST;
}

"HTTP/" {
BEGIN RESP_VERSION;

std::cout << "RESPONSE\n";
}

<RESP_VERSION>{DIGIT}+\.{DIGIT}+/{WS} {
BEGIN AFTER_RESP_VERSION;

std::cout << "RESP_VERSION='" << YYText() << "'\n";

return T_RESP_VERSION;
}

<AFTER_RESP_VERSION>{WS} {
BEGIN RESP_CODE;
}

<RESP_CODE>{DIGIT}+/{WS} {
BEGIN AFTER_RESP_CODE;

std::cout << "RESP_CODE='" << YYText() << "'\n";

return T_RESP_CODE;
}

<AFTER_RESP_CODE>{WS} {
BEGIN RESP_MSG;
}

<RESP_MSG>{TOKEN}/{CRLF} {
BEGIN AFTER_RESP_MSG;

std::cout << "RESP_MSG='" << YYText() << "'\n";

return T_RESP_MSG;
}

<AFTER_RESP_MSG>{CRLF} {
BEGIN HEADER_NAME;
}

<REQUEST>"/" {
BEGIN REQ_PATH;

std::cout << "REQ_RELATIVE_1\n";
}

<REQUEST>"/"{WS} {
BEGIN REQ_BEFORE_VERSION;

std::cout << "REQ_RELATIVE_2\n";
}

<REQUEST>{PROTOCOL} {
BEGIN REQ_HOST;

std::cout << "REQ_ABSOLUTE_1\n";
std::cout << "PROTOCOL='" << YYText() << "'\n";

return T_REQ_PROTOCOL;
}

<REQ_HOST>{HOST}/: {
BEGIN REQ_PORT_DELIMITER;

std::cout << "REQ_HOST_1='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_HOST>{HOST}/\/ {
BEGIN REQ_PATH;

std::cout << "REQ_HOST_2='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_HOST>{HOST}/{WS} {
BEGIN REQ_AFTER_HOST;

std::cout << "REQ_HOST_3='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_AFTER_HOST>{WS} {
BEGIN REQ_BEFORE_VERSION;
}

<REQ_PORT_DELIMITER>":" {
BEGIN REQ_PORT;
}

<REQ_PORT>{PORT}/\/ {
BEGIN REQ_PATH;

std::cout << "REQ_PORT_1='" << YYText() << "'\n";

return T_REQ_PORT;
}

<REQ_PORT>{PORT}/{WS} {
BEGIN REQ_BEFORE_VERSION;

std::cout << "REQ_PORT_2='" << YYText() << "'\n";

return T_REQ_PORT;
}

REQ_PATH>{TOKEN}/{WS} {
BEGIN AFTER_REQ_PATH;

std::cout << "REQ_PATH='" << YYText() << "'\n";

return T_REQ_PATH;
}

<AFTER_REQ_PATH>{WS} {
BEGIN REQ_BEFORE_VERSION;
}

<REQ_BEFORE_VERSION>"HTTP/" {
BEGIN REQ_VERSION;
}

<REQ_VERSION>{DIGIT}+\.{DIGIT}+/{CRLF} {
BEGIN AFTER_REQ_VERSION;

std::cout << "REQ_VERSION='" << YYText() << "'\n";

return T_REQ_VERSION;
}

<AFTER_REQ_VERSION>{CRLF} {
BEGIN HEADER_NAME;
}

<HEADER_NAME>{HEADER_NAME}+/:{WS} {
BEGIN HEADER_DELIMITER;

std::cout << "HEADER_NAME='" << YYText() << "'\n";

return T_HEADER_NAME;
}

<HEADER_DELIMITER>:{WS} {
BEGIN HEADER_VALUE;
}

<HEADER_VALUE>[^\r\n]*/{CRLF} {
BEGIN AFTER_HEADER_VALUE;

std::cout << "HEADER_VALUE='" << YYText() << "'\n";

return T_HEADER_VALUE;
}

<AFTER_HEADER_VALUE>{CRLF} {
BEGIN HEADER_NAME;
}

<AFTER_HEADER_VALUE>{CRLF}{CRLF} { ; }

%%

============== Bizon file (http_parser.ypp) ================

%{
#include <iostream>

extern "C"
{
void yyerror(char *);
int yyparse(void);
int yylex(void);
int yywrap();
}

%}

%token T_REQ_METHOD
%token T_REQ_PROTOCOL
%token T_REQ_HOST
%token T_REQ_PORT
%token T_REQ_PATH
%token T_REQ_VERSION

%token T_RESP_VERSION
%token T_RESP_CODE
%token T_RESP_MSG

%token T_HEADER_NAME
%token T_HEADER_VALUE


%%

program:
| request
| response
;

request:
/* Absolute requests */
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PORT T_REQ_PATH
T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PORT T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PATH T_REQ_VERSION
headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_VERSION headers\n";
}
|
/* Relative requests */
T_REQ_METHOD T_REQ_PATH T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_PATH T_REQ_VERSION
headers\n";
}
|
T_REQ_METHOD T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_VERSION headers\n";
}
;

response:
T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers {
std::cout << "T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers\n";
}
;

headers:
headers header
|
;

header:
T_HEADER_NAME T_HEADER_VALUE {
std::cout << "T_HEADER_NAME T_HEADER_VALUE\n";
}
;

%%

int yywrap(void) {
return 1;
}

void yyerror(char * msg)
{
std::cout << "ERROR: " << msg << std::endl;
}

int main( void )
{
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;
return 0;
}

===================== Compile ====================

1. flex --c++ http_parser.lpp
OK

2. bison -d http_parser.ypp
OK

3. Files list
http_parser.lpp
http_parser.tab.cpp
http_parser.tab.hpp
http_parser.ypp
lex.yy.cc

4. g++ -c lex.yy.cc http_parser.tab.cpp
http_parser.lpp: In member function `virtual int yyFlexLexer::yylex()':
http_parser.lpp:222: error: `yyerror' undeclared (first use this
function)
http_parser.lpp:222: error: (Each undeclared identifier is reported
only once
for each function it appears in.)
lex.yy.cc:1174: error: `yywrap' undeclared (first use this function)
http_parser.ypp: In function `int main()':
http_parser.ypp:90: error: `FlexLexer' undeclared (first use this
function)
http_parser.ypp:90: error: (Each undeclared identifier is reported only
once
for each function it appears in.)
http_parser.ypp:90: error: `lexer' undeclared (first use this function)
http_parser.ypp:90: error: parse error before `;' token

What i am doing wrong ???

Thanks a lot.
 
J

John Harrison

Hi,

I am using flex and bizon to write HTTP parser.
I am passing well flex and bison tools but can't compile their output.

[snip]


4. g++ -c lex.yy.cc http_parser.tab.cpp
http_parser.lpp: In member function `virtual int yyFlexLexer::yylex()':
http_parser.lpp:222: error: `yyerror' undeclared (first use this
function)
http_parser.lpp:222: error: (Each undeclared identifier is reported
only once
for each function it appears in.)
lex.yy.cc:1174: error: `yywrap' undeclared (first use this function)
http_parser.ypp: In function `int main()':
http_parser.ypp:90: error: `FlexLexer' undeclared (first use this
function)
http_parser.ypp:90: error: (Each undeclared identifier is reported only
once
for each function it appears in.)
http_parser.ypp:90: error: `lexer' undeclared (first use this function)
http_parser.ypp:90: error: parse error before `;' token

What i am doing wrong ???

Thanks a lot.

Flex and bison are really ugly, they use confusing macros all over the
place and they don't interface cleanly with each other or with C++.

I'm not exactly sure (this isn't a felix/bison group after all) but I
would say that you need to put #include <FlexLexer.h> at the start of
http_parser.ypp. Really to fix these bugs you are going to have to dig
around in the awful code that flex and bison generate and figure out for
yourself what the causes are. Usually it will be that you have to
manually add some prototype, header file or macro to your grammar or
scanner file.

While you are trying to fix these problems it is a good idea to use the
options that prevent #line directives appearing in the generated output
(-L for flex, not sure for bison). That way at least you get the correct
line numbers for errors reported.

Also while you are getting the hang of this, it might be a better idea
to start small.

john
 
P

pavel.orehov

Okey i have fixed dome things and now i have a linking problem.
It can't find yylex function.

========= Flex =========
%{
#include <iostream>
#include "http_parser.tab.hpp"

extern int yywrap(void);

//#define ECHO yyerror("Parse error.")

%}

%x REQUEST
%x AFTER_METHOD
%x RESP_VERSION
%x AFTER_RESP_VERSION
%x RESP_CODE
%x AFTER_RESP_CODE
%x RESP_MSG
%x AFTER_RESP_MSG
%x REQ_HOST
%x REQ_AFTER_HOST
%x REQ_PORT_DELIMITER
%x REQ_PORT
%x REQ_PATH
%x AFTER_REQ_PATH
%x REQ_BEFORE_VERSION
%x REQ_VERSION
%x AFTER_REQ_VERSION
%x HEADER_NAME
%x HEADER_DELIMITER
%x HEADER_VALUE
%x AFTER_HEADER_VALUE

WS [\x20\t]+
CRLF (\r\n|\r|\n)
TOKEN [^\x80-\xFF\x7F\x00-\x1F\x20\x22\r\n\t]+
LETTER [a-zA-Z]
HEADER_NAME [-_a-zA-Z]+
DIGIT [0-9]
PROTOCOL (http:\/\/|ftp:\/\/)
HOST [^\x2F\x3A\x80-\xFF\x7F\x00-\x1F\x20\x22\r\n\t]+
PORT {DIGIT}+
METHOD {LETTER}+

%%

{METHOD}/{WS} {
BEGIN AFTER_METHOD;

std::cout << "REQUEST\n";
std::cout << "METHOD='" << YYText() << "'\n";

return T_REQ_METHOD;
}

<AFTER_METHOD>{WS} {
BEGIN REQUEST;
}

"HTTP/" {
BEGIN RESP_VERSION;

std::cout << "RESPONSE\n";
}

<RESP_VERSION>{DIGIT}+\.{DIGIT}+/{WS} {
BEGIN AFTER_RESP_VERSION;

std::cout << "RESP_VERSION='" << YYText() << "'\n";

return T_RESP_VERSION;
}

<AFTER_RESP_VERSION>{WS} {
BEGIN RESP_CODE;
}

<RESP_CODE>{DIGIT}+/{WS} {
BEGIN AFTER_RESP_CODE;

std::cout << "RESP_CODE='" << YYText() << "'\n";

return T_RESP_CODE;
}

<AFTER_RESP_CODE>{WS} {
BEGIN RESP_MSG;
}

<RESP_MSG>{TOKEN}/{CRLF} {
BEGIN AFTER_RESP_MSG;

std::cout << "RESP_MSG='" << YYText() << "'\n";

return T_RESP_MSG;
}

<AFTER_RESP_MSG>{CRLF} {
BEGIN HEADER_NAME;
}

<REQUEST>"/" {
BEGIN REQ_PATH;

std::cout << "REQ_RELATIVE_1\n";
}

<REQUEST>"/"{WS} {
BEGIN REQ_BEFORE_VERSION;

std::cout << "REQ_RELATIVE_2\n";
}

<REQUEST>{PROTOCOL} {
BEGIN REQ_HOST;

std::cout << "REQ_ABSOLUTE_1\n";
std::cout << "PROTOCOL='" << YYText() << "'\n";

return T_REQ_PROTOCOL;
}

<REQ_HOST>{HOST}/: {
BEGIN REQ_PORT_DELIMITER;

std::cout << "REQ_HOST_1='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_HOST>{HOST}/\/ {
BEGIN REQ_PATH;

std::cout << "REQ_HOST_2='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_HOST>{HOST}/{WS} {
BEGIN REQ_AFTER_HOST;

std::cout << "REQ_HOST_3='" << YYText() << "'\n";

return T_REQ_HOST;
}

<REQ_AFTER_HOST>{WS} {
BEGIN REQ_BEFORE_VERSION;
}

<REQ_PORT_DELIMITER>":" {
BEGIN REQ_PORT;
}

<REQ_PORT>{PORT}/\/ {
BEGIN REQ_PATH;

std::cout << "REQ_PORT_1='" << YYText() << "'\n";

return T_REQ_PORT;
}

<REQ_PORT>{PORT}/{WS} {
BEGIN REQ_BEFORE_VERSION;

std::cout << "REQ_PORT_2='" << YYText() << "'\n";

return T_REQ_PORT;
}

REQ_PATH>{TOKEN}/{WS} {
BEGIN AFTER_REQ_PATH;

std::cout << "REQ_PATH='" << YYText() << "'\n";

return T_REQ_PATH;
}

<AFTER_REQ_PATH>{WS} {
BEGIN REQ_BEFORE_VERSION;
}

<REQ_BEFORE_VERSION>"HTTP/" {
BEGIN REQ_VERSION;
}

<REQ_VERSION>{DIGIT}+\.{DIGIT}+/{CRLF} {
BEGIN AFTER_REQ_VERSION;

std::cout << "REQ_VERSION='" << YYText() << "'\n";

return T_REQ_VERSION;
}

<AFTER_REQ_VERSION>{CRLF} {
BEGIN HEADER_NAME;
}

<HEADER_NAME>{HEADER_NAME}+/:{WS} {
BEGIN HEADER_DELIMITER;

std::cout << "HEADER_NAME='" << YYText() << "'\n";

return T_HEADER_NAME;
}

<HEADER_DELIMITER>:{WS} {
BEGIN HEADER_VALUE;
}

<HEADER_VALUE>[^\r\n]*/{CRLF} {
BEGIN AFTER_HEADER_VALUE;

std::cout << "HEADER_VALUE='" << YYText() << "'\n";

return T_HEADER_VALUE;
}

<AFTER_HEADER_VALUE>{CRLF} {
BEGIN HEADER_NAME;
}

<AFTER_HEADER_VALUE>{CRLF}{CRLF} { ; }

%%

int yywrap(void) {
return 1;
}

========= Bison =========

%{
#include <iostream>
#include <FlexLexer.h>

extern void yyerror(char *);

#ifdef __cplusplus
extern "C"
{
int yylex(void);
}
#endif

%}

%token T_REQ_METHOD
%token T_REQ_PROTOCOL
%token T_REQ_HOST
%token T_REQ_PORT
%token T_REQ_PATH
%token T_REQ_VERSION

%token T_RESP_VERSION
%token T_RESP_CODE
%token T_RESP_MSG

%token T_HEADER_NAME
%token T_HEADER_VALUE


%%

program:
| request
| response
;

request:
/* Absolute requests */
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PORT T_REQ_PATH
T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PORT T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PATH T_REQ_VERSION
headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_VERSION headers\n";
}
|
/* Relative requests */
T_REQ_METHOD T_REQ_PATH T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_PATH T_REQ_VERSION
headers\n";
}
|
T_REQ_METHOD T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_VERSION headers\n";
}
;

response:
T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers {
std::cout << "T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers\n";
}
;

headers:
headers header
|
;

header:
T_HEADER_NAME T_HEADER_VALUE {
std::cout << "T_HEADER_NAME T_HEADER_VALUE\n";
}
;

%%

void yyerror(char * msg)
{
std::cout << "ERROR: " << msg << std::endl;
}

int main(void)
{
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;

return 0;
}

========= Makefile =========

APP = http_parser
SOURCE = resp_header
BISON_OPTIONS = -dv
FLEX_OPTIONS = --c++

$(APP): lex.yy.o $(APP).tab.o
g++ -o $(APP) $(APP).tab.o lex.yy.o # -lm -lfl
./$(APP) < $(SOURCE)

lex.yy.o: lex.yy.cc
g++ -c lex.yy.cc

$(APP).tab.o: $(APP).tab.cpp
g++ -c $(APP).tab.cpp

lex.yy.cc: $(APP).tab.hpp $(APP).tab.cpp
flex $(FLEX_OPTIONS) $(APP).lpp

$(APP).tab.hpp:
bison $(BISON_OPTIONS) $(APP).ypp

$(APP).tab.cpp:
bison $(BISON_OPTIONS) $(APP).ypp

run:
./$(APP) < $(SOURCE)

clean:
-rm *.tab.* lex.yy.* *.o *~ *.output

=========== Output =========

bison -dv http_parser.ypp
flex --c++ http_parser.lpp
g++ -c lex.yy.cc
g++ -c http_parser.tab.cpp
g++ -o http_parser http_parser.tab.o lex.yy.o # -lm -lfl
http_parser.tab.o(.text+0x261): In function `yyparse()':
: undefined reference to `yylex'
collect2: ld returned 1 exit status
make: *** [http_parser] Error 1
 
J

John Harrison

Okey i have fixed dome things and now i have a linking problem.
It can't find yylex function.

[snip]


int main(void)
{
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;

return 0;
}

Two problems I can see. Firstly in main you should be calling yyparse
not lexer->yylex. The parser calls the scanner, in your code you are
calling the scanner only so no parsing is going to happen.

Normally the parser calls a function called yylex to do the scanning.
Because you've chosen to use a C++ scanner the yylex function doesn't
get generated. I guess the easiest way round this is to write your own
version of yylex that calls lexer->yylex. You can use the %lex-param
directive to add extra paramters to yylex. Something like that anyway, I
am not an expert.

john
 
J

Jacques Labuschagne

Okey i have fixed dome things and now i have a linking problem.
It can't find yylex function.
========= Makefile =========

APP = http_parser
SOURCE = resp_header
BISON_OPTIONS = -dv
FLEX_OPTIONS = --c++

$(APP): lex.yy.o $(APP).tab.o
g++ -o $(APP) $(APP).tab.o lex.yy.o # -lm -lfl
./$(APP) < $(SOURCE)

You're not linking the Flex library. '#' is the comment character.

Jacques.
 
P

pavel.orehov

You're not linking the Flex library. '#' is the comment character.

I don't know what these flugs for, but i have tried with them, the same
problem.
I guess the easiest way round this is to write your own version of yylex that calls lexer->yylex.

It worked, but now i only lex works without yacc/bison grammar.

How should i start grammar checker ?

============ Changed yacc/bison ============
%{
#include <iostream>
#include <FlexLexer.h>

#ifdef __cplusplus
extern "C"
{
int yylex(void);
void yyerror(char *);
int yyparse(void);
}
#endif

%}

%token T_REQ_METHOD
%token T_REQ_PROTOCOL
%token T_REQ_HOST
%token T_REQ_PORT
%token T_REQ_PATH
%token T_REQ_VERSION

%token T_RESP_VERSION
%token T_RESP_CODE
%token T_RESP_MSG

%token T_HEADER_NAME
%token T_HEADER_VALUE


%%

program:
| request
| response
;

request:
/* Absolute requests */
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PORT T_REQ_PATH
T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PORT T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_PATH T_REQ_VERSION
headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_PATH T_REQ_VERSION headers\n";
}
|
T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST T_REQ_VERSION headers {
std::cout << "ABS => T_REQ_METHOD T_REQ_PROTOCOL T_REQ_HOST
T_REQ_VERSION headers\n";
}
|
/* Relative requests */
T_REQ_METHOD T_REQ_PATH T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_PATH T_REQ_VERSION
headers\n";
}
|
T_REQ_METHOD T_REQ_VERSION headers {
std::cout << "REL => T_REQ_METHOD T_REQ_VERSION headers\n";
}
;

response:
T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers {
std::cout << "T_RESP_VERSION T_RESP_CODE T_RESP_MSG headers\n";
}
;

headers:
headers header
|
;

header:
T_HEADER_NAME T_HEADER_VALUE {
std::cout << "T_HEADER_NAME T_HEADER_VALUE\n";
}
;

%%

void yyerror(char * msg)
{
std::cout << "ERROR: " << msg << std::endl;
}

int yylex(void)
{
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;
}

int main(void)
{
yyparse();
return 0;
}
 
P

pavel.orehov

Should i implement yylex by myself and return tokens match to
dictionary rules ???
 
P

pavel.orehov

Okey, i found the way to solve it.

I have declared global lexer in bison input file:

yyFlexLexer lexer;

and

int yylex(void)
{
return lexer.yylex();
}

It works fine with grammar.

Now my next question is how can i call yyparse() not from main in beson
input file ?
I mean i want other external main.cpp file and call yyparse() from
there. What should i include in this file to know yyparse() function ?
 
J

John Harrison

Okey, i found the way to solve it.

I have declared global lexer in bison input file:

yyFlexLexer lexer;

and

int yylex(void)
{
return lexer.yylex();
}

It works fine with grammar.

Now my next question is how can i call yyparse() not from main in beson
input file ?
I mean i want other external main.cpp file and call yyparse() from
there. What should i include in this file to know yyparse() function ?

I don't think there is anything to include. I think you just write

extern int yyparse();

int main()
{
yyparse();
}

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,734
Latest member
manin

Latest Threads

Top