]> git.saurik.com Git - bison.git/blob - examples/variant.yy
Merge branch 'maint'
[bison.git] / examples / variant.yy
1 /*
2 Copyright (C) 2008-2012 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 <http://www.gnu.org/licenses/>.
16 */
17
18 %debug
19 %skeleton "lalr1.cc"
20 %defines
21 %define parse.assert
22 %define variant
23 %define lex_symbol
24 %locations
25
26 %code requires // *.hh
27 {
28 #include <list>
29 #include <string>
30 typedef std::list<std::string> strings_type;
31 }
32
33 %code // *.cc
34 {
35 #include <algorithm>
36 #include <iostream>
37 #include <iterator>
38 #include <sstream>
39
40 // Prototype of the yylex function providing subsequent tokens.
41 static yy::parser::symbol_type yylex ();
42
43 // Printing a list of strings.
44 // Koening look up will look into std, since that's an std::list.
45 namespace std
46 {
47 std::ostream&
48 operator<< (std::ostream& o, const strings_type& s)
49 {
50 std::copy (s.begin (), s.end (),
51 std::ostream_iterator<strings_type::value_type> (o, "\n"));
52 return o;
53 }
54 }
55
56 // Conversion to string.
57 template <typename T>
58 inline
59 std::string
60 string_cast (const T& t)
61 {
62 std::ostringstream o;
63 o << t;
64 return o.str ();
65 }
66 }
67
68 %token <::std::string> TEXT;
69 %token <int> NUMBER;
70 %printer { debug_stream () << $$; }
71 <int> <::std::string> <::std::list<std::string>>;
72 %token END_OF_FILE 0;
73
74 %type <::std::string> item;
75 %type <::std::list<std::string>> list;
76
77 %%
78
79 result:
80 list { std::cout << $1 << std::endl; }
81 ;
82
83 list:
84 /* nothing */ { /* Generates an empty string list */ }
85 | list item { std::swap ($$, $1); $$.push_back ($2); }
86 ;
87
88 item:
89 TEXT { std::swap ($$, $1); }
90 | NUMBER { $$ = string_cast ($1); }
91 ;
92 %%
93
94 // The yylex function providing subsequent tokens:
95 // TEXT "I have three numbers for you:"
96 // NUMBER 1
97 // NUMBER 2
98 // NUMBER 3
99 // TEXT " and that's all!"
100 // END_OF_FILE
101
102 static
103 yy::parser::symbol_type
104 yylex ()
105 {
106 static int stage = -1;
107 ++stage;
108 yy::parser::location_type loc(0, stage + 1, stage + 1);
109 switch (stage)
110 {
111 case 0:
112 return yy::parser::make_TEXT ("I have three numbers for you.", loc);
113 case 1:
114 case 2:
115 case 3:
116 return yy::parser::make_NUMBER (stage, loc);
117 case 4:
118 return yy::parser::make_TEXT ("And that's all!", loc);
119 default:
120 return yy::parser::make_END_OF_FILE (loc);
121 }
122 }
123
124 // Mandatory error function
125 void
126 yy::parser::error (const yy::parser::location_type& loc, const std::string& msg)
127 {
128 std::cerr << loc << ": " << msg << std::endl;
129 }
130
131 int
132 main ()
133 {
134 yy::parser p;
135 p.set_debug_level (!!getenv ("YYDEBUG"));
136 return p.parse ();
137 }
138
139 // Local Variables:
140 // mode: C++
141 // End: