Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Cserveni, Akos | |
11 | * Forstner, Matyas | |
12 | * Raduly, Csaba | |
13 | * Szabados, Kristof | |
14 | * Szabo, Janos Zoltan – initial implementation | |
15 | * | |
16 | ******************************************************************************/ | |
970ed795 EL |
17 | #include "OCSV.hh" |
18 | #include "Block.hh" | |
19 | #include "TokenBuf.hh" | |
20 | #include "../Type.hh" | |
21 | #include "../Value.hh" | |
22 | ||
23 | namespace Asn { | |
24 | ||
25 | // ================================= | |
26 | // ===== OCSV_Builder | |
27 | // ================================= | |
28 | ||
29 | OCSV_Builder::OCSV_Builder(TokenBuf *p_tb, FieldSpecs *p_fss) | |
30 | : OCS_Visitor(), fss(p_fss) | |
31 | { | |
32 | if(!p_fss) | |
33 | FATAL_ERROR("NULL parameter: Asn::OCSV_Builder::OCSV_Builder()"); | |
34 | if(!p_tb) { // default syntax | |
35 | tb=0; | |
36 | } | |
37 | else { | |
38 | tb=new TokenBuf(); | |
39 | tb->reset(p_tb->get_filename()); | |
40 | bool ok=false; | |
41 | while(!ok) { | |
42 | Token *token=p_tb->pop_front_token(); | |
43 | switch(token->get_token()) { | |
44 | case TOK_LeftVersionBrackets: | |
45 | token->set_token('['); | |
46 | tb->push_back_token(token); | |
47 | tb->push_back_token(token->clone()); | |
48 | break; | |
49 | case TOK_RightVersionBrackets: | |
50 | token->set_token(']'); | |
51 | tb->push_back_token(token); | |
52 | tb->push_back_token(token->clone()); | |
53 | break; | |
54 | case '\0': | |
55 | ok=true; | |
56 | default: | |
57 | tb->push_back_token(token); | |
58 | } // switch token | |
59 | } // while !ok | |
60 | } | |
61 | } | |
62 | ||
63 | OCSV_Builder::~OCSV_Builder() | |
64 | { | |
65 | delete tb; | |
66 | } | |
67 | ||
68 | void OCSV_Builder::visit0(OCS_Node& p) | |
69 | { | |
70 | if(p.get_is_builded()) | |
71 | FATAL_ERROR("Asn::OCSV_Builder::visit0()"); | |
72 | } | |
73 | ||
74 | void OCSV_Builder::visit_root(OCS_root& p) | |
75 | { | |
76 | visit0(p); | |
77 | if(tb) { | |
78 | p.get_seq().accept(*this); | |
79 | } | |
80 | else { | |
81 | OCS_seq& seq=p.get_seq(); | |
82 | for(size_t i=0; i<fss->get_nof_fss(); i++) { | |
83 | FieldSpec *t_fs=fss->get_fs_byIndex(i)->get_last(); | |
84 | OCS_setting::settingtype_t t_st=OCS_setting::S_UNDEF; | |
85 | switch(t_fs->get_fstype()) { | |
86 | case FieldSpec::FS_T: | |
87 | t_st=OCS_setting::S_T; | |
88 | break; | |
89 | case FieldSpec::FS_V_FT: | |
90 | case FieldSpec::FS_V_VT: | |
91 | t_st=OCS_setting::S_V; | |
92 | break; | |
93 | case FieldSpec::FS_VS_FT: | |
94 | case FieldSpec::FS_VS_VT: | |
95 | t_st=OCS_setting::S_VS; | |
96 | break; | |
97 | case FieldSpec::FS_O: | |
98 | t_st=OCS_setting::S_O; | |
99 | break; | |
100 | case FieldSpec::FS_OS: | |
101 | t_st=OCS_setting::S_OS; | |
102 | break; | |
103 | case FieldSpec::FS_ERROR: | |
104 | continue; | |
105 | break; | |
106 | default: | |
107 | FATAL_ERROR("Asn::OCSV_Builder::visit_root()"); | |
108 | } // switch | |
109 | OCS_seq *t_seq=new OCS_seq | |
110 | (t_fs->get_is_optional() || t_fs->has_default(), true); | |
111 | t_seq->add_node(new OCS_literal(t_fs->get_id().clone())); | |
112 | t_seq->add_node(new OCS_setting(t_st, t_fs->get_id().clone())); | |
113 | for(size_t j=0; j<2; j++) | |
114 | t_seq->get_nth_node(j)->set_location(*t_fs); | |
115 | seq.add_node(t_seq); | |
116 | } // for i | |
117 | } | |
118 | p.set_is_builded(); | |
119 | } | |
120 | ||
121 | void OCSV_Builder::visit_seq(OCS_seq& p) | |
122 | { | |
123 | visit0(p); | |
124 | ||
125 | bool ok=false; | |
126 | Token *token; | |
127 | while(!ok) { | |
128 | token=tb->pop_front_token(); | |
129 | token->set_loc_info(); | |
130 | if(token->get_token()=='\0') { | |
131 | ok=true; | |
132 | delete token; | |
133 | } | |
134 | else if(token->get_token()=='[') { | |
135 | delete token; | |
136 | int blocklevel=1; | |
137 | TokenBuf *new_tb=new TokenBuf(); | |
138 | while(blocklevel>0) { | |
139 | token=tb->pop_front_token(); | |
140 | switch(token->get_token()) { | |
141 | case '[': | |
142 | blocklevel++; | |
143 | new_tb->push_back_token(token); | |
144 | break; | |
145 | case ']': | |
146 | blocklevel--; | |
147 | if(!blocklevel) token->set_token('\0'); | |
148 | new_tb->push_back_token(token); | |
149 | break; | |
150 | case 0: | |
151 | token->set_loc_info(); | |
152 | token->error("Unmatched `['"); | |
153 | break; | |
154 | default: | |
155 | new_tb->push_back_token(token); | |
156 | break; | |
157 | } // switch | |
158 | } // while | |
159 | OCSV_Builder *new_OCSV_Builder=new OCSV_Builder(new_tb, fss); | |
160 | delete new_tb; | |
161 | OCS_seq *new_OCS_seq=new OCS_seq(true); | |
162 | p.add_node(new_OCS_seq); | |
163 | new_OCS_seq->accept(*new_OCSV_Builder); | |
164 | delete new_OCSV_Builder; | |
165 | } | |
166 | else if(token->is_literal_kw()) { | |
167 | p.add_node(new OCS_literal(token->get_token())); | |
168 | delete token; | |
169 | } | |
170 | else if(token->is_literal_id()) { | |
171 | p.add_node(new OCS_literal(token->get_semval_id().clone())); | |
172 | delete token; | |
173 | } | |
174 | else if(token->is_ampId()) { | |
175 | OCS_setting::settingtype_t st=OCS_setting::S_UNDEF; | |
176 | FieldSpec *fs=0; | |
177 | const Identifier& id = token->get_semval_id(); | |
178 | if(!fss->has_fs_withId(id)) { | |
179 | token->error("No field with name `%s'", id.get_dispname().c_str()); | |
180 | goto afteradding; | |
181 | } | |
182 | fs=fss->get_fs_byId(id)->get_last(); | |
183 | switch(fs->get_fstype()) { | |
184 | case FieldSpec::FS_UNDEF: | |
185 | FATAL_ERROR("Asn::OCSV_Builder::visit_seq()"); | |
186 | break; | |
187 | case FieldSpec::FS_T: | |
188 | st=OCS_setting::S_T; | |
189 | break; | |
190 | case FieldSpec::FS_V_FT: | |
191 | case FieldSpec::FS_V_VT: | |
192 | st=OCS_setting::S_V; | |
193 | break; | |
194 | case FieldSpec::FS_VS_FT: | |
195 | case FieldSpec::FS_VS_VT: | |
196 | st=OCS_setting::S_VS; | |
197 | break; | |
198 | case FieldSpec::FS_O: | |
199 | st=OCS_setting::S_O; | |
200 | break; | |
201 | case FieldSpec::FS_OS: | |
202 | st=OCS_setting::S_OS; | |
203 | break; | |
204 | case FieldSpec::FS_ERROR: | |
205 | goto afteradding; | |
206 | default: | |
207 | FATAL_ERROR("Asn::OCSV_Builder::visit_seq()"); | |
208 | } // switch | |
209 | p.add_node(new OCS_setting(st, id.clone())); | |
210 | afteradding: | |
211 | delete token; | |
212 | } | |
213 | else { | |
214 | token->set_loc_info(); | |
215 | token->error("Unexpected `%s'", token->get_token_name()); | |
216 | delete token; | |
217 | } | |
218 | } // while !ok | |
219 | if(p.get_is_opt() && p.get_nof_nodes()==0) | |
220 | token->error("Empty optional group is not allowed"); | |
221 | p.set_is_builded(); | |
222 | } | |
223 | ||
224 | void OCSV_Builder::visit_literal(OCS_literal&) | |
225 | { | |
226 | FATAL_ERROR("Asn::OCSV_Builder::visit_literal()"); | |
227 | } | |
228 | ||
229 | void OCSV_Builder::visit_setting(OCS_setting&) | |
230 | { | |
231 | FATAL_ERROR("Asn::OCSV_Builder::visit_setting()"); | |
232 | } | |
233 | ||
234 | // ================================= | |
235 | // ===== OCSV_Parser | |
236 | // ================================= | |
237 | ||
238 | OCSV_Parser::OCSV_Parser(TokenBuf *p_tb, Obj_defn *p_my_obj) | |
239 | : OCS_Visitor(), my_obj(p_my_obj), success(true) | |
240 | { | |
241 | if(!p_tb || !my_obj) | |
242 | FATAL_ERROR("NULL parameter: Asn::OCSV_Parser::OCSV_Parser()"); | |
243 | tb=new TokenBuf(); | |
244 | tb->reset(p_tb->get_filename()); | |
245 | bool ok=false; | |
246 | while(!ok) { | |
247 | Token *token=p_tb->pop_front_token(); | |
248 | switch(token->get_token()) { | |
249 | case '\0': | |
250 | ok=true; | |
251 | default: | |
252 | tb->push_back_token(token); | |
253 | } // switch token | |
254 | } // while !ok | |
255 | } | |
256 | ||
257 | OCSV_Parser::~OCSV_Parser() | |
258 | { | |
259 | delete tb; | |
260 | } | |
261 | ||
262 | void OCSV_Parser::visit_root(OCS_root& p) | |
263 | { | |
264 | if(!p.get_is_builded() || !success) | |
265 | FATAL_ERROR("Asn::OCSV_Parser::visit_root()"); | |
266 | prev_success=false; | |
267 | my_obj->set_location(*tb->get_at(0)); | |
268 | Error_Context ec(my_obj, "While parsing object `%s'", | |
269 | my_obj->get_fullname().c_str()); | |
270 | p.get_seq().accept(*this); | |
271 | if(success && tb->get_at(0)->get_token()!='\0') { | |
272 | success=false; | |
273 | tb->get_at(0)->error("Unexpected `%s'", | |
274 | tb->get_at(0)->get_token_name()); | |
275 | tb->get_at(0)->error("Superfluous part detected"); | |
276 | } | |
277 | if(!success) { | |
278 | DEBUG(1, "Erroneous object definition detected."); | |
279 | DEBUG(1, "The correct syntax is:"); | |
280 | p.dump(1); | |
281 | my_obj->error("Check the syntax of objectclass" | |
282 | " (consider using debug messages)"); | |
283 | my_obj->set_is_erroneous(); | |
284 | } | |
285 | } | |
286 | ||
287 | void OCSV_Parser::visit_seq(OCS_seq& p) | |
288 | { | |
289 | size_t i; | |
290 | if(p.get_opt_first_comma() && my_obj->get_nof_fss()>0) { | |
291 | if(tb->get_at(0)->get_token()==',') { | |
292 | delete tb->pop_front_token(); | |
293 | } | |
294 | else { | |
295 | if(!p.get_is_opt()) { | |
296 | success=false; | |
297 | tb->get_at(0)->error("Unexpected `%s'", | |
298 | tb->get_at(0)->get_token_name()); | |
299 | tb->get_at(0)->error("Expecting `,'"); | |
300 | } | |
301 | else prev_success=true; | |
302 | return; | |
303 | } | |
304 | i=0; | |
305 | } | |
306 | else { | |
307 | /* This can be only if each of the fieldspecs were erroneous */ | |
308 | if(p.get_nof_nodes()==0) return; | |
309 | p.get_nth_node(0)->accept(*this); | |
310 | if(!success) return; | |
311 | if(!prev_success) { | |
312 | if(!p.get_is_opt()) { | |
313 | success=false; | |
314 | tb->get_at(0)->error("Unexpected `%s'", | |
315 | tb->get_at(0)->get_token_name()); | |
316 | tb->get_at(0)->error("Expecting %s", | |
317 | p.get_dispname().c_str()); | |
318 | } | |
319 | else prev_success=true; | |
320 | return; | |
321 | } | |
322 | i=1; | |
323 | } | |
324 | for(; i<p.get_nof_nodes(); i++) { | |
325 | p.get_nth_node(i)->accept(*this); | |
326 | if(!prev_success) { | |
327 | if(p.get_is_opt()){ | |
328 | prev_success = true; | |
329 | tb->push_front_kw_token(','); | |
330 | return; | |
331 | } | |
332 | success=false; | |
333 | tb->get_at(0)->error("Unexpected `%s'", | |
334 | tb->get_at(0)->get_token_name()); | |
335 | tb->get_at(0)->error("Expecting %s", | |
336 | p.get_dispname().c_str()); | |
337 | } | |
338 | if(!success) return; | |
339 | } | |
340 | } | |
341 | ||
342 | void OCSV_Parser::visit_literal(OCS_literal& p) | |
343 | { | |
344 | prev_success=false; | |
345 | if(p.is_keyword()) { | |
346 | if(p.get_keyword()==tb->get_at(0)->get_token()) { | |
347 | delete tb->pop_front_token(); | |
348 | prev_success=true; | |
349 | } | |
350 | } | |
351 | else { | |
352 | Token *token=tb->get_at(0); | |
353 | if(token->is_id() | |
354 | && (token->get_semval_id().get_dispname() | |
355 | == p.get_word()->get_dispname())) { | |
356 | delete tb->pop_front_token(); | |
357 | prev_success=true; | |
358 | } | |
359 | } | |
360 | } | |
361 | ||
362 | void OCSV_Parser::visit_setting(OCS_setting& p) | |
363 | { | |
364 | Error_Context cntxt(&p, "While parsing setting for this field: `%s'", | |
365 | p.get_id()->get_dispname().c_str()); | |
366 | FieldSetting *fs=0; | |
367 | switch(p.get_st()) { | |
368 | case OCS_setting::S_T: { | |
369 | Type *setting=parse_type(); | |
370 | if(setting) { | |
371 | fs=new FieldSetting_Type(p.get_id()->clone(), setting); | |
372 | fs->set_location(*setting); | |
373 | } | |
374 | break;} | |
375 | case OCS_setting::S_V: { | |
376 | Value *setting=parse_value(); | |
377 | if(setting) { | |
378 | fs=new FieldSetting_Value(p.get_id()->clone(), setting); | |
379 | fs->set_location(*setting); | |
380 | } | |
381 | break;} | |
382 | case OCS_setting::S_VS: | |
383 | NOTSUPP("ValueSet settings"); | |
384 | prev_success=false; | |
385 | return; | |
386 | break; | |
387 | case OCS_setting::S_O: { | |
388 | Object *setting=parse_object(); | |
389 | if(setting) { | |
390 | fs=new FieldSetting_O(p.get_id()->clone(), setting); | |
391 | fs->set_location(*setting); | |
392 | } | |
393 | break;} | |
394 | case OCS_setting::S_OS: { | |
395 | ObjectSet *setting=parse_objectset(); | |
396 | if(setting) { | |
397 | fs=new FieldSetting_OS(p.get_id()->clone(), setting); | |
398 | fs->set_location(*setting); | |
399 | } | |
400 | break;} | |
401 | case OCS_setting::S_UNDEF: | |
402 | FATAL_ERROR("Undefined setting"); | |
403 | break; | |
404 | } // switch | |
405 | if(!fs) { | |
406 | prev_success=false; | |
407 | return; | |
408 | } | |
409 | prev_success=true; | |
410 | my_obj->add_fs(fs); | |
411 | } | |
412 | ||
413 | size_t OCSV_Parser::is_ref(size_t pos) | |
414 | { | |
415 | if(!(tb->get_at(pos)->get_token()==TOK_UpperIdentifier | |
416 | || tb->get_at(pos)->get_token()==TOK_LowerIdentifier)) | |
417 | return 0; | |
418 | size_t pos2=pos+1; | |
419 | while(tb->get_at(pos2)->get_token()=='.' | |
420 | && tb->get_at(pos2+1)->is_id()) | |
421 | pos2+=2; | |
422 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
423 | pos2++; | |
424 | return pos2-pos; | |
425 | } | |
426 | ||
427 | size_t OCSV_Parser::is_tag(size_t pos) | |
428 | { | |
429 | size_t pos2=pos; | |
430 | if(tb->get_at(pos2)->get_token()!='[') | |
431 | return 0; | |
432 | do pos2++; | |
433 | while(tb->get_at(pos2)->get_token()!=']' | |
434 | && tb->get_at(pos2)->get_token()!='\0'); | |
435 | if(tb->get_at(pos2)->get_token()==']') pos2++; | |
436 | switch(tb->get_at(pos2)->get_token()) { | |
437 | case KW_IMPLICIT: | |
438 | case KW_EXPLICIT: | |
439 | pos2++; | |
440 | } //switch | |
441 | return pos2-pos; | |
442 | } | |
443 | ||
444 | size_t OCSV_Parser::is_constraint(size_t pos) | |
445 | { | |
446 | size_t pos2=pos; | |
447 | if(tb->get_at(pos2)->get_token()!='(') | |
448 | return 0; | |
449 | unsigned blocklevel=1; | |
450 | for(pos2=pos+1; blocklevel>0; pos2++) { | |
451 | switch(tb->get_at(pos2)->get_token()) { | |
452 | case '(': | |
453 | blocklevel++; | |
454 | break; | |
455 | case ')': | |
456 | blocklevel--; | |
457 | break; | |
458 | case '\0': | |
459 | blocklevel=0; | |
460 | break; | |
461 | } // switch | |
462 | } // for pos2 | |
463 | if(tb->get_at(pos2)->get_token()==')') pos2++; | |
464 | return pos2-pos; | |
465 | } | |
466 | ||
467 | size_t OCSV_Parser::is_constraints(size_t pos) | |
468 | { | |
469 | size_t pos2=pos, pos3; | |
470 | while((pos3=is_constraint(pos2))) | |
471 | pos2+=pos3; | |
472 | return pos2-pos; | |
473 | } | |
474 | ||
475 | size_t OCSV_Parser::is_nakedtype(size_t pos) | |
476 | { | |
477 | size_t pos2=pos; | |
478 | switch(tb->get_at(pos2)->get_token()) { | |
479 | case KW_NULL: | |
480 | case KW_BOOLEAN: | |
481 | case KW_GeneralString: | |
482 | case KW_BMPString: | |
483 | case KW_GraphicString: | |
484 | case KW_IA5String: | |
485 | case KW_NumericString: | |
486 | case KW_PrintableString: | |
487 | case KW_TeletexString: | |
488 | case KW_T61String: | |
489 | case KW_UniversalString: | |
490 | case KW_UTF8String: | |
491 | case KW_VideotexString: | |
492 | case KW_VisibleString: | |
493 | case KW_ISO646String: | |
494 | case KW_RELATIVE_OID: | |
495 | case KW_REAL: | |
496 | case KW_EXTERNAL: | |
497 | case KW_GeneralizedTime: | |
498 | case KW_UTCTime: | |
499 | case KW_ObjectDescriptor: | |
500 | pos2++; | |
501 | break; | |
502 | case KW_BIT: | |
503 | pos2++; | |
504 | if(tb->get_at(pos2)->get_token()==KW_STRING) { | |
505 | pos2++; | |
506 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
507 | pos2++; | |
508 | } | |
509 | break; | |
510 | case KW_CHARACTER: | |
511 | pos2++; | |
512 | if(tb->get_at(pos2)->get_token()==KW_STRING) | |
513 | pos2++; | |
514 | break; | |
515 | case KW_CHOICE: | |
516 | case KW_ENUMERATED: | |
517 | case KW_INTEGER: | |
518 | pos2++; | |
519 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
520 | pos2++; | |
521 | break; | |
522 | case KW_SEQUENCE: | |
523 | case KW_SET: | |
524 | pos2++; | |
525 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
526 | pos2++; | |
527 | else { // SeOf | |
528 | if(tb->get_at(pos2)->get_token()==KW_SIZE) | |
529 | pos2++; | |
530 | pos2+=is_constraint(pos2); | |
531 | if(tb->get_at(pos2)->get_token()==KW_OF) { | |
532 | pos2+=tb->get_at(pos2+1)->get_token()==TOK_LowerIdentifier?2:1; | |
533 | pos2+=is_type(pos2); | |
534 | } | |
535 | } | |
536 | break; | |
537 | case KW_OBJECT: | |
538 | pos2++; | |
539 | if(tb->get_at(pos2)->get_token()==KW_IDENTIFIER) | |
540 | pos2++; | |
541 | break; | |
542 | case KW_OCTET: | |
543 | pos2++; | |
544 | if(tb->get_at(pos2)->get_token()==KW_STRING) | |
545 | pos2++; | |
546 | break; | |
547 | case KW_EMBEDDED: | |
548 | pos2++; | |
549 | if(tb->get_at(pos2)->get_token()==KW_PDV) | |
550 | pos2++; | |
551 | break; | |
552 | case KW_ANY: | |
553 | pos2++; | |
554 | if(tb->get_at(pos2)->get_token()==KW_DEFINED | |
555 | && tb->get_at(pos2+1)->get_token()==KW_BY | |
556 | && tb->get_at(pos2+2)->get_token()==TOK_LowerIdentifier | |
557 | ) | |
558 | pos2+=3; | |
559 | break; | |
560 | } // switch | |
561 | if(pos2==pos) | |
562 | pos2=is_ref(pos)+pos2; | |
563 | return pos2-pos; | |
564 | } | |
565 | ||
566 | size_t OCSV_Parser::is_type(size_t pos) | |
567 | { | |
568 | size_t pos2=pos, pos3; | |
569 | while((pos3=is_tag(pos2))) | |
570 | pos2+=pos3; | |
571 | pos2+=is_nakedtype(pos2); | |
572 | pos2+=is_constraints(pos2); | |
573 | return pos2-pos; | |
574 | } | |
575 | ||
576 | size_t OCSV_Parser::is_value(size_t pos) | |
577 | { | |
578 | size_t pos2=pos; | |
579 | switch(tb->get_at(pos2)->get_token()) { | |
580 | case TOK_Block: | |
581 | case TOK_BString: | |
582 | case TOK_HString: | |
583 | case TOK_CString: | |
584 | case KW_NULL: | |
585 | case KW_TRUE: | |
586 | case KW_FALSE: | |
587 | case TOK_Number: | |
588 | case TOK_RealNumber: | |
589 | case KW_PLUS_INFINITY: | |
590 | case KW_MINUS_INFINITY: | |
591 | pos2++; | |
592 | break; | |
593 | case '-': | |
594 | pos2++; | |
595 | if(tb->get_at(pos2)->get_token()==TOK_Number | |
596 | || tb->get_at(pos2)->get_token()==TOK_RealNumber) | |
597 | pos2++; | |
598 | break; | |
599 | case TOK_LowerIdentifier: | |
600 | if(tb->get_at(pos2+1)->get_token()==':') { | |
601 | pos2=is_value(pos2+2); | |
602 | if(pos2) pos2+=pos+2; | |
603 | else pos2=pos; | |
604 | } else pos2=pos; | |
605 | break; | |
606 | } // switch | |
607 | if(pos2==pos) | |
608 | pos2=is_ref(pos)+pos; | |
609 | return pos2-pos; | |
610 | } | |
611 | ||
612 | size_t OCSV_Parser::is_object(size_t pos) | |
613 | { | |
614 | size_t pos2=pos; | |
615 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
616 | pos2++; | |
617 | if(pos2==pos) | |
618 | pos2=is_ref(pos)+pos; | |
619 | return pos2-pos; | |
620 | } | |
621 | ||
622 | size_t OCSV_Parser::is_objectset(size_t pos) | |
623 | { | |
624 | size_t pos2=pos; | |
625 | if(tb->get_at(pos2)->get_token()==TOK_Block) | |
626 | pos2++; | |
627 | return pos2-pos; | |
628 | } | |
629 | ||
630 | Block* OCSV_Parser::get_first_n(size_t n) | |
631 | { | |
632 | TokenBuf *new_tb=new TokenBuf(); | |
633 | new_tb->reset(tb->get_filename()); | |
634 | for(size_t i=0; i<n; i++) | |
635 | new_tb->push_back_token(tb->pop_front_token()); | |
636 | new_tb->push_back_token(new Token(0, Location(tb->get_filename()))); | |
637 | return new Block(new_tb); | |
638 | } | |
639 | ||
640 | Type* OCSV_Parser::parse_type() | |
641 | { | |
642 | size_t n; | |
643 | n=is_type(0); | |
644 | if(!n) return 0; | |
645 | Block *block=get_first_n(n); | |
646 | Node *node=block->parse(KW_Block_Type); | |
647 | delete block; | |
648 | Type *new_type=dynamic_cast<Type*>(node); | |
649 | if(!new_type) | |
650 | new_type=new Type(Type::T_ERROR); | |
651 | return new_type; | |
652 | } | |
653 | ||
654 | Value* OCSV_Parser::parse_value() | |
655 | { | |
656 | size_t n; | |
657 | n=is_value(0); | |
658 | if(!n) return 0; | |
659 | Block *block=get_first_n(n); | |
660 | Node *node=block->parse(KW_Block_Value); | |
661 | delete block; | |
662 | Value *new_value=dynamic_cast<Value*>(node); | |
663 | if(!new_value) | |
664 | new_value=new Value(Value::V_ERROR); | |
665 | return new_value; | |
666 | } | |
667 | ||
668 | Object* OCSV_Parser::parse_object() | |
669 | { | |
670 | size_t n; | |
671 | n=is_object(0); | |
672 | if(!n) return 0; | |
673 | Block *block=get_first_n(n); | |
674 | Node *node=block->parse(KW_Block_Object); | |
675 | delete block; | |
676 | Object *new_object=dynamic_cast<Object*>(node); | |
677 | if(!new_object) | |
678 | new_object=new Obj_defn(); | |
679 | return new_object; | |
680 | } | |
681 | ||
682 | ObjectSet* OCSV_Parser::parse_objectset() | |
683 | { | |
684 | size_t n; | |
685 | n=is_objectset(0); | |
686 | if(!n) return 0; | |
687 | Block *block=get_first_n(n); | |
688 | Node *node=block->parse(KW_Block_ObjectSet); | |
689 | delete block; | |
690 | ObjectSet *new_objectset=dynamic_cast<ObjectSet*>(node); | |
691 | if(!new_objectset) | |
692 | new_objectset=new OS_defn(); | |
693 | return new_objectset; | |
694 | } | |
695 | ||
696 | } // namespace Asn |