summaryrefslogtreecommitdiffabout
path: root/lib
Unidiff
Diffstat (limited to 'lib') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/sitecing_parser.ll159
1 files changed, 81 insertions, 78 deletions
diff --git a/lib/sitecing_parser.ll b/lib/sitecing_parser.ll
index 8ba8673..9514ce4 100644
--- a/lib/sitecing_parser.ll
+++ b/lib/sitecing_parser.ll
@@ -1,639 +1,642 @@
1%{ 1%{
2 /* 2 /*
3 * XXX: I have a strong feeling that this parser should be completely rewritten. 3 * XXX: I have a strong feeling that this parser should be completely rewritten.
4 */ 4 */
5#include <iostream> 5#include <iostream>
6#include <fstream> 6#include <fstream>
7#include <cassert> 7#include <cassert>
8#include <stdexcept> 8#include <stdexcept>
9using namespace std; 9using namespace std;
10#include "sitecing/sitecing_util.h" 10#include "sitecing/sitecing_util.h"
11#include "sitecing/sitecing_exception.h" 11#include "sitecing/sitecing_exception.h"
12using namespace sitecing; 12using namespace sitecing;
13#define sitecing_parser_flexlexer_once 13#define sitecing_parser_flexlexer_once
14#include "sitecing/sitecing_parser.h" 14#include "sitecing/sitecing_parser.h"
15#include "sitecing/sitecing_enflesher.h" 15#include "sitecing/sitecing_enflesher.h"
16#undef yyFlexLexer 16#undef yyFlexLexer
17#define yyFlexLexer sitecing_parserFlexLexer 17#define yyFlexLexer sitecing_parserFlexLexer
18%} 18%}
19%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING 19%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING
20%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT 20%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT
21%x IMPORTLINE IMPORTCOMPONENT 21%x IMPORTLINE IMPORTCOMPONENT
22%x IMPORTTYPELINE IMPORTTYPECOMPONENT 22%x IMPORTTYPELINE IMPORTTYPECOMPONENT
23%x DERIVELINE DERIVECOMPONENT 23%x DERIVELINE DERIVECOMPONENT
24%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS 24%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS
25%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK 25%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK
26%x PRAGMALINE 26%x PRAGMALINE
27%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno 27%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno
28 28
29 WHITESPACE[ \t] 29 WHITESPACE[ \t]
30 ID [A-Za-z_][A-Za-z0-9_]* 30 ID [A-Za-z_][A-Za-z0-9_]*
31 NOIDCHAR[^A-Za-z0-9_] 31 NOIDCHAR[^A-Za-z0-9_]
32 32
33%% 33%%
34 34
35<INITIAL>{ 35<INITIAL>{
36 ^\%\%class{WHITESPACE}+{ 36 ^\%\%class{WHITESPACE}+{
37 // TODO: signal error if we already have class name acquired from source. 37 // TODO: signal error if we already have class name acquired from source.
38 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace)); 38 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace));
39 BEGIN(CLASSLINE); 39 BEGIN(CLASSLINE);
40 } 40 }
41 ^\%\%decl{WHITESPACE}+{ 41 ^\%\%decl{WHITESPACE}+{
42 modi.push_front(modus_operandi(0)); 42 modi.push_front(modus_operandi(0));
43 anchor(); 43 anchor();
44 BEGIN(DECLLINE); 44 BEGIN(DECLLINE);
45 } 45 }
46 ^\%\%impl{WHITESPACE}+{ 46 ^\%\%impl{WHITESPACE}+{
47 modi.push_front(modus_operandi(0)); 47 modi.push_front(modus_operandi(0));
48 anchor(); 48 anchor();
49 BEGIN(IMPLLINE); 49 BEGIN(IMPLLINE);
50 } 50 }
51 \<\%decl\> { 51 \<\%decl\> {
52 modi.push_front(modus_operandi(0)); 52 modi.push_front(modus_operandi(0));
53 anchor(); 53 anchor();
54 BEGIN(DECLBLOCK); 54 BEGIN(DECLBLOCK);
55 } 55 }
56 \<\%impl\> { 56 \<\%impl\> {
57 modi.push_front(modus_operandi(0)); 57 modi.push_front(modus_operandi(0));
58 anchor(); 58 anchor();
59 BEGIN(IMPLBLOCK); 59 BEGIN(IMPLBLOCK);
60 } 60 }
61 ^\%\%var{WHITESPACE}+{ 61 ^\%\%var{WHITESPACE}+{
62 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 62 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
63 anchor(); 63 anchor();
64 BEGIN(VARLINE); 64 BEGIN(VARLINE);
65 } 65 }
66 ^\%\%import{WHITESPACE}+{ 66 ^\%\%import{WHITESPACE}+{
67 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 67 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
68 BEGIN(IMPORTLINE); 68 BEGIN(IMPORTLINE);
69 } 69 }
70 ^\%\%import_type{WHITESPACE}+ { 70 ^\%\%import_type{WHITESPACE}+ {
71 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 71 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
72 BEGIN(IMPORTTYPELINE); 72 BEGIN(IMPORTTYPELINE);
73 } 73 }
74 ^\%\%derive{WHITESPACE}+{ 74 ^\%\%derive{WHITESPACE}+{
75 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 75 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
76 BEGIN(DERIVELINE); 76 BEGIN(DERIVELINE);
77 } 77 }
78 \<\%constructor\>{ 78 \<\%constructor\>{
79 modi.push_front(modus_operandi()); 79 modi.push_front(modus_operandi());
80 anchor(); 80 anchor();
81 BEGIN(CONSTRUCTOR); 81 BEGIN(CONSTRUCTOR);
82 } 82 }
83 \<\%destructor\>{ 83 \<\%destructor\>{
84 modi.push_front(modus_operandi()); 84 modi.push_front(modus_operandi());
85 anchor(); 85 anchor();
86 BEGIN(DESTRUCTOR); 86 BEGIN(DESTRUCTOR);
87 } 87 }
88 \<\%codemethod{WHITESPACE}+{ 88 \<\%codemethod{WHITESPACE}+{
89 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 89 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
90 anchor(); 90 anchor();
91 BEGIN(CODEMETHODLINE); 91 BEGIN(CODEMETHODLINE);
92 } 92 }
93 \<\%method{WHITESPACE}+ { 93 \<\%method{WHITESPACE}+ {
94 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 94 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
95 anchor(); 95 anchor();
96 BEGIN(METHODLINE); 96 BEGIN(METHODLINE);
97 } 97 }
98 ^\%\%pragma{WHITESPACE}+{ 98 ^\%\%pragma{WHITESPACE}+{
99 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 99 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
100 BEGIN(PRAGMALINE); 100 BEGIN(PRAGMALINE);
101 } 101 }
102 <<EOF>>{ 102 <<EOF>>{
103 assert(modi.size()==1); 103 assert(modi.size()==1);
104 M().modify(modus_operandi::modus_preop); 104 M().modify(modus_operandi::modus_preop);
105 LexerOutput(";",1); 105 LexerOutput(";",1);
106 return 0; 106 return 0;
107 } 107 }
108} 108}
109 <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno()); 109 <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno());
110 110
111<CODEBLOCK,CODEMETHODBLOCK>{ 111<CODEBLOCK,CODEMETHODBLOCK>{
112 "<%output>"{ 112 "<%output>"{
113 anchor(); 113 anchor();
114 yy_push_state(OUTPUTBLOCK); 114 yy_push_state(OUTPUTBLOCK);
115 } 115 }
116} 116}
117 117
118<PRAGMALINE>{ 118<PRAGMALINE>{
119 {WHITESPACE}+{ 119 {WHITESPACE}+{
120 modus_operandi& m = M(); 120 modus_operandi& m = M();
121 if(!m.output.empty()) { 121 if(!m.output.empty()) {
122 string::size_type eq = m.output.find('='); 122 string::size_type eq = m.output.find('=');
123 if(eq==string::npos) { 123 if(eq==string::npos) {
124 pragmas[m.output]=m.output; 124 pragmas[m.output]=m.output;
125 }else{ 125 }else{
126 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); 126 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1);
127 } 127 }
128 m.output.erase(); 128 m.output.erase();
129 } 129 }
130 } 130 }
131 \n { 131 \n {
132 modus_operandi& m = M(); 132 modus_operandi& m = M();
133 if(!m.output.empty()) { 133 if(!m.output.empty()) {
134 string::size_type eq = m.output.find('='); 134 string::size_type eq = m.output.find('=');
135 if(eq==string::npos) { 135 if(eq==string::npos) {
136 pragmas[m.output]=m.output; 136 pragmas[m.output]=m.output;
137 }else{ 137 }else{
138 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); 138 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1);
139 } 139 }
140 m.output.erase(); 140 m.output.erase();
141 } 141 }
142 modi.pop_front(); 142 modi.pop_front();
143 BEGIN(INITIAL); 143 BEGIN(INITIAL);
144 anchor(); 144 anchor();
145 } 145 }
146} 146}
147 147
148<METHODLINE>{ 148<METHODLINE>{
149 {WHITESPACE}+{ 149 {WHITESPACE}+{
150 modus_operandi& m = modi.front(); 150 modus_operandi& m = M();
151 if(!m.output.empty()) { 151 if(!m.output.empty()) {
152 if(!m._lastid.empty()) { 152 if(!m._lastid.empty()) {
153 if(!m._type.empty()) m._type += ' '; 153 if(!m._type.empty()) m._type += ' ';
154 m._type += m._lastid; 154 m._type += m._lastid;
155 } 155 }
156 m._lastid = m.output; 156 m._lastid = m.output;
157 m.output.clear(); 157 m.output.clear();
158 } 158 }
159 } 159 }
160 \*{ 160 \*{
161 modus_operandi& m = modi.front(); 161 modus_operandi& m = M();
162 ECHO; 162 ECHO;
163 if(!m._lastid.empty()) { 163 if(!m._lastid.empty()) {
164 if(!m._type.empty()) m._type += ' '; 164 if(!m._type.empty()) m._type += ' ';
165 m._type += m._lastid; 165 m._type += m._lastid;
166 } 166 }
167 m._lastid = m.output; 167 m._lastid = m.output;
168 m.output.clear(); 168 m.output.clear();
169 } 169 }
170 \({ 170 \({
171 modus_operandi& m = modi.front(); 171 modus_operandi& m = M();
172 if(m.output.empty()) { 172 if(m.output.empty()) {
173 m._name=m._lastid; 173 m._name=m._lastid;
174 }else{ 174 }else{
175 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... 175 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy...
176 if(!m._type.empty()) m._type += ' '; 176 if(!m._type.empty()) m._type += ' ';
177 m._type += m._lastid; 177 m._type += m._lastid;
178 } 178 }
179 m._name = m.output; 179 m._name = m.output;
180 m.output.clear(); 180 m.output.clear();
181 } 181 }
182 ECHO; 182 ECHO;
183 BEGIN(METHODARGS); 183 BEGIN(METHODARGS);
184 } 184 }
185} 185}
186<METHODARGS>{ 186<METHODARGS>{
187 \%\>{ 187 \%\>{
188 modus_operandi& m = modi.front(); 188 modus_operandi& m = M();
189 m._args = m.output; 189 m._args = m.output;
190 m.output.clear(); 190 m.output.clear();
191 anchor(); 191 anchor();
192 BEGIN(METHODBLOCK); 192 BEGIN(METHODBLOCK);
193 } 193 }
194} 194}
195 195
196<INITIAL,METHODBLOCK,OUTPUTBLOCK>{ 196<INITIAL,METHODBLOCK,OUTPUTBLOCK>{
197 \<\%{WHITESPACE}+{ 197 \<\%{WHITESPACE}+{
198 M().modify(modus_operandi::modus_postop); 198 M().modify(modus_operandi::modus_postop);
199 anchor(); 199 anchor();
200 LexerOutput("(",1); 200 LexerOutput("(",1);
201 yy_push_state(INLINE); 201 yy_push_state(INLINE);
202 } 202 }
203 ^\%{WHITESPACE}{ 203 ^\%{WHITESPACE}{
204 M().modify(modus_operandi::modus_code); 204 M().modify(modus_operandi::modus_code);
205 anchor(); 205 anchor();
206 yy_push_state(CODELINE); 206 yy_push_state(CODELINE);
207 } 207 }
208 \<\%code\>{ 208 \<\%code\>{
209 M().modify(modus_operandi::modus_code); 209 M().modify(modus_operandi::modus_code);
210 anchor(); 210 anchor();
211 yy_push_state(CODEBLOCK); 211 yy_push_state(CODEBLOCK);
212 } 212 }
213 "</%output>" { 213 "</%output>" {
214 if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno()); 214 if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno());
215 M().modify(modus_operandi::modus_code); 215 M().modify(modus_operandi::modus_code);
216 anchor(); 216 anchor();
217 yy_pop_state(); 217 yy_pop_state();
218 } 218 }
219} 219}
220 220
221 <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state(); 221 <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state();
222 <CODELINE>\nyy_pop_state(); 222 <CODELINE>\nyy_pop_state();
223 223
224<CODEMETHODLINE>{ 224<CODEMETHODLINE>{
225 {WHITESPACE}+{ 225 {WHITESPACE}+{
226 modus_operandi& m = modi.front(); 226 modus_operandi& m = M();
227 if(!m.output.empty()) { 227 if(!m.output.empty()) {
228 if(!m._lastid.empty()) { 228 if(!m._lastid.empty()) {
229 if(!m._type.empty()) m._type += ' '; 229 if(!m._type.empty()) m._type += ' ';
230 m._type += m._lastid; 230 m._type += m._lastid;
231 } 231 }
232 m._lastid = m.output; 232 m._lastid = m.output;
233 m.output.clear(); 233 m.output.clear();
234 } 234 }
235 } 235 }
236 \*{ 236 \*{
237 modus_operandi& m = modi.front(); 237 modus_operandi& m = M();
238 ECHO; 238 ECHO;
239 if(!m._lastid.empty()) { 239 if(!m._lastid.empty()) {
240 if(!m._type.empty()) m._type += ' '; 240 if(!m._type.empty()) m._type += ' ';
241 m._type += m._lastid; 241 m._type += m._lastid;
242 } 242 }
243 m._lastid = m.output; 243 m._lastid = m.output;
244 m.output.clear(); 244 m.output.clear();
245 } 245 }
246 \({ 246 \({
247 modus_operandi& m = modi.front(); 247 modus_operandi& m = M();
248 if(m.output.empty()) { 248 if(m.output.empty()) {
249 m._name=m._lastid; 249 m._name=m._lastid;
250 }else{ 250 }else{
251 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... 251 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy...
252 if(!m._type.empty()) m._type += ' '; 252 if(!m._type.empty()) m._type += ' ';
253 m._type += m._lastid; 253 m._type += m._lastid;
254 } 254 }
255 m._name = m.output; 255 m._name = m.output;
256 m.output.clear(); 256 m.output.clear();
257 } 257 }
258 ECHO; 258 ECHO;
259 BEGIN(CODEMETHODARGS); 259 BEGIN(CODEMETHODARGS);
260 } 260 }
261} 261}
262<CODEMETHODARGS>{ 262<CODEMETHODARGS>{
263 \%\>{ 263 \%\>{
264 modus_operandi& m = modi.front(); 264 modus_operandi& m = M();
265 m._args = m.output; 265 m._args = m.output;
266 m.output.clear(); 266 m.output.clear();
267 m.flags=0; 267 m.flags=0;
268 anchor(); 268 anchor();
269 BEGIN(CODEMETHODBLOCK); 269 BEGIN(CODEMETHODBLOCK);
270 } 270 }
271} 271}
272 272
273<IMPORTLINE>{ 273<IMPORTLINE>{
274 {WHITESPACE}+{ } 274 {WHITESPACE}+{ }
275 {ID}{ 275 {ID}{
276 if(!modi.front()._name.empty()) 276 modus_operandi& m = M();
277 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 277 if(!m._name.empty())
278 modi.front()._name = yytext; 278 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
279 } 279 m._name = yytext;
280 }
280 \= { 281 \= {
281 modi.front().output.clear(); 282 M().output.clear();
282 BEGIN(IMPORTCOMPONENT); 283 BEGIN(IMPORTCOMPONENT);
283 } 284 }
284} 285}
285<IMPORTCOMPONENT>{ 286<IMPORTCOMPONENT>{
286 {WHITESPACE}+{ } 287 {WHITESPACE}+{ }
287 \n{ 288 \n{
288 modus_operandi& m = M(); 289 modus_operandi& m = M();
289 string::size_type t = m.output.find_first_not_of(" \t"); 290 string::size_type t = m.output.find_first_not_of(" \t");
290 if(t!=string::npos) 291 if(t!=string::npos)
291 m.output.erase(0,t); 292 m.output.erase(0,t);
292 t = m.output.find_last_not_of(" \t;"); 293 t = m.output.find_last_not_of(" \t;");
293 if(t!=string::npos) 294 if(t!=string::npos)
294 m.output.erase(t+1); 295 m.output.erase(t+1);
295 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 296 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
296 m.output.erase(0,1); 297 m.output.erase(0,1);
297 m.output.erase(m.output.length()-1); 298 m.output.erase(m.output.length()-1);
298 } 299 }
299 string c = combine_path(component_basename,m.output); 300 string c = combine_path(component_basename,m.output);
300 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true)); 301 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true));
301 modi.pop_front(); 302 modi.pop_front();
302 BEGIN(INITIAL); 303 BEGIN(INITIAL);
303 } 304 }
304} 305}
305 306
306<IMPORTTYPELINE>{ 307<IMPORTTYPELINE>{
307 {WHITESPACE}+{ } 308 {WHITESPACE}+{ }
308 {ID}{ 309 {ID}{
309 if(!modi.front()._name.empty()) 310 modus_operandi& m = M();
310 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 311 if(!m._name.empty())
311 modi.front()._name = yytext; 312 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
312 } 313 m._name = yytext;
314 }
313 \= { 315 \= {
314 modi.front().output.clear(); 316 M().output.clear();
315 BEGIN(IMPORTTYPECOMPONENT); 317 BEGIN(IMPORTTYPECOMPONENT);
316 } 318 }
317} 319}
318<IMPORTTYPECOMPONENT>{ 320<IMPORTTYPECOMPONENT>{
319 {WHITESPACE}+{ } 321 {WHITESPACE}+{ }
320 \n{ 322 \n{
321 modus_operandi& m = M(); 323 modus_operandi& m = M();
322 string::size_type t = m.output.find_first_not_of(" \t"); 324 string::size_type t = m.output.find_first_not_of(" \t");
323 if(t!=string::npos) 325 if(t!=string::npos)
324 m.output.erase(0,t); 326 m.output.erase(0,t);
325 t = m.output.find_last_not_of(" \t;"); 327 t = m.output.find_last_not_of(" \t;");
326 if(t!=string::npos) 328 if(t!=string::npos)
327 m.output.erase(t+1); 329 m.output.erase(t+1);
328 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 330 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
329 m.output.erase(0,1); 331 m.output.erase(0,1);
330 m.output.erase(m.output.length()-1); 332 m.output.erase(m.output.length()-1);
331 } 333 }
332 string c = combine_path(component_basename,m.output); 334 string c = combine_path(component_basename,m.output);
333 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true)); 335 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true));
334 modi.pop_front(); 336 modi.pop_front();
335 BEGIN(INITIAL); 337 BEGIN(INITIAL);
336 } 338 }
337} 339}
338 340
339<DERIVELINE>{ 341<DERIVELINE>{
340 {WHITESPACE}+{ } 342 {WHITESPACE}+{ }
341 {ID}{ 343 {ID}{
342 if(!modi.front()._name.empty()) 344 modus_operandi& m = M();
343 throw preprocessor_error(CODEPOINT,"syntax_error",lineno()); 345 if(!m._name.empty())
344 modi.front()._name = yytext; 346 throw preprocessor_error(CODEPOINT,"syntax_error",lineno());
345 } 347 m._name = yytext;
348 }
346 \= { 349 \= {
347 modi.front().output.clear(); 350 M().output.clear();
348 BEGIN(DERIVECOMPONENT); 351 BEGIN(DERIVECOMPONENT);
349 } 352 }
350} 353}
351<DERIVECOMPONENT>{ 354<DERIVECOMPONENT>{
352 {WHITESPACE}+{ } 355 {WHITESPACE}+{ }
353 \n { 356 \n {
354 modus_operandi& m = M(); 357 modus_operandi& m = M();
355 string::size_type t = m.output.find_first_not_of(" \t"); 358 string::size_type t = m.output.find_first_not_of(" \t");
356 if(t!=string::npos) 359 if(t!=string::npos)
357 m.output.erase(0,t); 360 m.output.erase(0,t);
358 t = m.output.find_last_not_of(" \t;"); 361 t = m.output.find_last_not_of(" \t;");
359 if(t!=string::npos) 362 if(t!=string::npos)
360 m.output.erase(t+1); 363 m.output.erase(t+1);
361 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 364 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
362 m.output.erase(0,1); 365 m.output.erase(0,1);
363 m.output.erase(m.output.length()-1); 366 m.output.erase(m.output.length()-1);
364 } 367 }
365 string c = combine_path(component_basename,m.output); 368 string c = combine_path(component_basename,m.output);
366 ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash))); 369 ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash)));
367 modi.pop_front(); 370 modi.pop_front();
368 BEGIN(INITIAL); 371 BEGIN(INITIAL);
369 } 372 }
370} 373}
371 374
372<VARLINE>{ 375<VARLINE>{
373 {WHITESPACE}+{ 376 {WHITESPACE}+{
374 modus_operandi& m = modi.front(); 377 modus_operandi& m = M();
375 if(!m.output.empty()) { 378 if(!m.output.empty()) {
376 if(!m._lastid.empty()) { 379 if(!m._lastid.empty()) {
377 if(!m._type.empty()) m._type += ' '; 380 if(!m._type.empty()) m._type += ' ';
378 m._type += m._lastid; 381 m._type += m._lastid;
379 } 382 }
380 m._lastid = m.output; 383 m._lastid = m.output;
381 m.output.clear(); 384 m.output.clear();
382 } 385 }
383 } 386 }
384 \*{ 387 \*{
385 modus_operandi& m = modi.front(); 388 modus_operandi& m = M();
386 ECHO; 389 ECHO;
387 if(!m._lastid.empty()) { 390 if(!m._lastid.empty()) {
388 if(!m._type.empty()) m._type += ' '; 391 if(!m._type.empty()) m._type += ' ';
389 m._type += m._lastid; 392 m._type += m._lastid;
390 } 393 }
391 m._lastid = m.output; 394 m._lastid = m.output;
392 m.output.clear(); 395 m.output.clear();
393 } 396 }
394 \;|\n|\={ 397 \;|\n|\={
395 modus_operandi& m = modi.front(); 398 modus_operandi& m = M();
396 if(m.output.empty()) { 399 if(m.output.empty()) {
397 m._name=m._lastid; 400 m._name=m._lastid;
398 }else{ 401 }else{
399 if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe? 402 if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe?
400 if(!m._type.empty()) m._type += ' '; 403 if(!m._type.empty()) m._type += ' ';
401 m._type += m._lastid; 404 m._type += m._lastid;
402 } 405 }
403 m._name=m.output; 406 m._name=m.output;
404 m.output.clear(); 407 m.output.clear();
405 } 408 }
406 BEGIN(VARINIT); 409 BEGIN(VARINIT);
407 if(*yytext!='=') 410 if(*yytext!='=')
408 unput('\n'); 411 unput('\n');
409 } 412 }
410} 413}
411<VARINIT>{ 414<VARINIT>{
412 \n{ 415 \n{
413 modus_operandi& m = modi.front(); 416 modus_operandi& m = M();
414 string::size_type t = m.output.find_first_not_of(" \t"); 417 string::size_type t = m.output.find_first_not_of(" \t");
415 if(t!=string::npos) 418 if(t!=string::npos)
416 m.output.erase(0,t); 419 m.output.erase(0,t);
417 t = m.output.find_last_not_of(" \t;"); 420 t = m.output.find_last_not_of(" \t;");
418 if(t!=string::npos) 421 if(t!=string::npos)
419 m.output.erase(t+1); 422 m.output.erase(t+1);
420 member_variables.push_back(member_variable(m._type,m._name,m.output)); 423 member_variables.push_back(member_variable(m._type,m._name,m.output));
421 if(!m.output.empty()) 424 if(!m.output.empty())
422 have_initializers=true; 425 have_initializers=true;
423 modi.pop_front(); 426 modi.pop_front();
424 BEGIN(INITIAL); 427 BEGIN(INITIAL);
425 } 428 }
426} 429}
427 <DECLLINE>\n{ 430 <DECLLINE>\n{
428 ECHO; 431 ECHO;
429 decl += modi.front().output; 432 decl += M().output;
430 modi.pop_front(); 433 modi.pop_front();
431 BEGIN(INITIAL); 434 BEGIN(INITIAL);
432} 435}
433 <IMPLLINE>\n{ 436 <IMPLLINE>\n{
434 ECHO; 437 ECHO;
435 impl += modi.front().output; 438 impl += M().output;
436 modi.pop_front(); 439 modi.pop_front();
437 BEGIN(INITIAL); 440 BEGIN(INITIAL);
438} 441}
439 <CLASSLINE>\n{ 442 <CLASSLINE>\n{
440 class_name = modi.front().output; 443 class_name = M().output;
441 modi.pop_front(); 444 modi.pop_front();
442 BEGIN(INITIAL); 445 BEGIN(INITIAL);
443} 446}
444<CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK,PRAGMALINE>{ 447<CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK,PRAGMALINE>{
445 "/*"{ 448 "/*"{
446 yy_push_state(SLASHSTAR_COMMENT); 449 yy_push_state(SLASHSTAR_COMMENT);
447 if(!M().devour_comments()) { 450 if(!M().devour_comments()) {
448 ECHO; 451 ECHO;
449 } 452 }
450 } 453 }
451 "//"{ 454 "//"{
452 yy_push_state(SLASHSLASH_COMMENT); 455 yy_push_state(SLASHSLASH_COMMENT);
453 if(!M().devour_comments()) { 456 if(!M().devour_comments()) {
454 ECHO; 457 ECHO;
455 } 458 }
456 } 459 }
457 \" { 460 \" {
458 yy_push_state(STRING); 461 yy_push_state(STRING);
459 ECHO; 462 ECHO;
460 } 463 }
461 \'\\.\'{ 464 \'\\.\'{
462 ECHO; 465 ECHO;
463 } 466 }
464} 467}
465 468
466<INITIAL,METHODBLOCK,OUTPUTBLOCK>{ 469<INITIAL,METHODBLOCK,OUTPUTBLOCK>{
467 \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2); 470 \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2);
468 \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2); 471 \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2);
469 \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2); 472 \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2);
470 \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2); 473 \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2);
471 \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2); 474 \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2);
472 \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2); 475 \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2);
473 .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; 476 .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO;
474 {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; 477 {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO;
475} 478}
476 479
477<DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{ 480<DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{
478 \<\/\%decl\>{ 481 \<\/\%decl\>{
479 if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 482 if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
480 decl += modi.front().output; 483 decl += M().output;
481 modi.pop_front(); 484 modi.pop_front();
482 BEGIN(INITIAL); 485 BEGIN(INITIAL);
483 } 486 }
484 \<\/\%impl\>{ 487 \<\/\%impl\>{
485 if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 488 if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
486 impl += modi.front().output; 489 impl += M().output;
487 modi.pop_front(); 490 modi.pop_front();
488 BEGIN(INITIAL); 491 BEGIN(INITIAL);
489 } 492 }
490 \<\/\%constructor\>{ 493 \<\/\%constructor\>{
491 if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 494 if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
492 member_functions.push_back(member_function("","","",modi.front().output)); 495 member_functions.push_back(member_function("","","",M().output));
493 have_constructor = true; 496 have_constructor = true;
494 modi.pop_front(); 497 modi.pop_front();
495 BEGIN(INITIAL); 498 BEGIN(INITIAL);
496 } 499 }
497 \<\/\%destructor\>{ 500 \<\/\%destructor\>{
498 if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 501 if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
499 member_functions.push_back(member_function("","~","",modi.front().output)); 502 member_functions.push_back(member_function("","~","",M().output));
500 modi.pop_front(); 503 modi.pop_front();
501 BEGIN(INITIAL); 504 BEGIN(INITIAL);
502 } 505 }
503 \<\/\%codemethod\>{ 506 \<\/\%codemethod\>{
504 if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 507 if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
505 modus_operandi& m = modi.front(); 508 modus_operandi& m = M();
506 member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); 509 member_functions.push_back(member_function(m._type,m._name,m._args,m.output));
507 modi.pop_front(); 510 modi.pop_front();
508 BEGIN(INITIAL); 511 BEGIN(INITIAL);
509 } 512 }
510 \<\/%method\> { 513 \<\/%method\> {
511 if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 514 if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
512 modus_operandi& m = modi.front(); 515 modus_operandi& m = M();
513 m.modify(modus_operandi::modus_code); 516 m.modify(modus_operandi::modus_code);
514 member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); 517 member_functions.push_back(member_function(m._type,m._name,m._args,m.output));
515 modi.pop_front(); 518 modi.pop_front();
516 BEGIN(INITIAL); 519 BEGIN(INITIAL);
517 } 520 }
518 \<\/%code\> { 521 \<\/%code\> {
519 if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 522 if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
520 yy_pop_state(); 523 yy_pop_state();
521 } 524 }
522 \n ECHO; 525 \n ECHO;
523} 526}
524 527
525<SLASHSTAR_COMMENT>{ 528<SLASHSTAR_COMMENT>{
526 "*/"{ 529 "*/"{
527 if(!M().devour_comments()) { 530 if(!M().devour_comments()) {
528 ECHO; 531 ECHO;
529 } 532 }
530 yy_pop_state(); 533 yy_pop_state();
531 unput(' '); 534 unput(' ');
532 } 535 }
533 \n{ 536 \n{
534 if(!M().devour_comments()) { 537 if(!M().devour_comments()) {
535 ECHO; 538 ECHO;
536 } 539 }
537 } 540 }
538} 541}
539<SLASHSLASH_COMMENT>{ 542<SLASHSLASH_COMMENT>{
540 \n{ 543 \n{
541 if(!M().devour_comments()) { 544 if(!M().devour_comments()) {
542 ECHO; 545 ECHO;
543 } 546 }
544 yy_pop_state(); 547 yy_pop_state();
545 if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK) 548 if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK)
546 unput('\n'); 549 unput('\n');
547 } 550 }
548} 551}
549 <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{ 552 <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{
550 if(!M().devour_comments()) { 553 if(!M().devour_comments()) {
551 ECHO; 554 ECHO;
552 } 555 }
553} 556}
554<STRING>{ 557<STRING>{
555 \\.ECHO; 558 \\.ECHO;
556 \"ECHO; yy_pop_state(); 559 \"ECHO; yy_pop_state();
557 .ECHO; 560 .ECHO;
558} 561}
559 562
560 {WHITESPACE}+{ 563 {WHITESPACE}+{
561 if(!(M().flags&modus_operandi::flag_devour_whitespace)) { 564 if(!(M().flags&modus_operandi::flag_devour_whitespace)) {
562 ECHO; 565 ECHO;
563 } 566 }
564} 567}
565 568
566%% 569%%
567 570
568sitecing_parser::sitecing_parser(component_factory& f) 571sitecing_parser::sitecing_parser(component_factory& f)
569 : factory(f), have_initializers(false), have_constructor(false), 572 : factory(f), have_initializers(false), have_constructor(false),
570 base_class("sitecing::cgi_component"), 573 base_class("sitecing::cgi_component"),
571 base_header("sitecing/cgi_component.h"), 574 base_header("sitecing/cgi_component.h"),
572 skeleton(__SC_DEFAULT_SKELETON) { 575 skeleton(__SC_DEFAULT_SKELETON) {
573 } 576 }
574 577
575void sitecing_parser::preprocess(const string& in) { 578void sitecing_parser::preprocess(const string& in) {
576 ifstream ifs(in.c_str(),ios::in); 579 ifstream ifs(in.c_str(),ios::in);
577 if(!ifs.good()) 580 if(!ifs.good())
578 throw preprocessor_error(CODEPOINT,"failed to open input file"); 581 throw preprocessor_error(CODEPOINT,"failed to open input file");
579 input_file = in; 582 input_file = in;
580 modi.push_front(modus_operandi(0)); 583 modi.push_front(modus_operandi(0));
581 switch_streams(&ifs,NULL); 584 switch_streams(&ifs,NULL);
582 if(yylex()) 585 if(yylex())
583 throw preprocessor_error(CODEPOINT,"unknown error"); 586 throw preprocessor_error(CODEPOINT,"unknown error");
584 pragmas_t::const_iterator mp = pragmas.find("main"); 587 pragmas_t::const_iterator mp = pragmas.find("main");
585 if(mp==pragmas.end()) { 588 if(mp==pragmas.end()) {
586 member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output)); 589 member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output));
587 }else{ 590 }else{
588 member_functions.push_back( 591 member_functions.push_back(
589 member_function( 592 member_function(
590 "void","main","(int _magic,va_list _args)", 593 "void","main","(int _magic,va_list _args)",
591 mp->second+"::main(_magic,_args);" 594 mp->second+"::main(_magic,_args);"
592 ) 595 )
593 ); 596 );
594 } 597 }
595 if(have_initializers && !have_constructor) 598 if(have_initializers && !have_constructor)
596 member_functions.push_back(member_function("","","","")); 599 member_functions.push_back(member_function("","","",""));
597 sitecing_enflesher enflesher(*this); 600 sitecing_enflesher enflesher(*this);
598 enflesher.enflesh(); 601 enflesher.enflesh();
599} 602}
600 603
601void sitecing_parser::LexerOutput(const char* buf,int size) { 604void sitecing_parser::LexerOutput(const char* buf,int size) {
602 assert(modi.size()); 605 assert(modi.size());
603 M().output.append(buf,size); 606 M().output.append(buf,size);
604} 607}
605 608
606static const char *modus_transitions 609static const char *modus_transitions
607 [sitecing_parser::modus_operandi::modi] 610 [sitecing_parser::modus_operandi::modi]
608 [sitecing_parser::modus_operandi::modi] = { 611 [sitecing_parser::modus_operandi::modi] = {
609// To: 612// To:
610// code preop postop text From: 613// code preop postop text From:
611 { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code 614 { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code
612 { ";", "", "<<", "<<\"" }, // preop 615 { ";", "", "<<", "<<\"" }, // preop
613 { NULL, NULL, "", "\"" }, // postop 616 { NULL, NULL, "", "\"" }, // postop
614 { "\";", "\"", "\"<<", "" } // text 617 { "\";", "\"", "\"<<", "" } // text
615}; 618};
616 619
617void sitecing_parser::modus_operandi::modify(modus_t m) { 620void sitecing_parser::modus_operandi::modify(modus_t m) {
618 const char * x = modus_transitions[modus][m]; 621 const char * x = modus_transitions[modus][m];
619 assert(x); 622 assert(x);
620 output += x; 623 output += x;
621 modus = m; 624 modus = m;
622} 625}
623 626
624void sitecing_parser::soft_anchor() { 627void sitecing_parser::soft_anchor() {
625 if(M().modus!=modus_operandi::modus_text) 628 if(M().modus!=modus_operandi::modus_text)
626 anchor(); 629 anchor();
627} 630}
628void sitecing_parser::anchor() { 631void sitecing_parser::anchor() {
629 if(M().modus==modus_operandi::modus_text) 632 if(M().modus==modus_operandi::modus_text)
630 M().modify(modus_operandi::modus_preop); 633 M().modify(modus_operandi::modus_preop);
631 M().output += "\n#line "; 634 M().output += "\n#line ";
632 char tmp[7]; 635 char tmp[7];
633 snprintf(tmp,sizeof(tmp),"%d",lineno()); 636 snprintf(tmp,sizeof(tmp),"%d",lineno());
634 M().output += tmp; 637 M().output += tmp;
635 M().output += " \""; 638 M().output += " \"";
636 M().output += input_file; 639 M().output += input_file;
637 M().output += "\"\n"; 640 M().output += "\"\n";
638} 641}
639/* vim:set ft=lex: */ 642/* vim:set ft=lex: */