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