comparison examples/mpp/token.h @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 /*
2 * AnaGram, a System for Syntax Directed Programming
3 * C Macro preprocessor
4 * Token handling definitions
5 *
6 * Copyright 1993 Parsifal Software. All Rights Reserved.
7 *
8 * This software is provided 'as-is', without any express or implied
9 * warranty. In no event will the authors be held liable for any damages
10 * arising from the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * 2. Altered source versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source distribution.
23 */
24
25 #ifndef TOKEN_H
26 #define TOKEN_H
27
28 #include <assert.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include "charsink.h"
32 #include "strdict.h"
33
34 extern string_dictionary td;
35
36
37 // define token identification codes
38
39 enum token_id {
40 END_OF_FILE =0,
41 SPACE =' ',
42 ANDAND ='A', // "&&"
43 ANDassign, // "&="
44 ARROW, // "->"
45 CONCAT, // "##"
46 DECR, // "--"
47 DIVassign, // "/="
48 ELLIPSIS, // "..."
49 EQ, // "=="
50 ERassign, // "^="
51 GE, // ">="
52 ICR, // "++"
53 LE, // "<="
54 LS, // "<<"
55 LSassign, // "<<="
56 MODassign, // "%="
57 MINUSassign, // "-="
58 MULTassign, // "*="
59 NE, // "!="
60 ORassign, // "|="
61 OROR, // "||"
62 PLUSassign, // "+="
63 RS, // ">>"
64 RSassign, // ">>="
65 CHARACTERconstant, // character constant
66 STRINGliteral, // character string
67 HEXconstant =129,
68 OCTconstant,
69 DECconstant,
70 FLOATconstant, // real
71 NAME,
72 AUTO, // "auto"
73 BREAK, // "break"
74 CASE, // "case"
75 CHAR, // "char"
76 CONSTANT, // "const"
77 CONTINUE, // "continue"
78 DEFAULT, // "default"
79 DO, // "do"
80 DOUBLE, // "double"
81 ELSE, // "else"
82 ENUM, // "enum"
83 EXTERN, // "extern"
84 FLOAT, // "float"
85 FOR, // "for"
86 GOTO, // "goto"
87 IF, // "if"
88 INT, // "int"
89 LONG, // "long"
90 REGISTER, // "register"
91 RETURN, // "return"
92 SHORT, // "short"
93 SIGNED, // "signed"
94 SIZEOF, // "sizeof"
95 STATIC, // "static"
96 STRUCT, // "struct"
97 SWITCH, // "switch"
98 TYPEDEF, // "typedef"
99 UNION, // "union"
100 UNSIGNED, // "unsigned"
101 VOIDkey, // "void"
102 VOLATILE, // "volatile"
103 WHILE, // "while"
104 UNRECOGNIZED
105 };
106
107 struct token {
108 unsigned handle; // token dictionary index
109 token_id id; // token type
110 };
111
112 // Token sink class
113
114 class token_sink {
115 public:
116 virtual ~token_sink() {}
117 virtual token_sink &operator << (token) = 0;
118 virtual token_sink &operator << (token *) = 0;
119 friend int error(token_sink &);
120 };
121
122
123 // Token accumulator
124 // Member functions that are not inline are in token.cpp
125
126 class token_accumulator : public token_sink {
127 token *cs;
128 unsigned *xs;
129 unsigned csx;
130 unsigned xsx;
131 unsigned csmax;
132 unsigned xsmax;
133 public:
134
135 // Constructor
136
137 token_accumulator(int nc, int nx = 1);
138
139
140 // Destructor
141
142 ~token_accumulator();
143
144
145 // Reset token accumulator
146
147 friend token_accumulator &reset(token_accumulator &);
148
149
150 // Change levels
151
152 token_accumulator& operator ++(){
153 assert(xsx); // Room for another level?
154 xs[--xsx] = csx;
155 return *this;
156 }
157
158 token_accumulator& operator --() {
159 csx = xs[xsx++];
160 assert(xsx < xsmax); // Have to leave last level active
161 return *this;
162 }
163
164
165 // Push data
166
167 token_sink& operator << (token c) {
168 assert(csx < csmax); // room for data?
169 cs[csx++] = c;
170 return *this;
171 }
172
173 token_sink &operator << (token *tp);
174
175 token_sink &operator << (token_accumulator &t) {
176 assert(this != &t); // prevent disaster
177 return *this << (token *) t;
178 }
179
180 // Pop data
181
182 token_accumulator &operator >> (token &c);
183
184
185 // Access data
186
187 //token &operator [](unsigned);
188
189 operator token *() {
190 cs[csx].id = END_OF_FILE;
191 cs[csx].handle = 0;
192 return &cs[xs[xsx]];
193 }
194
195
196 // Concatenate token strings
197
198 friend token_accumulator& concat(token_accumulator &);
199
200
201 // Make permanent copy of token string
202
203 friend token *copy(token_accumulator &);
204
205
206 // Get size of token string
207
208 friend unsigned size(token_accumulator &s);
209
210 // Check for error
211
212 friend int error(token_accumulator &t);
213
214 };
215
216 inline unsigned size(token_accumulator &s) {
217 return s.csx - s.xs[s.xsx];
218 }
219
220 inline int error(token_accumulator &t) {
221 return t.csx >= t.csmax || t.xsx >= t.xsmax;
222 }
223
224
225
226 // Token Translator class
227
228 class token_translator : public token_sink {
229 character_sink *cs;
230 int space_required;
231 public:
232
233
234 // Constructor
235
236 token_translator(character_sink *sink) {
237 cs = sink;
238 space_required = 0;
239 }
240
241
242 // Accept data
243
244 token_sink &operator << (token t) {
245 if (space_required && t.id > 128) *cs << ' ';
246 *cs << td[t.handle];
247 space_required = t.id > 128;
248 return *this;
249 }
250
251 token_sink &operator << (token *tp);
252
253
254 // Check for error;
255 friend int error(token_sink &) {return 0;}
256 };
257
258 #endif