1/* 2 Copyright (C) 2008-2015, 2018-2021 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. 16*/ 17 18%require "3.2" 19%debug 20%language "c++" 21%define api.token.constructor 22%define api.value.type variant 23%define api.location.file none 24%define parse.assert 25%locations 26 27%code requires // *.hh 28{ 29#include <string> 30#include <vector> 31typedef std::vector<std::string> strings_type; 32} 33 34%code // *.cc 35{ 36#include <iostream> 37#include <sstream> 38 39 namespace yy 40 { 41 // Prototype of the yylex function providing subsequent tokens. 42 static parser::symbol_type yylex (); 43 44 // Print a vector of strings. 45 std::ostream& 46 operator<< (std::ostream& o, const strings_type& ss) 47 { 48 o << '{'; 49 const char *sep = ""; 50 for (strings_type::const_iterator i = ss.begin (), end = ss.end (); 51 i != end; ++i) 52 { 53 o << sep << *i; 54 sep = ", "; 55 } 56 return o << '}'; 57 } 58 } 59 60 // Convert to string. 61 template <typename T> 62 std::string 63 to_string (const T& t) 64 { 65 std::ostringstream o; 66 o << t; 67 return o.str (); 68 } 69} 70 71%token <::std::string> TEXT; 72%token <int> NUMBER; 73%printer { yyo << '(' << &$$ << ") " << $$; } <*>; 74%token END_OF_FILE 0; 75 76%type <::std::string> item; 77%type <::std::vector<std::string>> list; 78 79%% 80 81result: 82 list { std::cout << $1 << '\n'; } 83; 84 85list: 86 %empty { /* Generates an empty string list */ } 87| list item { std::swap ($$, $1); $$.push_back ($2); } 88; 89 90item: 91 TEXT 92| NUMBER { $$ = to_string ($1); } 93; 94%% 95 96namespace yy 97{ 98 // Use nullptr with pre-C++11. 99#if !defined __cplusplus || __cplusplus < 201103L 100# define NULLPTR 0 101#else 102# define NULLPTR nullptr 103#endif 104 105 // The yylex function providing subsequent tokens: 106 // TEXT "I have three numbers for you." 107 // NUMBER 1 108 // NUMBER 2 109 // NUMBER 3 110 // TEXT "And that's all!" 111 // END_OF_FILE 112 113 static 114 parser::symbol_type 115 yylex () 116 { 117 static int count = 0; 118 const int stage = count; 119 ++count; 120 parser::location_type loc (NULLPTR, stage + 1, stage + 1); 121 switch (stage) 122 { 123 case 0: 124 return parser::make_TEXT ("I have three numbers for you.", loc); 125 case 1: 126 case 2: 127 case 3: 128 return parser::make_NUMBER (stage, loc); 129 case 4: 130 return parser::make_TEXT ("And that's all!", loc); 131 default: 132 return parser::make_END_OF_FILE (loc); 133 } 134 } 135 136 // Mandatory error function 137 void 138 parser::error (const parser::location_type& loc, const std::string& msg) 139 { 140 std::cerr << loc << ": " << msg << '\n'; 141 } 142} 143 144int 145main () 146{ 147 yy::parser p; 148 p.set_debug_level (!!getenv ("YYDEBUG")); 149 return p.parse (); 150} 151 152// Local Variables: 153// mode: C++ 154// End: 155