X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/5ab8c47bcf5088cf420db6e03cd44bfa68e92ca0..432ac57aaae89de7a4305dc72c5a5b716c6defc4:/examples/variant.yy?ds=sidebyside diff --git a/examples/variant.yy b/examples/variant.yy index fafb6556..d560e7dd 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.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: