mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-27 05:03:07 +00:00
Make variant.yy more complex.
std::list cannot be copied via memcpy, they are more demanding than std::string. Use one std::list to strengthen the test. * examples/variant.yy: Use lalr1-fusion.cc, not lalr1.cc. Adjust. Create a list of strings, instead of a single large string.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -1,3 +1,13 @@
|
|||||||
|
2008-11-04 Akim Demaille <demaille@gostai.com>
|
||||||
|
|
||||||
|
Make variant.yy more complex.
|
||||||
|
std::list cannot be copied via memcpy, they are more demanding than
|
||||||
|
std::string. Use one std::list to strengthen the test.
|
||||||
|
|
||||||
|
* examples/variant.yy: Use lalr1-fusion.cc, not lalr1.cc.
|
||||||
|
Adjust.
|
||||||
|
Create a list of strings, instead of a single large string.
|
||||||
|
|
||||||
2008-11-04 Akim Demaille <demaille@gostai.com>
|
2008-11-04 Akim Demaille <demaille@gostai.com>
|
||||||
|
|
||||||
bench.pl --bench.
|
bench.pl --bench.
|
||||||
|
|||||||
@@ -1,60 +1,88 @@
|
|||||||
/* Test file for C++ parsers using variants.
|
/* Test file for C++ parsers using variants.
|
||||||
Based on an example by Michiel De Wilde <mdewilde.agilent@gmail.com>. */
|
Based on an example by Michiel De Wilde <mdewilde.agilent@gmail.com>. */
|
||||||
%language "C++"
|
|
||||||
%debug
|
%debug
|
||||||
|
%skeleton "lalr1-fusion.cc"
|
||||||
%defines
|
%defines
|
||||||
%define variant
|
%define variant
|
||||||
|
|
||||||
%code requires // *.hh
|
%code requires // *.hh
|
||||||
{
|
{
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
typedef std::list<std::string> strings_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
%code // *.cc
|
%code // *.cc
|
||||||
{
|
{
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
static yy::parser::token_type yylex(yy::parser::semantic_type* yylval);
|
// Prototype of the yylex function providing subsequent tokens.
|
||||||
|
static yy::parser::token_type yylex(yy::parser::semantic_type* yylval);
|
||||||
|
|
||||||
|
// Printing a list of strings.
|
||||||
|
// Koening look up will look into std, since that's an std::list.
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream& o, const strings_type& s)
|
||||||
|
{
|
||||||
|
std::copy(s.begin(), s.end(),
|
||||||
|
std::ostream_iterator<strings_type::value_type>(o, "\n"));
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion to string.
|
||||||
|
template <typename T>
|
||||||
|
inline
|
||||||
|
std::string
|
||||||
|
string_cast (const T& t)
|
||||||
|
{
|
||||||
|
std::ostringstream o;
|
||||||
|
o << t;
|
||||||
|
return o.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <std::string> TEXT
|
%token <std::string> TEXT;
|
||||||
%token <int> NUMBER
|
%token <int> NUMBER;
|
||||||
%printer { debug_stream() << $$; } <int> <std::string>
|
%printer { debug_stream () << $$; } <int> <std::string> <strings_type>;
|
||||||
%token END_OF_FILE 0
|
%token END_OF_FILE 0;
|
||||||
|
|
||||||
%type <std::string> text result
|
%type <std::string> item;
|
||||||
|
%type <strings_type> list;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
result:
|
result:
|
||||||
text { std::cout << $1 << std::endl; }
|
list { std::cout << $1 << std::endl; }
|
||||||
;
|
;
|
||||||
|
|
||||||
text:
|
list:
|
||||||
/* nothing */ { /* This will generate an empty string */ }
|
/* nothing */ { /* Generates an empty string list */ }
|
||||||
| text TEXT { std::swap($$,$1); $$.append($2); }
|
| list item { std::swap ($$, $1); $$.push_back ($2); }
|
||||||
| text NUMBER {
|
;
|
||||||
std::swap($$,$1);
|
|
||||||
std::ostringstream o;
|
item:
|
||||||
o << ' ' << $2;
|
TEXT { std::swap ($$, $1); }
|
||||||
$$.append(o.str());
|
| NUMBER { $$ = string_cast ($1); }
|
||||||
}
|
|
||||||
;
|
;
|
||||||
%%
|
%%
|
||||||
|
|
||||||
// The yylex function providing subsequent tokens:
|
// The yylex function providing subsequent tokens:
|
||||||
// TEXT "I have three numbers for you:"
|
// TEXT "I have three numbers for you:"
|
||||||
// NUMBER 1
|
// NUMBER 1
|
||||||
// NUMBER 2
|
// NUMBER 2
|
||||||
// NUMBER 3
|
// NUMBER 3
|
||||||
// TEXT " and that's all!"
|
// TEXT " and that's all!"
|
||||||
// END_OF_FILE
|
// END_OF_FILE
|
||||||
|
|
||||||
static
|
static
|
||||||
yy::parser::token_type
|
yy::parser::token_type
|
||||||
yylex(yy::parser::semantic_type* yylval)
|
yylex (yy::parser::semantic_type* yylval)
|
||||||
{
|
{
|
||||||
static int stage = 0;
|
static int stage = 0;
|
||||||
yy::parser::token_type result;
|
yy::parser::token_type result;
|
||||||
@@ -62,20 +90,18 @@ yylex(yy::parser::semantic_type* yylval)
|
|||||||
switch (stage)
|
switch (stage)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
yylval->build<std::string>();
|
yylval->build<std::string> () =
|
||||||
yylval->as<std::string>() = std::string("I have three numbers for you:");
|
std::string ("I have three numbers for you.");
|
||||||
result = yy::parser::token::TEXT;
|
result = yy::parser::token::TEXT;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
yylval->build<int>();
|
yylval->build<int> () = stage;
|
||||||
yylval->as<int>() = stage;
|
|
||||||
result = yy::parser::token::NUMBER;
|
result = yy::parser::token::NUMBER;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
yylval->build<std::string>();
|
yylval->build<std::string> () = std::string ("And that's all!");
|
||||||
yylval->as<std::string>() = std::string(" and that's all!");
|
|
||||||
result = yy::parser::token::TEXT;
|
result = yy::parser::token::TEXT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -89,18 +115,18 @@ yylex(yy::parser::semantic_type* yylval)
|
|||||||
|
|
||||||
// Mandatory error function
|
// Mandatory error function
|
||||||
void
|
void
|
||||||
yy::parser::error(const yy::parser::location_type& yylloc,
|
yy::parser::error (const yy::parser::location_type& yylloc,
|
||||||
const std::string& message)
|
const std::string& message)
|
||||||
{
|
{
|
||||||
std::cerr << yylloc << ": " << message << std::endl;
|
std::cerr << yylloc << ": " << message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
yy::parser p;
|
yy::parser p;
|
||||||
p.set_debug_level(!!getenv("YYDEBUG"));
|
p.set_debug_level (!!getenv ("YYDEBUG"));
|
||||||
p.parse();
|
p.parse ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|||||||
Reference in New Issue
Block a user