X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/5ab8c47bcf5088cf420db6e03cd44bfa68e92ca0..28126202a52cda40411bc33ed795ceb4cfdd302d:/examples/variant.yy diff --git a/examples/variant.yy b/examples/variant.yy index fafb6556..39a57ba8 100644 --- a/examples/variant.yy +++ b/examples/variant.yy @@ -1,106 +1,139 @@ -/* Test file for C++ parsers using variants. - Based on an example by Michiel De Wilde . */ -%language "C++" +/* + Copyright (C) 2008-2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + %debug +%skeleton "lalr1.cc" %defines +%define parse.assert %define variant +%define lex_symbol +%locations %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::symbol_type yylex (); + + // 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 <::std::string> TEXT; +%token NUMBER; +%printer { debug_stream () << $$; } + <::std::string> <::std::list>; +%token END_OF_FILE 0; -%type text result +%type <::std::string> item; +%type <::std::list> list; %% result: - text { std::cout << $1 << std::endl; } + list { std::cout << $1 << std::endl; } ; -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()); - } +list: + /* nothing */ { /* Generates an empty string list */ } +| list item { std::swap ($$, $1); $$.push_back ($2); } +; + +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) +yy::parser::symbol_type +yylex () { - static int stage = 0; - yy::parser::token_type result; - + static int stage = -1; + ++stage; + yy::parser::location_type loc(0, stage + 1, stage + 1); switch (stage) { case 0: - yylval->build(); - yylval->as() = std::string("I have three numbers for you:"); - result = yy::parser::token::TEXT; - break; + return yy::parser::make_TEXT ("I have three numbers for you.", loc); case 1: case 2: case 3: - yylval->build(); - yylval->as() = stage; - result = yy::parser::token::NUMBER; - break; + return yy::parser::make_NUMBER (stage, loc); case 4: - yylval->build(); - yylval->as() = std::string(" and that's all!"); - result = yy::parser::token::TEXT; - break; + return yy::parser::make_TEXT ("And that's all!", loc); default: - result = yy::parser::token::END_OF_FILE; - break; + return yy::parser::make_END_OF_FILE (loc); } - - stage++; - return result; } // 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& loc, const std::string& msg) { - std::cerr << yylloc << ": " << message << std::endl; + std::cerr << loc << ": " << msg << std::endl; } int -main(int argc, char *argv[]) +main () { yy::parser p; - p.set_debug_level(!!getenv("YYDEBUG")); - p.parse(); + p.set_debug_level (!!getenv ("YYDEBUG")); + return p.parse (); } // Local Variables: