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