Multiply parse using flex and bison
I am working at a C++ database query engine project
. At this time I should be able to parse to schema sql.data (like create table
) and the query sql.data (like select ... from ...
). So I have 2 parser for each sql.
The Problem I have: I can only use the parser only once and it worked very good. If I try to parse the schema and the query at same time, then I have some following conflicts:
(It just part of the coming conflicts, but I think it can the main reasons and main conflicts)
> ninja
[9/10] Linking CXX executable imlabdb
FAILED: imlabdb
: && /usr/bin/c++ -g -O0 -fsanitize=address CMakeFiles/imlabdb.dir/tools/imlabdb.cc.o -o imlabdb libimlab.a libschema.a libquery.a vendor/gflags/lib/libgflags.a -pthread && :
libquery.a(query_scanner.cc.o):(.bss+0x140): multiple definition of `yyleng'
libschema.a(schema_scanner.cc.o):(.bss+0x140): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x280): multiple definition of `yyin'
libschema.a(schema_scanner.cc.o):(.bss+0x280): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x2c0): multiple definition of `yyout'
libschema.a(schema_scanner.cc.o):(.bss+0x2c0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x0): multiple definition of `yylineno'
libschema.a(schema_scanner.cc.o):(.data+0x0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x40): multiple definition of `yy_flex_debug'
libschema.a(schema_scanner.cc.o):(.data+0x40): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x380): multiple definition of `yytext'
libschema.a(schema_scanner.cc.o):(.bss+0x380): first defined here
And as you can see, I compile with ninja. I think the local.make
and the CMakeList.txt
have no problem, so I skip to show them here.
The I try to show my code in the clean way.
imlabdb.cc
int main(int argc, char *argv) {
imlab::schemac::SchemaParseContext schema_parse_context;
std::ifstream in_schema("../data/schema.sql"); // schema sql
auto schema = schema_parse_context.Parse(in_schema);
in_schema.close();
imlab::queryc::QueryParseContext query_parse_context;
std::ifstream in_query("../data/queryc_2.sql"); // query sql
auto query = query_parse_context.Parse(in_query);
in_query.close();
}
schema_parse_context.cc
Schema SchemaParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::schemac::SchemaParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {mySchema}; // a container for the create table nokens
}
query_parse_context.cc
Query QueryParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::queryc::QueryParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {myQuery}; // a container for querys
}
Then I show the flex and bison
of the schema.
schema_scanner.l without the most unnecessary tokens.
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/schemac/schema_parse_context.h"
#include "./schema_parser.h"
namespace imlab {
namespace schemac {
// The location of the current token
extern imlab::schemac::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace schemac
} // namespace imlab
using namespace imlab::schemac;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL SchemaParser::symbol_type yylex(SchemaParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%{
// noyywrap: Disable yywrap (EOF == end of parsing)
// nounput: Disable manipulation of input stream
// noinput: Disable explicit fetch of the next character
// batch: Scanner in batch-mode (vs. interactive)
// debug: Write debug info to stderr
// caseless: Case-insensitive pattern matching
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
// Code run each time a token is matched.
// We just update the location of the token.
#define YY_USER_ACTION { loc.columns(yyleng); }
%}
%%
%{
// Code runs each time yylex is called.
// Set the beginning of the token to the end of the previous token.
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return SchemaParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::schemac::location imlab::schemac::loc;
// The input stream of the scanner
std::istream *imlab::schemac::in = nullptr;
// Begin a scan
void imlab::schemac::SchemaParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::schemac::SchemaParseContext::endScan() {
in = nullptr;
}
schema_parser.y also with the unnecessary tokens and cases deleted
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
// Write a parser header file
%defines
// Define the parser class name
%define parser_class_name {SchemaParser}
// Create the parser in our namespace
%define api.namespace { imlab::schemac }
// Use C++ variant to store the values and get better type warnings (compared to "union")
%define api.value.type variant
// With variant-based values, symbols are handled as a whole in the scanner
%define api.token.constructor
// Prefix all tokens
%define api.token.prefix {SCHEMA_}
// Check if variants are constructed and destroyed properly
%define parse.assert
// Trace the parser
%define parse.trace
// Use verbose parser errors
%define parse.error verbose
// Enable location tracking.
%locations
// Pass the compiler as parameter to yylex/yyparse.
%param { imlab::schemac::SchemaParseContext &sc }
// ---------------------------------------------------------------------------------------------------
// Added to the header file and parser implementation before bison definitions.
// We include string for string tokens and forward declare the SchemaParseContext.
%code requires {
#include <string>
#include <vector>
#include "imlab/schemac/schema_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
// Import the compiler header in the implementation file
%code {
imlab::schemac::SchemaParser::symbol_type yylex(imlab::schemac::SchemaParseContext& sc);
}
%code {
std::string insertTableId;
int positionToInsert;
}
// ---------------------------------------------------------------------------------------------------
// Token definitions but deleted the most of them
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::schemac::SchemaParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
Now the flex and bison
for query
, but almost written in the same way.
query_scanner.l
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/queryc/query_parse_context.h"
#include "./query_parser.h"
namespace imlab {
namespace queryc {
// The location of the current token
extern imlab::queryc::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace queryc
} // namespace imlab
using namespace imlab::queryc;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL QueryParser::symbol_type yylex(QueryParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
#define YY_USER_ACTION { loc.columns(yyleng); }
%%
%{
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return QueryParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::queryc::location imlab::queryc::loc;
// The input stream of the scanner
std::istream *imlab::queryc::in = nullptr;
// Begin a scan
void imlab::queryc::QueryParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::queryc::QueryParseContext::endScan() {
in = nullptr;
}
query_parser.y
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
%defines
%define parser_class_name {QueryParser}
%define api.namespace { imlab::queryc }
%define api.value.type variant
%define api.token.constructor
%define api.token.prefix {QUERY_}
%define parse.assert
%define parse.trace
%define parse.error verbose
%locations
%param { imlab::queryc::QueryParseContext &sc }
// ---------------------------------------------------------------------------------------------------
%code requires {
#include <string>
#include <vector>
#include "imlab/queryc/query_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
%code {
imlab::queryc::QueryParser::symbol_type yylex(imlab::queryc::QueryParseContext& sc);
}
// %code {
// std::string insertTableId;
// int positionToInsert;
// }
// ---------------------------------------------------------------------------------------------------
// Token definitions -- most of them deleted
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::queryc::QueryParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
// ---------------------------------------------------------------------------------------------------
In short:
What I can be sure: These two flex and bison
and other things like imlabdb.cc
are working well, if I only use one of them in the imlabdb.cc
. The conflict which I added to the top only happens, when I try to use two parser at same time.
What I want: To use the two parser at same time and avoid the naming conflicts.
Thanks!
(If I deleted to much code or is the current code not sufficient, please post. I will fix it.)
c++ database parsing bison flex-lexer
add a comment |
I am working at a C++ database query engine project
. At this time I should be able to parse to schema sql.data (like create table
) and the query sql.data (like select ... from ...
). So I have 2 parser for each sql.
The Problem I have: I can only use the parser only once and it worked very good. If I try to parse the schema and the query at same time, then I have some following conflicts:
(It just part of the coming conflicts, but I think it can the main reasons and main conflicts)
> ninja
[9/10] Linking CXX executable imlabdb
FAILED: imlabdb
: && /usr/bin/c++ -g -O0 -fsanitize=address CMakeFiles/imlabdb.dir/tools/imlabdb.cc.o -o imlabdb libimlab.a libschema.a libquery.a vendor/gflags/lib/libgflags.a -pthread && :
libquery.a(query_scanner.cc.o):(.bss+0x140): multiple definition of `yyleng'
libschema.a(schema_scanner.cc.o):(.bss+0x140): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x280): multiple definition of `yyin'
libschema.a(schema_scanner.cc.o):(.bss+0x280): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x2c0): multiple definition of `yyout'
libschema.a(schema_scanner.cc.o):(.bss+0x2c0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x0): multiple definition of `yylineno'
libschema.a(schema_scanner.cc.o):(.data+0x0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x40): multiple definition of `yy_flex_debug'
libschema.a(schema_scanner.cc.o):(.data+0x40): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x380): multiple definition of `yytext'
libschema.a(schema_scanner.cc.o):(.bss+0x380): first defined here
And as you can see, I compile with ninja. I think the local.make
and the CMakeList.txt
have no problem, so I skip to show them here.
The I try to show my code in the clean way.
imlabdb.cc
int main(int argc, char *argv) {
imlab::schemac::SchemaParseContext schema_parse_context;
std::ifstream in_schema("../data/schema.sql"); // schema sql
auto schema = schema_parse_context.Parse(in_schema);
in_schema.close();
imlab::queryc::QueryParseContext query_parse_context;
std::ifstream in_query("../data/queryc_2.sql"); // query sql
auto query = query_parse_context.Parse(in_query);
in_query.close();
}
schema_parse_context.cc
Schema SchemaParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::schemac::SchemaParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {mySchema}; // a container for the create table nokens
}
query_parse_context.cc
Query QueryParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::queryc::QueryParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {myQuery}; // a container for querys
}
Then I show the flex and bison
of the schema.
schema_scanner.l without the most unnecessary tokens.
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/schemac/schema_parse_context.h"
#include "./schema_parser.h"
namespace imlab {
namespace schemac {
// The location of the current token
extern imlab::schemac::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace schemac
} // namespace imlab
using namespace imlab::schemac;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL SchemaParser::symbol_type yylex(SchemaParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%{
// noyywrap: Disable yywrap (EOF == end of parsing)
// nounput: Disable manipulation of input stream
// noinput: Disable explicit fetch of the next character
// batch: Scanner in batch-mode (vs. interactive)
// debug: Write debug info to stderr
// caseless: Case-insensitive pattern matching
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
// Code run each time a token is matched.
// We just update the location of the token.
#define YY_USER_ACTION { loc.columns(yyleng); }
%}
%%
%{
// Code runs each time yylex is called.
// Set the beginning of the token to the end of the previous token.
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return SchemaParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::schemac::location imlab::schemac::loc;
// The input stream of the scanner
std::istream *imlab::schemac::in = nullptr;
// Begin a scan
void imlab::schemac::SchemaParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::schemac::SchemaParseContext::endScan() {
in = nullptr;
}
schema_parser.y also with the unnecessary tokens and cases deleted
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
// Write a parser header file
%defines
// Define the parser class name
%define parser_class_name {SchemaParser}
// Create the parser in our namespace
%define api.namespace { imlab::schemac }
// Use C++ variant to store the values and get better type warnings (compared to "union")
%define api.value.type variant
// With variant-based values, symbols are handled as a whole in the scanner
%define api.token.constructor
// Prefix all tokens
%define api.token.prefix {SCHEMA_}
// Check if variants are constructed and destroyed properly
%define parse.assert
// Trace the parser
%define parse.trace
// Use verbose parser errors
%define parse.error verbose
// Enable location tracking.
%locations
// Pass the compiler as parameter to yylex/yyparse.
%param { imlab::schemac::SchemaParseContext &sc }
// ---------------------------------------------------------------------------------------------------
// Added to the header file and parser implementation before bison definitions.
// We include string for string tokens and forward declare the SchemaParseContext.
%code requires {
#include <string>
#include <vector>
#include "imlab/schemac/schema_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
// Import the compiler header in the implementation file
%code {
imlab::schemac::SchemaParser::symbol_type yylex(imlab::schemac::SchemaParseContext& sc);
}
%code {
std::string insertTableId;
int positionToInsert;
}
// ---------------------------------------------------------------------------------------------------
// Token definitions but deleted the most of them
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::schemac::SchemaParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
Now the flex and bison
for query
, but almost written in the same way.
query_scanner.l
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/queryc/query_parse_context.h"
#include "./query_parser.h"
namespace imlab {
namespace queryc {
// The location of the current token
extern imlab::queryc::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace queryc
} // namespace imlab
using namespace imlab::queryc;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL QueryParser::symbol_type yylex(QueryParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
#define YY_USER_ACTION { loc.columns(yyleng); }
%%
%{
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return QueryParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::queryc::location imlab::queryc::loc;
// The input stream of the scanner
std::istream *imlab::queryc::in = nullptr;
// Begin a scan
void imlab::queryc::QueryParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::queryc::QueryParseContext::endScan() {
in = nullptr;
}
query_parser.y
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
%defines
%define parser_class_name {QueryParser}
%define api.namespace { imlab::queryc }
%define api.value.type variant
%define api.token.constructor
%define api.token.prefix {QUERY_}
%define parse.assert
%define parse.trace
%define parse.error verbose
%locations
%param { imlab::queryc::QueryParseContext &sc }
// ---------------------------------------------------------------------------------------------------
%code requires {
#include <string>
#include <vector>
#include "imlab/queryc/query_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
%code {
imlab::queryc::QueryParser::symbol_type yylex(imlab::queryc::QueryParseContext& sc);
}
// %code {
// std::string insertTableId;
// int positionToInsert;
// }
// ---------------------------------------------------------------------------------------------------
// Token definitions -- most of them deleted
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::queryc::QueryParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
// ---------------------------------------------------------------------------------------------------
In short:
What I can be sure: These two flex and bison
and other things like imlabdb.cc
are working well, if I only use one of them in the imlabdb.cc
. The conflict which I added to the top only happens, when I try to use two parser at same time.
What I want: To use the two parser at same time and avoid the naming conflicts.
Thanks!
(If I deleted to much code or is the current code not sufficient, please post. I will fix it.)
c++ database parsing bison flex-lexer
add a comment |
I am working at a C++ database query engine project
. At this time I should be able to parse to schema sql.data (like create table
) and the query sql.data (like select ... from ...
). So I have 2 parser for each sql.
The Problem I have: I can only use the parser only once and it worked very good. If I try to parse the schema and the query at same time, then I have some following conflicts:
(It just part of the coming conflicts, but I think it can the main reasons and main conflicts)
> ninja
[9/10] Linking CXX executable imlabdb
FAILED: imlabdb
: && /usr/bin/c++ -g -O0 -fsanitize=address CMakeFiles/imlabdb.dir/tools/imlabdb.cc.o -o imlabdb libimlab.a libschema.a libquery.a vendor/gflags/lib/libgflags.a -pthread && :
libquery.a(query_scanner.cc.o):(.bss+0x140): multiple definition of `yyleng'
libschema.a(schema_scanner.cc.o):(.bss+0x140): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x280): multiple definition of `yyin'
libschema.a(schema_scanner.cc.o):(.bss+0x280): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x2c0): multiple definition of `yyout'
libschema.a(schema_scanner.cc.o):(.bss+0x2c0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x0): multiple definition of `yylineno'
libschema.a(schema_scanner.cc.o):(.data+0x0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x40): multiple definition of `yy_flex_debug'
libschema.a(schema_scanner.cc.o):(.data+0x40): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x380): multiple definition of `yytext'
libschema.a(schema_scanner.cc.o):(.bss+0x380): first defined here
And as you can see, I compile with ninja. I think the local.make
and the CMakeList.txt
have no problem, so I skip to show them here.
The I try to show my code in the clean way.
imlabdb.cc
int main(int argc, char *argv) {
imlab::schemac::SchemaParseContext schema_parse_context;
std::ifstream in_schema("../data/schema.sql"); // schema sql
auto schema = schema_parse_context.Parse(in_schema);
in_schema.close();
imlab::queryc::QueryParseContext query_parse_context;
std::ifstream in_query("../data/queryc_2.sql"); // query sql
auto query = query_parse_context.Parse(in_query);
in_query.close();
}
schema_parse_context.cc
Schema SchemaParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::schemac::SchemaParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {mySchema}; // a container for the create table nokens
}
query_parse_context.cc
Query QueryParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::queryc::QueryParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {myQuery}; // a container for querys
}
Then I show the flex and bison
of the schema.
schema_scanner.l without the most unnecessary tokens.
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/schemac/schema_parse_context.h"
#include "./schema_parser.h"
namespace imlab {
namespace schemac {
// The location of the current token
extern imlab::schemac::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace schemac
} // namespace imlab
using namespace imlab::schemac;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL SchemaParser::symbol_type yylex(SchemaParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%{
// noyywrap: Disable yywrap (EOF == end of parsing)
// nounput: Disable manipulation of input stream
// noinput: Disable explicit fetch of the next character
// batch: Scanner in batch-mode (vs. interactive)
// debug: Write debug info to stderr
// caseless: Case-insensitive pattern matching
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
// Code run each time a token is matched.
// We just update the location of the token.
#define YY_USER_ACTION { loc.columns(yyleng); }
%}
%%
%{
// Code runs each time yylex is called.
// Set the beginning of the token to the end of the previous token.
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return SchemaParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::schemac::location imlab::schemac::loc;
// The input stream of the scanner
std::istream *imlab::schemac::in = nullptr;
// Begin a scan
void imlab::schemac::SchemaParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::schemac::SchemaParseContext::endScan() {
in = nullptr;
}
schema_parser.y also with the unnecessary tokens and cases deleted
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
// Write a parser header file
%defines
// Define the parser class name
%define parser_class_name {SchemaParser}
// Create the parser in our namespace
%define api.namespace { imlab::schemac }
// Use C++ variant to store the values and get better type warnings (compared to "union")
%define api.value.type variant
// With variant-based values, symbols are handled as a whole in the scanner
%define api.token.constructor
// Prefix all tokens
%define api.token.prefix {SCHEMA_}
// Check if variants are constructed and destroyed properly
%define parse.assert
// Trace the parser
%define parse.trace
// Use verbose parser errors
%define parse.error verbose
// Enable location tracking.
%locations
// Pass the compiler as parameter to yylex/yyparse.
%param { imlab::schemac::SchemaParseContext &sc }
// ---------------------------------------------------------------------------------------------------
// Added to the header file and parser implementation before bison definitions.
// We include string for string tokens and forward declare the SchemaParseContext.
%code requires {
#include <string>
#include <vector>
#include "imlab/schemac/schema_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
// Import the compiler header in the implementation file
%code {
imlab::schemac::SchemaParser::symbol_type yylex(imlab::schemac::SchemaParseContext& sc);
}
%code {
std::string insertTableId;
int positionToInsert;
}
// ---------------------------------------------------------------------------------------------------
// Token definitions but deleted the most of them
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::schemac::SchemaParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
Now the flex and bison
for query
, but almost written in the same way.
query_scanner.l
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/queryc/query_parse_context.h"
#include "./query_parser.h"
namespace imlab {
namespace queryc {
// The location of the current token
extern imlab::queryc::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace queryc
} // namespace imlab
using namespace imlab::queryc;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL QueryParser::symbol_type yylex(QueryParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
#define YY_USER_ACTION { loc.columns(yyleng); }
%%
%{
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return QueryParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::queryc::location imlab::queryc::loc;
// The input stream of the scanner
std::istream *imlab::queryc::in = nullptr;
// Begin a scan
void imlab::queryc::QueryParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::queryc::QueryParseContext::endScan() {
in = nullptr;
}
query_parser.y
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
%defines
%define parser_class_name {QueryParser}
%define api.namespace { imlab::queryc }
%define api.value.type variant
%define api.token.constructor
%define api.token.prefix {QUERY_}
%define parse.assert
%define parse.trace
%define parse.error verbose
%locations
%param { imlab::queryc::QueryParseContext &sc }
// ---------------------------------------------------------------------------------------------------
%code requires {
#include <string>
#include <vector>
#include "imlab/queryc/query_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
%code {
imlab::queryc::QueryParser::symbol_type yylex(imlab::queryc::QueryParseContext& sc);
}
// %code {
// std::string insertTableId;
// int positionToInsert;
// }
// ---------------------------------------------------------------------------------------------------
// Token definitions -- most of them deleted
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::queryc::QueryParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
// ---------------------------------------------------------------------------------------------------
In short:
What I can be sure: These two flex and bison
and other things like imlabdb.cc
are working well, if I only use one of them in the imlabdb.cc
. The conflict which I added to the top only happens, when I try to use two parser at same time.
What I want: To use the two parser at same time and avoid the naming conflicts.
Thanks!
(If I deleted to much code or is the current code not sufficient, please post. I will fix it.)
c++ database parsing bison flex-lexer
I am working at a C++ database query engine project
. At this time I should be able to parse to schema sql.data (like create table
) and the query sql.data (like select ... from ...
). So I have 2 parser for each sql.
The Problem I have: I can only use the parser only once and it worked very good. If I try to parse the schema and the query at same time, then I have some following conflicts:
(It just part of the coming conflicts, but I think it can the main reasons and main conflicts)
> ninja
[9/10] Linking CXX executable imlabdb
FAILED: imlabdb
: && /usr/bin/c++ -g -O0 -fsanitize=address CMakeFiles/imlabdb.dir/tools/imlabdb.cc.o -o imlabdb libimlab.a libschema.a libquery.a vendor/gflags/lib/libgflags.a -pthread && :
libquery.a(query_scanner.cc.o):(.bss+0x140): multiple definition of `yyleng'
libschema.a(schema_scanner.cc.o):(.bss+0x140): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x280): multiple definition of `yyin'
libschema.a(schema_scanner.cc.o):(.bss+0x280): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x2c0): multiple definition of `yyout'
libschema.a(schema_scanner.cc.o):(.bss+0x2c0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x0): multiple definition of `yylineno'
libschema.a(schema_scanner.cc.o):(.data+0x0): first defined here
libquery.a(query_scanner.cc.o):(.data+0x40): multiple definition of `yy_flex_debug'
libschema.a(schema_scanner.cc.o):(.data+0x40): first defined here
libquery.a(query_scanner.cc.o):(.bss+0x380): multiple definition of `yytext'
libschema.a(schema_scanner.cc.o):(.bss+0x380): first defined here
And as you can see, I compile with ninja. I think the local.make
and the CMakeList.txt
have no problem, so I skip to show them here.
The I try to show my code in the clean way.
imlabdb.cc
int main(int argc, char *argv) {
imlab::schemac::SchemaParseContext schema_parse_context;
std::ifstream in_schema("../data/schema.sql"); // schema sql
auto schema = schema_parse_context.Parse(in_schema);
in_schema.close();
imlab::queryc::QueryParseContext query_parse_context;
std::ifstream in_query("../data/queryc_2.sql"); // query sql
auto query = query_parse_context.Parse(in_query);
in_query.close();
}
schema_parse_context.cc
Schema SchemaParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::schemac::SchemaParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {mySchema}; // a container for the create table nokens
}
query_parse_context.cc
Query QueryParseContext::Parse(std::istream &in) {
beginScan(in);
imlab::queryc::QueryParser parser(*this);
parser.set_debug_level(trace_parsing_);
parser.parse();
endScan();
return {myQuery}; // a container for querys
}
Then I show the flex and bison
of the schema.
schema_scanner.l without the most unnecessary tokens.
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/schemac/schema_parse_context.h"
#include "./schema_parser.h"
namespace imlab {
namespace schemac {
// The location of the current token
extern imlab::schemac::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace schemac
} // namespace imlab
using namespace imlab::schemac;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL SchemaParser::symbol_type yylex(SchemaParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%{
// noyywrap: Disable yywrap (EOF == end of parsing)
// nounput: Disable manipulation of input stream
// noinput: Disable explicit fetch of the next character
// batch: Scanner in batch-mode (vs. interactive)
// debug: Write debug info to stderr
// caseless: Case-insensitive pattern matching
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
// Code run each time a token is matched.
// We just update the location of the token.
#define YY_USER_ACTION { loc.columns(yyleng); }
%}
%%
%{
// Code runs each time yylex is called.
// Set the beginning of the token to the end of the previous token.
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return SchemaParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::schemac::location imlab::schemac::loc;
// The input stream of the scanner
std::istream *imlab::schemac::in = nullptr;
// Begin a scan
void imlab::schemac::SchemaParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::schemac::SchemaParseContext::endScan() {
in = nullptr;
}
schema_parser.y also with the unnecessary tokens and cases deleted
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
// Write a parser header file
%defines
// Define the parser class name
%define parser_class_name {SchemaParser}
// Create the parser in our namespace
%define api.namespace { imlab::schemac }
// Use C++ variant to store the values and get better type warnings (compared to "union")
%define api.value.type variant
// With variant-based values, symbols are handled as a whole in the scanner
%define api.token.constructor
// Prefix all tokens
%define api.token.prefix {SCHEMA_}
// Check if variants are constructed and destroyed properly
%define parse.assert
// Trace the parser
%define parse.trace
// Use verbose parser errors
%define parse.error verbose
// Enable location tracking.
%locations
// Pass the compiler as parameter to yylex/yyparse.
%param { imlab::schemac::SchemaParseContext &sc }
// ---------------------------------------------------------------------------------------------------
// Added to the header file and parser implementation before bison definitions.
// We include string for string tokens and forward declare the SchemaParseContext.
%code requires {
#include <string>
#include <vector>
#include "imlab/schemac/schema_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
// Import the compiler header in the implementation file
%code {
imlab::schemac::SchemaParser::symbol_type yylex(imlab::schemac::SchemaParseContext& sc);
}
%code {
std::string insertTableId;
int positionToInsert;
}
// ---------------------------------------------------------------------------------------------------
// Token definitions but deleted the most of them
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::schemac::SchemaParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
Now the flex and bison
for query
, but almost written in the same way.
query_scanner.l
%{
// Header
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <string>
#include <istream>
#include "imlab/queryc/query_parse_context.h"
#include "./query_parser.h"
namespace imlab {
namespace queryc {
// The location of the current token
extern imlab::queryc::location loc;
// The input stream of the scanner
extern std::istream *in;
} // namespace queryc
} // namespace imlab
using namespace imlab::queryc;
// Work around an incompatibility in flex (at least versions
// 2.5.31 through 2.5.33): it generates code that does
// not conform to C89. See Debian bug 333231
// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.
#undef yywrap
#define yywrap() 1
// Declare the yylex function
#define YY_DECL QueryParser::symbol_type yylex(QueryParseContext& sc)
// Configure the scanner to use istreams
#define YY_INPUT(buffer, result, max_size)
result = 0;
while (true) {
int c = in->get();
if (in->eof()) break;
buffer[result++] = c;
if (result == max_size || c == 'n') break;
}
%}
%{
// ---------------------------------------------------------------------------------------------------
// Options
// ---------------------------------------------------------------------------------------------------
%}
%option noyywrap
%option nounput
%option noinput
%option batch
%option debug
%option caseless
%{
#define YY_USER_ACTION { loc.columns(yyleng); }
%%
%{
loc.step ();
%}
[ t]+ { loc.step(); }
"n" { loc.lines (yyleng); loc.step (); }
";" { return QueryParser::make_SEMICOLON(loc); }
%%
// ---------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------
// The input stream
imlab::queryc::location imlab::queryc::loc;
// The input stream of the scanner
std::istream *imlab::queryc::in = nullptr;
// Begin a scan
void imlab::queryc::QueryParseContext::beginScan(std::istream &is) {
yy_flex_debug = trace_scanning_;
in = &is;
}
// End a scan
void imlab::queryc::QueryParseContext::endScan() {
in = nullptr;
}
query_parser.y
%skeleton "lalr1.cc"
%require "3.0.4"
// ---------------------------------------------------------------------------------------------------
%defines
%define parser_class_name {QueryParser}
%define api.namespace { imlab::queryc }
%define api.value.type variant
%define api.token.constructor
%define api.token.prefix {QUERY_}
%define parse.assert
%define parse.trace
%define parse.error verbose
%locations
%param { imlab::queryc::QueryParseContext &sc }
// ---------------------------------------------------------------------------------------------------
%code requires {
#include <string>
#include <vector>
#include "imlab/queryc/query_parse_context.h"
}
// ---------------------------------------------------------------------------------------------------
%code {
imlab::queryc::QueryParser::symbol_type yylex(imlab::queryc::QueryParseContext& sc);
}
// %code {
// std::string insertTableId;
// int positionToInsert;
// }
// ---------------------------------------------------------------------------------------------------
// Token definitions -- most of them deleted
%token <int> INTEGER_VALUE "integer_value"
%token <std::string> IDENTIFIER "identifier"
// ---------------------------------------------------------------------------------------------------
// Define error function
void imlab::queryc::QueryParser::error(const location_type& l, const std::string& m) {
sc.Error(l.begin.line, l.begin.column, m);
}
// ---------------------------------------------------------------------------------------------------
In short:
What I can be sure: These two flex and bison
and other things like imlabdb.cc
are working well, if I only use one of them in the imlabdb.cc
. The conflict which I added to the top only happens, when I try to use two parser at same time.
What I want: To use the two parser at same time and avoid the naming conflicts.
Thanks!
(If I deleted to much code or is the current code not sufficient, please post. I will fix it.)
c++ database parsing bison flex-lexer
c++ database parsing bison flex-lexer
edited Nov 27 '18 at 17:34
sepp2k
293k38593609
293k38593609
asked Nov 23 '18 at 12:33
JigaoJigao
1214
1214
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Although @serge is correct about your specific issue, I will answer the question more generic.
Flex and bison create a C file with a bunch of functions and variables that are public, such as yylex
and yyparse
. This is unfortunate, if you have two parser or lexers in one program. The program does not know which yylex
and yyparse
to call. So you need to name them differently.
To do this in flex you use the option
%option prefix="foo"
This will rename all symbols that have yy prefex to foo, so foolex
. So in your case you then use one prefix for the one lexer and an other for the other.
On bison same thing, just different syntax. Depending on your version of bision you use either (new):
%define api.prefix {foo}
or (old):
%name-prefix "foo"
Which will then generate fooparse
.
For reference see the documentation:
- Flex Manual: Options
- Bison Manual: 3.8 Multiple Parsers in the Same Program
add a comment |
Both the schema (DDL) and queries (DML) are the parts of SQL language. You don't need to have two lexers/parsers but only one based on SQL grammar definitions. For example, have a look on the "YACC SQL Grammar Reference".
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446797%2fmultiply-parse-using-flex-and-bison%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Although @serge is correct about your specific issue, I will answer the question more generic.
Flex and bison create a C file with a bunch of functions and variables that are public, such as yylex
and yyparse
. This is unfortunate, if you have two parser or lexers in one program. The program does not know which yylex
and yyparse
to call. So you need to name them differently.
To do this in flex you use the option
%option prefix="foo"
This will rename all symbols that have yy prefex to foo, so foolex
. So in your case you then use one prefix for the one lexer and an other for the other.
On bison same thing, just different syntax. Depending on your version of bision you use either (new):
%define api.prefix {foo}
or (old):
%name-prefix "foo"
Which will then generate fooparse
.
For reference see the documentation:
- Flex Manual: Options
- Bison Manual: 3.8 Multiple Parsers in the Same Program
add a comment |
Although @serge is correct about your specific issue, I will answer the question more generic.
Flex and bison create a C file with a bunch of functions and variables that are public, such as yylex
and yyparse
. This is unfortunate, if you have two parser or lexers in one program. The program does not know which yylex
and yyparse
to call. So you need to name them differently.
To do this in flex you use the option
%option prefix="foo"
This will rename all symbols that have yy prefex to foo, so foolex
. So in your case you then use one prefix for the one lexer and an other for the other.
On bison same thing, just different syntax. Depending on your version of bision you use either (new):
%define api.prefix {foo}
or (old):
%name-prefix "foo"
Which will then generate fooparse
.
For reference see the documentation:
- Flex Manual: Options
- Bison Manual: 3.8 Multiple Parsers in the Same Program
add a comment |
Although @serge is correct about your specific issue, I will answer the question more generic.
Flex and bison create a C file with a bunch of functions and variables that are public, such as yylex
and yyparse
. This is unfortunate, if you have two parser or lexers in one program. The program does not know which yylex
and yyparse
to call. So you need to name them differently.
To do this in flex you use the option
%option prefix="foo"
This will rename all symbols that have yy prefex to foo, so foolex
. So in your case you then use one prefix for the one lexer and an other for the other.
On bison same thing, just different syntax. Depending on your version of bision you use either (new):
%define api.prefix {foo}
or (old):
%name-prefix "foo"
Which will then generate fooparse
.
For reference see the documentation:
- Flex Manual: Options
- Bison Manual: 3.8 Multiple Parsers in the Same Program
Although @serge is correct about your specific issue, I will answer the question more generic.
Flex and bison create a C file with a bunch of functions and variables that are public, such as yylex
and yyparse
. This is unfortunate, if you have two parser or lexers in one program. The program does not know which yylex
and yyparse
to call. So you need to name them differently.
To do this in flex you use the option
%option prefix="foo"
This will rename all symbols that have yy prefex to foo, so foolex
. So in your case you then use one prefix for the one lexer and an other for the other.
On bison same thing, just different syntax. Depending on your version of bision you use either (new):
%define api.prefix {foo}
or (old):
%name-prefix "foo"
Which will then generate fooparse
.
For reference see the documentation:
- Flex Manual: Options
- Bison Manual: 3.8 Multiple Parsers in the Same Program
answered Nov 23 '18 at 14:16
riokirioki
4,02442247
4,02442247
add a comment |
add a comment |
Both the schema (DDL) and queries (DML) are the parts of SQL language. You don't need to have two lexers/parsers but only one based on SQL grammar definitions. For example, have a look on the "YACC SQL Grammar Reference".
add a comment |
Both the schema (DDL) and queries (DML) are the parts of SQL language. You don't need to have two lexers/parsers but only one based on SQL grammar definitions. For example, have a look on the "YACC SQL Grammar Reference".
add a comment |
Both the schema (DDL) and queries (DML) are the parts of SQL language. You don't need to have two lexers/parsers but only one based on SQL grammar definitions. For example, have a look on the "YACC SQL Grammar Reference".
Both the schema (DDL) and queries (DML) are the parts of SQL language. You don't need to have two lexers/parsers but only one based on SQL grammar definitions. For example, have a look on the "YACC SQL Grammar Reference".
answered Nov 23 '18 at 13:16
sergeserge
59537
59537
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53446797%2fmultiply-parse-using-flex-and-bison%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown