From 9718cfa902806db3134c3c883457b548e23fb4a4 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 21 Jul 2008 21:23:42 +0200 Subject: [PATCH] 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. --- ChangeLog | 10 +++++ examples/variant.yy | 94 +++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index dac58612..87c0fcf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-11-04 Akim Demaille + + 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 bench.pl --bench. diff --git a/examples/variant.yy b/examples/variant.yy index fafb6556..be43c60d 100644 --- a/examples/variant.yy +++ b/examples/variant.yy @@ -1,60 +1,88 @@ /* Test file for C++ parsers using variants. Based on an example by Michiel De Wilde . */ -%language "C++" %debug +%skeleton "lalr1-fusion.cc" %defines %define variant %code requires // *.hh { +#include #include +typedef std::list strings_type; } %code // *.cc { #include #include +#include #include -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(o, "\n")); + return o; + } + } + + // Conversion to string. + template + inline + std::string + string_cast (const T& t) + { + std::ostringstream o; + o << t; + return o.str(); + } } -%token TEXT -%token NUMBER -%printer { debug_stream() << $$; } -%token END_OF_FILE 0 +%token TEXT; +%token NUMBER; +%printer { debug_stream () << $$; } ; +%token END_OF_FILE 0; -%type text result +%type item; +%type list; %% result: - text { std::cout << $1 << std::endl; } + list { std::cout << $1 << std::endl; } +; + +list: + /* nothing */ { /* Generates an empty string list */ } +| list item { std::swap ($$, $1); $$.push_back ($2); } ; -text: - /* nothing */ { /* This will generate an empty string */ } -| text TEXT { std::swap($$,$1); $$.append($2); } -| text NUMBER { - std::swap($$,$1); - std::ostringstream o; - o << ' ' << $2; - $$.append(o.str()); - } +item: + TEXT { std::swap ($$, $1); } +| NUMBER { $$ = string_cast ($1); } ; %% // The yylex function providing subsequent tokens: -// TEXT "I have three numbers for you:" -// NUMBER 1 -// NUMBER 2 -// NUMBER 3 -// TEXT " and that's all!" +// TEXT "I have three numbers for you:" +// NUMBER 1 +// NUMBER 2 +// NUMBER 3 +// TEXT " and that's all!" // END_OF_FILE static yy::parser::token_type -yylex(yy::parser::semantic_type* yylval) +yylex (yy::parser::semantic_type* yylval) { static int stage = 0; yy::parser::token_type result; @@ -62,20 +90,18 @@ yylex(yy::parser::semantic_type* yylval) switch (stage) { case 0: - yylval->build(); - yylval->as() = std::string("I have three numbers for you:"); + yylval->build () = + std::string ("I have three numbers for you."); result = yy::parser::token::TEXT; break; case 1: case 2: case 3: - yylval->build(); - yylval->as() = stage; + yylval->build () = stage; result = yy::parser::token::NUMBER; break; case 4: - yylval->build(); - yylval->as() = std::string(" and that's all!"); + yylval->build () = std::string ("And that's all!"); result = yy::parser::token::TEXT; break; default: @@ -89,18 +115,18 @@ yylex(yy::parser::semantic_type* yylval) // Mandatory error function void -yy::parser::error(const yy::parser::location_type& yylloc, - const std::string& message) +yy::parser::error (const yy::parser::location_type& yylloc, + const std::string& message) { std::cerr << yylloc << ": " << message << std::endl; } int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { yy::parser p; - p.set_debug_level(!!getenv("YYDEBUG")); - p.parse(); + p.set_debug_level (!!getenv ("YYDEBUG")); + p.parse (); } // Local Variables: -- 2.45.2