Modules |
Files |
Inheritance Tree |
Inheritance Graph |
Name Index |
Config
File: Synopsis/Parser/C++/occ/parse.cc
1| /*
2| Copyright (C) 1997-2000 Shigeru Chiba, University of Tsukuba.
3| Copyright (C) 2001-2002 Stephen Davies
4|
5| Permission to use, copy, distribute and modify this software and
6| its documentation for any purpose is hereby granted without fee,
7| provided that the above copyright notice appear in all copies and that
8| both that copyright notice and this permission notice appear in
9| supporting documentation.
10|
11| Shigeru Chiba makes no representations about the suitability of this
12| software for any purpose. It is provided "as is" without express or
13| implied warranty.
14| */
15| /*
16| C++ Parser
17|
18| This parser is a LL(k) parser with ad hoc rules such as
19| backtracking.
20|
21| r<name>() is the grammer rule for a non-terminal <name>.
22| opt<name>() is the grammer fule for an optional non-terminal <name>.
23| is<name>() looks ahead and returns TRUE if the next symbol is <name>.
24| */
25|
26| #include <iostream>
27| #include "parse.h"
28| #include "token.h"
29| #include "env.h"
30| #include "ptree.h"
31| #include "encoding.h"
32| #include "metaclass.h"
33| #include "walker.h"
34|
35| #if defined(_PARSE_VCC)
36| #define _MSC_VER
37| #endif
38|
39| const int MaxErrors = 10;
40|
41| Parser::Parser(Lex* l)
42| {
43| lex = l;
44| nerrors = 0;
45| comments = 0;
46| }
47|
48| bool Parser::ErrorMessage(const char* msg, Ptree* name, Ptree* where)
49| {
50| if(where != nil){
51| Ptree* head = where->Ca_ar();
52| if(head != nil)
53| ShowMessageHead(head->GetPosition());
54| }
55|
56| std::cerr << msg;
57| if(name != nil)
58| name->Write(std::cerr);
59|
60| std::cerr << '\n';
61| return bool(++nerrors < MaxErrors);
62| }
63|
64| void Parser::WarningMessage(const char* msg, Ptree* name, Ptree* where)
65| {
66| if(where != nil){
67| Ptree* head = where->Ca_ar();
68| if(head != nil)
69| ShowMessageHead(head->GetPosition());
70| }
71|
72| std::cerr << "warning: " << msg;
73| if(name != nil)
74| name->Write(std::cerr);
75|
76| std::cerr << '\n';
77| }
78|
79| bool Parser::SyntaxError()
80| {
81| Token t, t2;
82| int i;
83|
84| lex->LookAhead(0, t);
85| lex->LookAhead(1, t2);
86|
87| ShowMessageHead(t.ptr);
88| std::cerr << "parse error before `";
89| if(t.kind != '\0')
90| for(i = 0; i < t.len; ++i)
91| std::cerr << t.ptr[i];
92|
93| if(t2.kind != '\0'){
94| std::cerr << ' ';
95| for(i = 0; i < t2.len; ++i)
96| std::cerr << t2.ptr[i];
97| }
98|
99| std::cerr << "'\n";
100| return bool(++nerrors < MaxErrors);
101| }
102|
103| uint Parser::LineNumber(char* pos, char*& fname, int& fname_len)
104| {
105| uint line_number = lex->LineNumber(pos, fname, fname_len);
106| if(fname_len > 1){
107| if(fname[0] == '"') {
108| ++fname;
109| --fname_len;
110| }
111|
112| if(fname[fname_len - 1] == '"')
113| --fname_len;
114| }
115|
116| return line_number;
117| }
118|
119| void Parser::ShowMessageHead(char* pos)
120| {
121| char* fname;
122| int fname_len;
123|
124| uint line_number = LineNumber(pos, fname, fname_len);
125| int i = 0;
126| while(i < fname_len)
127| std::cerr << fname[i++];
128|
129| #if defined(_MSC_VER)
130| std::cerr << '(' << line_number << ") : ";
131| #else
132| std::cerr << ':' << line_number << ": ";
133| #endif
134| }
135|
136| bool Parser::rProgram(Ptree*& def)
137| {
138| while(lex->LookAhead(0) != '\0')
139| if(rDefinition(def)) return TRUE;
140| else{
141| Token tk;
142| if(!SyntaxError()) return FALSE; // too m
143| SkipTo(';');
144| lex->GetToken(tk);
145| }
146|
147| // Retrieve trailing comments
148| def = lex->GetComments();
149| if (def)
150| return TRUE;
151| return FALSE;
152| }
153|
154| /*
155| definition
156| : null.declaration
157| | typedef
158| | template.decl
159| | metaclass.decl
160| | linkage.spec
161| | namespace.spec
162| | using.declaration
163| | extern.template.decl
164| | declaration
165| */
166| bool Parser::rDefinition(Ptree*& p)
167| {
168| bool res;
169| int t = lex->LookAhead(0);
170| if(t == ';')
171| res = rNullDeclaration(p);
172| else if(t == TYPEDEF)
173| res = rTypedef(p);
174| else if(t == TEMPLATE)
175| res = rTemplateDecl(p);
176| else if(t == METACLASS)
177| res = rMetaclassDecl(p);
178| else if(t == EXTERN && lex->LookAhead(1) == StringL)
179| res = rLinkageSpec(p);
180| else if(t == EXTERN && lex->LookAhead(1) == TEMPLATE)
181| res = rExternTemplateDecl(p);
182| else if(t == NAMESPACE)
183| res = rNamespaceSpec(p);
184| else if(t == USING)
185| res = rUsing(p);
186| else {
187| if (!rDeclaration(p))
188| return FALSE;
189| Ptree* c = lex->GetComments();
190| if (c) {
191| Walker::SetDeclaratorComments(p, c);
192| }
193| return TRUE;
194| }
195|
196| // Leftover comments.. is this needed?
197| /* Ptree* c = */lex->GetComments();
198| //if (c) c->Display();
199| return res;
200| }
201|
202| bool Parser::rNullDeclaration(Ptree*& decl)
203| {
204| Token tk;
205|
206| if(lex->GetToken(tk) != ';')
207| return FALSE;
208|
209| decl = new PtreeDeclaration(nil, Ptree::List(nil, new Leaf(tk)));
210| return TRUE;
211| }
212|
213| /*
214| typedef
215| : TYPEDEF type.specifier declarators ';'
216| */
217| bool Parser::rTypedef(Ptree*& def)
218| {
219| Token tk;
220| Ptree *type_name, *decl;
221| Encoding type_encode;
222|
223| if(lex->GetToken(tk) != TYPEDEF)
224| return FALSE;
225|
226| def = new PtreeTypedef(new LeafReserved(tk));
227| if(!rTypeSpecifier(type_name, FALSE, type_encode))
228| return FALSE;
229|
230| def = Ptree::Snoc(def, type_name);
231| if(!rDeclarators(decl, type_encode, TRUE))
232| return FALSE;
233|
234| if(lex->GetToken(tk) != ';')
235| return FALSE;
236|
237| def = Ptree::Nconc(def, Ptree::List(decl, new Leaf(tk)));
238| return TRUE;
239| }
240|
241| /*
242| type.specifier
243| : {cv.qualify} (integral.or.class.spec | name) {cv.qualify}
244| */
245| bool Parser::rTypeSpecifier(Ptree*& tspec, bool check, Encoding& encode)
246| {
247| Ptree *cv_q, *cv_q2;
248|
249| if(!optCvQualify(cv_q) || !optIntegralTypeOrClassSpec(tspec, encode))
250| return FALSE;
251|
252| if(tspec == nil){
253| if(check){
254| Token tk;
255| lex->LookAhead(0, tk);
256| if(!MaybeTypeNameOrClassTemplate(tk))
257| return FALSE;
258| }
259|
260| if(!rName(tspec, encode))
261| return FALSE;
262| }
263|
264| if(!optCvQualify(cv_q2))
265| return FALSE;
266|
267| if(cv_q != nil){
268| tspec = Ptree::Snoc(cv_q, tspec);
269| if(cv_q2 != nil)
270| tspec = Ptree::Nconc(tspec, cv_q2);
271| }
272| else if(cv_q2 != nil)
273| tspec = Ptree::Cons(tspec, cv_q2);
274|
275| encode.CvQualify(cv_q, cv_q2);
276| return TRUE;
277| }
278|
279| // isTypeSpecifier() returns TRUE if the next is probably a type specifier.
280|
281| bool Parser::isTypeSpecifier()
282| {
283| int t = lex->LookAhead(0);
284| if(t == Identifier || t == Scope
285| ||t == CONST || t == VOLATILE
286| || t == CHAR || t == INT || t == SHORT || t == LONG
287| || t == SIGNED || t == UNSIGNED || t == FLOAT || t == DOUBLE
288| || t == VOID || t == BOOLEAN
289| || t == CLASS || t == STRUCT || t == UNION || t == ENUM
290| #if defined(_MSC_VER)
291| || t == INT64
292| #endif
293| )
294| return TRUE;
295| else
296| return FALSE;
297| }
298|
299| /*
300| metaclass.decl
301| : METACLASS Identifier {{':'} Identifier {'(' meta.arguments ')'}} ';'
302|
303| We allow two kinds of syntax:
304|
305| metaclass <metaclass> <class>(...);
306| metaclass <metaclass>;
307| metaclass <class> : <metaclass>(...); // for backward compa
308| */
309| bool Parser::rMetaclassDecl(Ptree*& decl)
310| {
311| int t;
312| Token tk1, tk2, tk3, tk4;
313| Ptree* metaclass_name;
314|
315| if(lex->GetToken(tk1) != METACLASS)
316| return FALSE;
317|
318| if(lex->GetToken(tk2) != Identifier)
319| return FALSE;
320|
321| t = lex->GetToken(tk3);
322| if(t == Identifier){
323| metaclass_name = new Leaf(tk2);
324| decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
325| Ptree::List(metaclass_name,
326| new Leaf(tk3)));
327| }
328| else if(t == ':'){
329| if(lex->GetToken(tk4) != Identifier)
330| return FALSE;
331|
332| metaclass_name = new Leaf(tk4);
333| decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
334| Ptree::List(metaclass_name,
335| new Leaf(tk2)));
336| }
337| else if(t == ';'){
338| metaclass_name = new Leaf(tk2);
339| decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
340| Ptree::List(metaclass_name, nil,
341| new Leaf(tk3)));
342| Metaclass::Load(metaclass_name);
343| return TRUE;
344| }
345| else
346| return FALSE;
347|
348| t = lex->GetToken(tk1);
349| if(t == '('){
350| Ptree* args;
351| if(!rMetaArguments(args))
352| return FALSE;
353|
354| if(lex->GetToken(tk2) != ')')
355| return FALSE;
356|
357| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1), args,
358| new Leaf(tk2)));
359| t = lex->GetToken(tk1);
360| }
361|
362| if(t == ';'){
363| decl = Ptree::Snoc(decl, new Leaf(tk1));
364| Metaclass::Load(metaclass_name);
365| return TRUE;
366| }
367| else
368| return FALSE;
369| }
370|
371| /*
372| meta.arguments : (anything but ')')*
373| */
374| bool Parser::rMetaArguments(Ptree*& args)
375| {
376| int t;
377| Token tk;
378|
379| int n = 1;
380| args = nil;
381| for(;;){
382| t = lex->LookAhead(0);
383| if(t == '\0')
384| return FALSE;
385| else if(t == '(')
386| ++n;
387| else if(t == ')')
388| if(--n <= 0)
389| return TRUE;
390|
391| lex->GetToken(tk);
392| args = Ptree::Snoc(args, new Leaf(tk));
393| }
394| }
395|
396| /*
397| linkage.spec
398| : EXTERN StringL definition
399| | EXTERN StringL linkage.body
400| */
401| bool Parser::rLinkageSpec(Ptree*& spec)
402| {
403| Token tk1, tk2;
404| Ptree* body;
405|
406| if(lex->GetToken(tk1) != EXTERN)
407| return FALSE;
408|
409| if(lex->GetToken(tk2) != StringL)
410| return FALSE;
411|
412| spec = new PtreeLinkageSpec(new LeafEXTERN(tk1),
413| Ptree::List(new Leaf(tk2)));
414| if(lex->LookAhead(0) == '{'){
415| if(!rLinkageBody(body))
416| return FALSE;
417| }
418| else
419| if(!rDefinition(body))
420| return FALSE;
421|
422| spec = Ptree::Snoc(spec, body);
423| return TRUE;
424| }
425|
426| /*
427| namespace.spec
428| : NAMESPACE Identifier definition
429| | NAMESPACE { Identifier } linkage.body
430| */
431| bool Parser::rNamespaceSpec(Ptree*& spec)
432| {
433| Token tk1, tk2;
434| Ptree* name;
435| Ptree* body;
436|
437| if(lex->GetToken(tk1) != NAMESPACE)
438| return FALSE;
439|
440| Ptree* comments = lex->GetComments();
441|
442| if(lex->LookAhead(0) == '{')
443| name = nil;
444| else
445| if(lex->GetToken(tk2) == Identifier)
446| name = new Leaf(tk2);
447| else
448| return FALSE;
449|
450| if(lex->LookAhead(0) == '{'){
451| if(!rLinkageBody(body))
452| return FALSE;
453| }
454| else
455| if(!rDefinition(body))
456| return FALSE;
457|
458| PtreeNamespaceSpec *nspec;
459| spec = nspec = new PtreeNamespaceSpec(
460| new LeafNAMESPACE(tk1), Ptree::List(name, body));
461|
462| nspec->SetComments(comments);
463| return TRUE;
464| }
465|
466|
467| /*
468| using.declaration : USING ... ';'
469| */
470| bool Parser::rUsing(Ptree*& decl)
471| {
472| Token tk;
473|
474| if(lex->GetToken(tk) != USING)
475| return FALSE;
476|
477| decl = new PtreeUsing(new LeafUSING(tk));
478| do {
479| lex->GetToken(tk);
480| decl = Ptree::Snoc(decl, new Leaf(tk));
481| } while(tk.kind != ';' && tk.kind != '\0');
482|
483| return TRUE;
484| }
485|
486|
487| /*
488| linkage.body : '{' (definition)* '}'
489|
490| Note: this is also used to construct namespace.spec
491| */
492| bool Parser::rLinkageBody(Ptree*& body)
493| {
494| Token op, cp;
495| Ptree* def;
496|
497| if(lex->GetToken(op) != '{')
498| return FALSE;
499|
500| body = nil;
501| while(lex->LookAhead(0) != '}'){
502| if(!rDefinition(def)){
503| if(!SyntaxError())
504| return FALSE; // too man
505|
506| SkipTo('}');
507| lex->GetToken(cp);
508| body = Ptree::List(new Leaf(op), nil, new Leaf(cp));
509| return TRUE;
510| }
511|
512| body = Ptree::Snoc(body, def);
513| }
514|
515| lex->GetToken(cp);
516| body = new PtreeBrace(new Leaf(op), body,
517| new CommentedLeaf(cp, lex->GetComments()));
518| return TRUE;
519| }
520|
521| /*
522| template.decl
523| : TEMPLATE '<' temp.arg.list '>' declaration
524| | TEMPLATE declaration
525| | TEMPLATE '<' '>' declaration
526|
527| The second case is an explicit template instantiation. declaration must
528| be a class declaration. For example,
529|
530| template class Foo<int, char>;
531|
532| explicitly instantiates the template Foo with int and char.
533|
534| The third case is a specialization of a template function. declaration
535| must be a function template. For example,
536|
537| template <> int count(String x) { return x.length; }
538| */
539| bool Parser::rTemplateDecl(Ptree*& decl)
540| {
541| Ptree *body;
542| TemplateDeclKind kind = tdk_unknown;
543|
544| if(!rTemplateDecl2(decl, kind))
545| return FALSE;
546|
547| if(!rDeclaration(body))
548| return FALSE;
549|
550| // Repackage the decl and body depending upon what kind of template
551| // declaration was observed.
552| switch (kind) {
553| case tdk_instantiation:
554| // Repackage the decl as a PtreeTemplateInstantiation
555| decl = body;
556| // assumes that decl has the form: [nil [class ...] ;]
557| if (Ptree::Length(decl) != 3)
558| return FALSE;
559|
560| if (Ptree::First(decl) != nil)
561| return FALSE;
562|
563| if (Ptree::Second(decl)->What() != ntClassSpec)
564| return FALSE;
565|
566| if (!Ptree::Eq(Ptree::Third(decl), ';'))
567| return FALSE;
568|
569| decl = new PtreeTemplateInstantiation(Ptree::Second(decl));
570| break;
571| case tdk_decl:
572| case tdk_specialization:
573| decl = Ptree::Snoc(decl, body);
574| break;
575| default:
576| MopErrorMessage("rTemplateDecl()", "fatal");
577| break;
578| }
579|
580| return TRUE;
581| }
582|
583| bool Parser::rTemplateDecl2(Ptree*& decl, TemplateDeclKind &kind)
584| {
585| Token tk;
586| Ptree *args;
587|
588| if(lex->GetToken(tk) != TEMPLATE)
589| return FALSE;
590|
591| if(lex->LookAhead(0) != '<') {
592| // template instantiation
593| decl = nil;
594| kind = tdk_instantiation;
595| return TRUE;
596| }
597|
598| decl = new PtreeTemplateDecl(new LeafReserved(tk));
599| if(lex->GetToken(tk) != '<')
600| return FALSE;
601|
602| decl = Ptree::Snoc(decl, new Leaf(tk));
603| if(!rTempArgList(args))
604| return FALSE;
605|
606| if(lex->GetToken(tk) != '>')
607| return FALSE;
608|
609| decl = Ptree::Nconc(decl, Ptree::List(args, new Leaf(tk)));
610|
611| // ignore nested TEMPLATE
612| while (lex->LookAhead(0) == TEMPLATE) {
613| lex->GetToken(tk);
614| if(lex->LookAhead(0) != '<')
615| break;
616|
617| lex->GetToken(tk);
618| if(!rTempArgList(args))
619| return FALSE;
620|
621| if(lex->GetToken(tk) != '>')
622| return FALSE;
623| }
624|
625| if (args == nil)
626| // template < > declaration
627| kind = tdk_specialization;
628| else
629| // template < ... > declaration
630| kind = tdk_decl;
631|
632| return TRUE;
633| }
634|
635| /*
636| temp.arg.list
637| : empty
638| | temp.arg.declaration (',' temp.arg.declaration)*
639| */
640| bool Parser::rTempArgList(Ptree*& args)
641| {
642| Token tk;
643| Ptree* a;
644|
645| if(lex->LookAhead(0) == '>'){
646| args = nil;
647| return TRUE;
648| }
649|
650| if(!rTempArgDeclaration(a))
651| return FALSE;
652|
653| args = Ptree::List(a);
654| while(lex->LookAhead(0) == ','){
655| lex->GetToken(tk);
656| args = Ptree::Snoc(args, new Leaf(tk));
657| if(!rTempArgDeclaration(a))
658| return FALSE;
659|
660| args = Ptree::Snoc(args, a);
661| }
662|
663| return TRUE;
664| }
665|
666| /*
667| temp.arg.declaration
668| : CLASS Identifier {'=' type.name}
669| | type.specifier arg.declarator {'=' additive.expr}
670| | template.decl2 CLASS Identifier {'=' type.name}
671| */
672| bool Parser::rTempArgDeclaration(Ptree*& decl)
673| {
674| Token tk1, tk2;
675|
676| int t0 = lex->LookAhead(0);
677| int t1 = lex->LookAhead(1);
678| int t2 = lex->LookAhead(2);
679| if(t0 == CLASS && t1 == Identifier && (t2 == '=' || t2 == '>' || t2 == ',')) {
680| lex->GetToken(tk1);
681| lex->GetToken(tk2);
682| Ptree* name = new Leaf(tk2);
683| decl = Ptree::List(new Leaf(tk1), name);
684|
685| if(t2 == '='){
686| Ptree* default_type;
687|
688| lex->GetToken(tk1);
689| if(!rTypeName(default_type))
690| return FALSE;
691|
692| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
693| default_type));
694| return TRUE;
695| }
696| else if (t2 == '>' || t2 == ',')
697| return TRUE;
698| }
699| else if (t0 == CLASS && (t1 == '=' || t1 == '>' || t1 == ',')) {
700| // class without the identifier
701| lex->GetToken(tk1);
702| decl = Ptree::List(new Leaf(tk1));
703|
704| if(lex->LookAhead(0) == '='){
705| Ptree* default_type;
706|
707| lex->GetToken(tk1);
708| if(!rTypeName(default_type))
709| return FALSE;
710|
711| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
712| default_type));
713| }
714| }
715| else if (t0 == TEMPLATE) {
716| TemplateDeclKind kind;
717| if(!rTemplateDecl2(decl, kind))
718| return FALSE;
719|
720| if (lex->GetToken(tk1) != CLASS || lex->GetToken(tk2) != Identifier)
721| return FALSE;
722|
723| Ptree* cspec = new PtreeClassSpec(new LeafReserved(tk1),
724| Ptree::Cons(new Leaf(tk2),nil),
725| nil);
726| decl = Ptree::Snoc(decl, cspec);
727| if(lex->LookAhead(0) == '='){
728| Ptree* default_type;
729| lex->GetToken(tk1);
730| if(!rTypeName(default_type))
731| return FALSE;
732|
733| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
734| default_type));
735| }
736| }
737| else{
738| Ptree *type_name, *arg;
739| Encoding type_encode, name_encode;
740| if(!rTypeSpecifier(type_name, TRUE, type_encode))
741| return FALSE;
742|
743| if(!rDeclarator(arg, kArgDeclarator, FALSE, type_encode, name_encode,
744| TRUE))
745| return FALSE;
746|
747| decl = Ptree::List(type_name, arg);
748| if(lex->LookAhead(0) == '='){
749| Ptree* exp;
750| lex->GetToken(tk1);
751| if(!rAdditiveExpr(exp))
752| return FALSE;
753|
754| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1), exp));
755| }
756| }
757|
758| return TRUE;
759| }
760|
761| /*
762| extern.template.decl
763| : EXTERN TEMPLATE declaration
764| */
765| bool Parser::rExternTemplateDecl(Ptree*& decl)
766| {
767| Token tk1, tk2;
768| Ptree* body;
769|
770| if(lex->GetToken(tk1) != EXTERN)
771| return FALSE;
772|
773| if(lex->GetToken(tk2) != TEMPLATE)
774| return FALSE;
775|
776| if(!rDeclaration(body))
777| return FALSE;
778|
779| decl = new PtreeExternTemplate(new Leaf(tk1),
780| Ptree::List(new Leaf(tk2), body));
781| return TRUE;
782| }
783|
784| /*
785| declaration
786| : integral.declaration
787| | const.declaration
788| | other.declaration
789|
790| decl.head
791| : {member.spec} {storage.spec} {member.spec} {cv.qualify}
792|
793| integral.declaration
794| : integral.decl.head declarators (';' | function.body)
795| | integral.decl.head ';'
796| | integral.decl.head ':' expression ';'
797|
798| integral.decl.head
799| : decl.head integral.or.class.spec {cv.qualify}
800|
801| other.declaration
802| : decl.head name {cv.qualify} declarators (';' | function.body)
803| | decl.head name constructor.decl (';' | function.body)
804| | FRIEND name ';'
805|
806| const.declaration
807| : cv.qualify {'*'} Identifier '=' expression {',' declarators} ';'
808|
809| Note: if you modify this function, look at declaration.statement, too.
810| Note: this regards a statement like "T (a);" as a constructor
811| declaration. See isConstructorDecl().
812| */
813| bool Parser::rDeclaration(Ptree*& statement)
814| {
815| Ptree *mem_s, *storage_s, *cv_q, *integral, *head;
816| Encoding type_encode;
817| int res;
818|
819| lex->LookAhead(0);
820| comments = lex->GetComments();
821|
822| if(!optMemberSpec(mem_s) || !optStorageSpec(storage_s))
823| return FALSE;
824|
825| if(mem_s == nil)
826| head = nil;
827| else
828| head = mem_s; // mem_s is a lis
829|
830| if(storage_s != nil)
831| head = Ptree::Snoc(head, storage_s);
832|
833| if(mem_s == nil)
834| if(optMemberSpec(mem_s))
835| head = Ptree::Nconc(head, mem_s);
836| else
837| return FALSE;
838|
839| if(!optCvQualify(cv_q)
840| || !optIntegralTypeOrClassSpec(integral, type_encode))
841| return FALSE;
842|
843| if(integral != nil)
844| res = rIntegralDeclaration(statement, type_encode,
845| head, integral, cv_q);
846| else{
847| type_encode.Clear();
848| int t = lex->LookAhead(0);
849| if(cv_q != nil && ((t == Identifier && lex->LookAhead(1) == '=')
850| || t == '*'))
851| res = rConstDeclaration(statement, type_encode, head, cv_q);
852| else
853| res = rOtherDeclaration(statement, type_encode,
854| mem_s, cv_q, head);
855| }
856| if (res && statement && (statement->What() == ntDeclaration))
857| static_cast<PtreeDeclaration*>(statement)->SetComments(comments);
858| return res;
859| }
860|
861| bool Parser::rIntegralDeclaration(Ptree*& statement, Encoding& type_encode,
862| Ptree* head, Ptree* integral, Ptree* cv_q)
863| {
864| Token tk;
865| Ptree *cv_q2, *decl;
866|
867| if(!optCvQualify(cv_q2))
868| return FALSE;
869|
870| if(cv_q != nil)
871| if(cv_q2 == nil)
872| integral = Ptree::Snoc(cv_q, integral);
873| else
874| integral = Ptree::Nconc(cv_q, Ptree::Cons(integral, cv_q2));
875| else if(cv_q2 != nil)
876| integral = Ptree::Cons(integral, cv_q2);
877|
878| type_encode.CvQualify(cv_q, cv_q2);
879| switch(lex->LookAhead(0)){
880| case ';' :
881| lex->GetToken(tk);
882| statement = new PtreeDeclaration(head, Ptree::List(integral,
883| new Leaf(tk)));
884| return TRUE;
885| case ':' : // bit fie
886| lex->GetToken(tk);
887| if(!rExpression(decl))
888| return FALSE;
889|
890| decl = Ptree::List(Ptree::List(new Leaf(tk), decl));
891| if(lex->GetToken(tk) != ';')
892| return FALSE;
893|
894| statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
895| new Leaf(tk)));
896| return TRUE;
897| default :
898| if(!rDeclarators(decl, type_encode, TRUE))
899| return FALSE;
900|
901| if(lex->LookAhead(0) == ';'){
902| lex->GetToken(tk);
903| statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
904| new Leaf(tk)));
905| return TRUE;
906| }
907| else{
908| Ptree* body;
909| if(!rFunctionBody(body))
910| return FALSE;
911|
912| if(Ptree::Length(decl) != 1)
913| return FALSE;
914|
915| statement = new PtreeDeclaration(head,
916| Ptree::List(integral,
917| decl->Car(), body));
918| return TRUE;
919| }
920| }
921| }
922|
923| bool Parser::rConstDeclaration(Ptree*& statement, Encoding&,
924| Ptree* head, Ptree* cv_q)
925| {
926| Ptree* decl;
927| Token tk;
928| Encoding type_encode;
929|
930| type_encode.SimpleConst();
931| if(!rDeclarators(decl, type_encode, FALSE))
932| return FALSE;
933|
934| if(lex->LookAhead(0) != ';')
935| return FALSE;
936|
937| lex->GetToken(tk);
938| statement = new PtreeDeclaration(head, Ptree::List(cv_q, decl,
939| new Leaf(tk)));
940| return TRUE;
941| }
942|
943| bool Parser::rOtherDeclaration(Ptree*& statement, Encoding& type_encode,
944| Ptree* mem_s, Ptree* cv_q, Ptree* head)
945| {
946| Ptree *type_name, *decl, *cv_q2;
947| Token tk;
948|
949| if(!rName(type_name, type_encode))
950| return FALSE;
951|
952| if(cv_q == nil && isConstructorDecl()){
953| Encoding ftype_encode;
954| if(!rConstructorDecl(decl, ftype_encode))
955| return FALSE;
956|
957| decl = Ptree::List(new PtreeDeclarator(type_name, decl,
958| ftype_encode, type_encode,
959| type_name));
960| type_name = nil;
961| }
962| else if(mem_s != nil && lex->LookAhead(0) == ';'){
963| // FRIEND name ';'
964| if(Ptree::Length(mem_s) == 1 && mem_s->Car()->What() == FRIEND){
965| lex->GetToken(tk);
966| statement = new PtreeDeclaration(head, Ptree::List(type_name,
967| new Leaf(tk)));
968| return TRUE;
969| }
970| else
971| return FALSE;
972| }
973| else{
974| if(!optCvQualify(cv_q2))
975| return FALSE;
976|
977| if(cv_q != nil)
978| if(cv_q2 == nil)
979| type_name = Ptree::Snoc(cv_q, type_name);
980| else
981| type_name = Ptree::Nconc(cv_q, Ptree::Cons(type_name, cv_q2));
982| else if(cv_q2 != nil)
983| type_name = Ptree::Cons(type_name, cv_q2);
984|
985| type_encode.CvQualify(cv_q, cv_q2);
986| if(!rDeclarators(decl, type_encode, FALSE))
987| return FALSE;
988| }
989|
990| if(lex->LookAhead(0) == ';'){
991| lex->GetToken(tk);
992| statement = new PtreeDeclaration(head, Ptree::List(type_name, decl,
993| new Leaf(tk)));
994| }
995| else{
996| Ptree* body;
997| if(!rFunctionBody(body))
998| return FALSE;
999|
1000| if(Ptree::Length(decl) != 1)
1001| return FALSE;
1002|
1003| statement = new PtreeDeclaration(head, Ptree::List(type_name,
1004| decl->Car(), body));
1005| }
1006|
1007| return TRUE;
1008| }
1009|
1010| /*
1011| This returns TRUE for an declaration like:
1012| T (a);
1013| even if a is not a type name. This is a bug according to the ANSI
1014| specification, but I believe none says "T (a);" for a variable
1015| declaration.
1016| */
1017| bool Parser::isConstructorDecl()
1018| {
1019| if(lex->LookAhead(0) != '(')
1020| return FALSE;
1021| else{
1022| int t = lex->LookAhead(1);
1023| if(t == '*' || t == '&' || t == '(')
1024| return FALSE; // decl
1025| else if(t == CONST || t == VOLATILE)
1026| return TRUE; // constructor or dec
1027| else if(isPtrToMember(1))
1028| return FALSE; // declarator
1029| else
1030| return TRUE;
1031| }
1032| }
1033|
1034| /*
1035| ptr.to.member
1036| : {'::'} (identifier {'<' any* '>'} '::')+ '*'
1037| */
1038| bool Parser::isPtrToMember(int i)
1039| {
1040| int t0 = lex->LookAhead(i++);
1041|
1042| if(t0 == Scope)
1043| t0 = lex->LookAhead(i++);
1044|
1045| while(t0 == Identifier){
1046| int t = lex->LookAhead(i++);
1047| if(t == '<'){
1048| int n = 1;
1049| while(n > 0){
1050| int u = lex->LookAhead(i++);
1051| if(u == '<')
1052| ++n;
1053| else if(u == '>')
1054| --n;
1055| else if(u == '('){
1056| int m = 1;
1057| while(m > 0){
1058| int v = lex->LookAhead(i++);
1059| if(v == '(')
1060| ++m;
1061| else if(v == ')')
1062| --m;
1063| else if(v == '\0' || v == ';' || v == '}')
1064| return FALSE;
1065| }
1066| }
1067| else if(u == '\0' || u == ';' || u == '}')
1068| return FALSE;
1069| }
1070|
1071| t = lex->LookAhead(i++);
1072| }
1073|
1074| if(t != Scope)
1075| return FALSE;
1076|
1077| t0 = lex->LookAhead(i++);
1078| if(t0 == '*')
1079| return TRUE;
1080| }
1081|
1082| return FALSE;
1083| }
1084|
1085| /*
1086| member.spec
1087| : (FRIEND | INLINE | VIRTUAL | userdef.keyword)+
1088| */
1089| bool Parser::optMemberSpec(Ptree*& p)
1090| {
1091| Token tk;
1092| Ptree* lf;
1093| int t = lex->LookAhead(0);
1094|
1095| p = nil;
1096| while(t == FRIEND || t == INLINE || t == VIRTUAL || t == UserKeyword5){
1097| if(t == UserKeyword5){
1098| if(!rUserdefKeyword(lf))
1099| return FALSE;
1100| }
1101| else{
1102| lex->GetToken(tk);
1103| if(t == INLINE)
1104| lf = new LeafINLINE(tk);
1105| else if(t == VIRTUAL)
1106| lf = new LeafVIRTUAL(tk);
1107| else
1108| lf = new LeafFRIEND(tk);
1109| }
1110|
1111| p = Ptree::Snoc(p, lf);
1112| t = lex->LookAhead(0);
1113| }
1114|
1115| return TRUE;
1116| }
1117|
1118| /*
1119| storage.spec : STATIC | EXTERN | AUTO | REGISTER | MUTABLE
1120| */
1121| bool Parser::optStorageSpec(Ptree*& p)
1122| {
1123| int t = lex->LookAhead(0);
1124| if(t == STATIC || t == EXTERN || t == AUTO || t == REGISTER
1125| || t == MUTABLE){
1126| Token tk;
1127| lex->GetToken(tk);
1128| switch(t){
1129| case STATIC :
1130| p = new LeafSTATIC(tk);
1131| break;
1132| case EXTERN :
1133| p = new LeafEXTERN(tk);
1134| break;
1135| case AUTO :
1136| p = new LeafAUTO(tk);
1137| break;
1138| case REGISTER :
1139| p = new LeafREGISTER(tk);
1140| break;
1141| case MUTABLE :
1142| p = new LeafMUTABLE(tk);
1143| break;
1144| default :
1145| MopErrorMessage("optStorageSpec()", "fatal");
1146| break;
1147| }
1148| }
1149| else
1150| p = nil; // no storage sp
1151|
1152| return TRUE;
1153| }
1154|
1155| /*
1156| cv.qualify : (CONST | VOLATILE)+
1157| */
1158| bool Parser::optCvQualify(Ptree*& cv)
1159| {
1160| Ptree* p = nil;
1161| for(;;){
1162| int t = lex->LookAhead(0);
1163| if(t == CONST || t == VOLATILE){
1164| Token tk;
1165| lex->GetToken(tk);
1166| switch(t){
1167| case CONST :
1168| p = Ptree::Snoc(p, new LeafCONST(tk));
1169| break;
1170| case VOLATILE :
1171| p = Ptree::Snoc(p, new LeafVOLATILE(tk));
1172| break;
1173| default :
1174| MopErrorMessage("optCvQualify()", "fatal");
1175| break;
1176| }
1177| }
1178| else
1179| break;
1180| }
1181|
1182| cv = p;
1183| return TRUE;
1184| }
1185|
1186| /*
1187| integral.or.class.spec
1188| : (CHAR | INT | SHORT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE
1189| | VOID | BOOLEAN)+
1190| | class.spec
1191| | enum.spec
1192|
1193| Note: if editing this, see also isTypeSpecifier().
1194| */
1195| bool Parser::optIntegralTypeOrClassSpec(Ptree*& p, Encoding& encode)
1196| {
1197| bool is_integral;
1198| int t;
1199| char type = ' ', flag = ' ';
1200|
1201| is_integral = FALSE;
1202| p = nil;
1203| for(;;){
1204| t = lex->LookAhead(0);
1205| if(t == CHAR || t == INT || t == SHORT || t == LONG || t == SIGNED
1206| || t == UNSIGNED || t == FLOAT || t == DOUBLE || t == VOID
1207| || t == BOOLEAN
1208| #if defined(_MSC_VER)
1209| || t == INT64
1210| #endif
1211| ){
1212| Token tk;
1213| Ptree* kw;
1214| lex->GetToken(tk);
1215| switch(t){
1216| case CHAR :
1217| type = 'c';
1218| kw = new LeafCHAR(tk);
1219| break;
1220| case INT :
1221| #if defined(_MSC_VER)
1222| case INT64 : // an int64 is *NOT* an int but...
1223| #endif
1224| if(type != 's' && type != 'l' && type != 'j' && type != 'r')
1225| type = 'i';
1226|
1227| kw = new LeafINT(tk);
1228| break;
1229| case SHORT :
1230| type = 's';
1231| kw = new LeafSHORT(tk);
1232| break;
1233| case LONG :
1234| if(type == 'l')
1235| type = 'j';
1236| else if(type == 'd')
1237| type = 'r';
1238| else
1239| type = 'l';
1240|
1241| kw = new LeafLONG(tk);
1242| break;
1243| case SIGNED :
1244| flag = 'S';
1245| kw = new LeafSIGNED(tk);
1246| break;
1247| case UNSIGNED :
1248| flag = 'U';
1249| kw = new LeafUNSIGNED(tk);
1250| break;
1251| case FLOAT :
1252| type = 'f';
1253| kw = new LeafFLOAT(tk);
1254| break;
1255| case DOUBLE :
1256| if(type == 'l')
1257| type = 'r';
1258| else
1259| type = 'd';
1260|
1261| kw = new LeafDOUBLE(tk);
1262| break;
1263| case VOID :
1264| type = 'v';
1265| kw = new LeafVOID(tk);
1266| break;
1267| case BOOLEAN :
1268| type = 'b';
1269| kw = new LeafBOOLEAN(tk);
1270| break;
1271| default :
1272| MopErrorMessage("optIntegralTypeOrClassSpec()", "fatal");
1273| kw = nil;
1274| break;
1275| }
1276|
1277| p = Ptree::Snoc(p, kw);
1278| is_integral = TRUE;
1279| }
1280| else
1281| break;
1282| }
1283|
1284| if(is_integral){
1285| if(flag == 'S' && type != 'c')
1286| flag = ' ';
1287|
1288| if(flag != ' ')
1289| encode.Append(flag);
1290|
1291| if(type == ' ')
1292| type = 'i'; // s
1293|
1294| encode.Append(type);
1295| return TRUE;
1296| }
1297|
1298| if(t == CLASS || t == STRUCT || t == UNION || t == UserKeyword)
1299| return rClassSpec(p, encode);
1300| else if(t == ENUM)
1301| return rEnumSpec(p, encode);
1302| else{
1303| p = nil;
1304| return TRUE;
1305| }
1306| }
1307|
1308| /*
1309| constructor.decl
1310| : '(' {arg.decl.list} ')' {cv.qualify} {throw.decl}
1311| {member.initializers} {'=' Constant}
1312| */
1313| bool Parser::rConstructorDecl(Ptree*& constructor, Encoding& encode)
1314| {
1315| Token op, cp;
1316| Ptree *args, *cv, *throw_decl, *mi;
1317|
1318| if(lex->GetToken(op) != '(')
1319| return FALSE;
1320|
1321| if(lex->LookAhead(0) == ')'){
1322| args = nil;
1323| encode.StartFuncArgs();
1324| encode.Void();
1325| encode.EndFuncArgs();
1326| }
1327| else
1328| if(!rArgDeclList(args, encode))
1329| return FALSE;
1330|
1331| lex->GetToken(cp);
1332| constructor = Ptree::List(new Leaf(op), args, new Leaf(cp));
1333| optCvQualify(cv);
1334| if(cv != nil){
1335| encode.CvQualify(cv);
1336| constructor = Ptree::Nconc(constructor, cv);
1337| }
1338|
1339| optThrowDecl(throw_decl); // ignore in this vers
1340|
1341| if(lex->LookAhead(0) == ':')
1342| if(rMemberInitializers(mi))
1343| constructor = Ptree::Snoc(constructor, mi);
1344| else
1345| return FALSE;
1346|
1347| if(lex->LookAhead(0) == '='){
1348| Token eq, zero;
1349| lex->GetToken(eq);
1350| if(lex->GetToken(zero) != Constant)
1351| return FALSE;
1352|
1353| constructor = Ptree::Nconc(constructor,
1354| Ptree::List(new Leaf(eq), new Leaf(zero)));
1355| }
1356|
1357| encode.NoReturnType();
1358| return TRUE;
1359| }
1360|
1361| /*
1362| throw.decl : THROW '(' (name {','})* {name} ')'
1363| */
1364| bool Parser::optThrowDecl(Ptree*& throw_decl)
1365| {
1366| Token tk;
1367| int t;
1368| Ptree* p = nil;
1369|
1370| if(lex->LookAhead(0) == THROW){
1371| lex->GetToken(tk);
1372| p = Ptree::Snoc(p, new LeafReserved(tk));
1373|
1374| if(lex->GetToken(tk) != '(')
1375| return FALSE;
1376|
1377| p = Ptree::Snoc(p, new Leaf(tk));
1378|
1379| for(;;){
1380| Ptree* q;
1381| Encoding encode;
1382| t = lex->LookAhead(0);
1383| if(t == '\0')
1384| return FALSE;
1385| else if(t == ')')
1386| break;
1387| else if(rName(q, encode))
1388| p = Ptree::Snoc(p, q);
1389| else
1390| return FALSE;
1391|
1392| if(lex->LookAhead(0) == ','){
1393| lex->GetToken(tk);
1394| p = Ptree::Snoc(p, new Leaf(tk));
1395| }
1396| else
1397| break;
1398| }
1399|
1400| if(lex->GetToken(tk) != ')')
1401| return FALSE;
1402|
1403| p = Ptree::Snoc(p, new Leaf(tk));
1404| }
1405|
1406| throw_decl = p;
1407| return TRUE;
1408| }
1409|
1410| /*
1411| declarators : declarator.with.init (',' declarator.with.init)*
1412|
1413| is_statement changes the behavior of rArgDeclListOrInit().
1414| */
1415| bool Parser::rDeclarators(Ptree*& decls, Encoding& type_encode,
1416| bool should_be_declarator, bool is_statement)
1417| {
1418| Ptree* d;
1419| Token tk;
1420| Encoding encode;
1421|
1422| decls = nil;
1423| for(;;){
1424|
1425| lex->LookAhead(0);
1426| Ptree *comments = lex->GetComments();
1427|
1428| encode.Reset(type_encode);
1429| if(!rDeclaratorWithInit(d, encode, should_be_declarator, is_statement))
1430| return FALSE;
1431|
1432| if (d && (d->What() == ntDeclarator))
1433| static_cast<PtreeDeclarator*>(d)->SetComments(comments);
1434|
1435| decls = Ptree::Snoc(decls, d);
1436| if(lex->LookAhead(0) == ','){
1437| lex->GetToken(tk);
1438| decls = Ptree::Snoc(decls, new Leaf(tk));
1439| }
1440| else
1441| return TRUE;
1442| };
1443| }
1444|
1445| /*
1446| declarator.with.init
1447| : ':' expression
1448| | declarator {'=' initialize.expr | ':' expression}
1449| */
1450| bool Parser::rDeclaratorWithInit(Ptree*& dw, Encoding& type_encode,
1451| bool should_be_declarator,
1452| bool is_statement)
1453| {
1454| Ptree *d, *e;
1455| Token tk;
1456| Encoding name_encode;
1457|
1458| if(lex->LookAhead(0) == ':'){ // bi
1459| lex->GetToken(tk);
1460| if(!rExpression(e))
1461| return FALSE;
1462|
1463| dw = Ptree::List(new Leaf(tk), e);
1464| return TRUE;
1465| }
1466| else{
1467| if(!rDeclarator(d, kDeclarator, FALSE, type_encode, name_encode,
1468| should_be_declarator, is_statement))
1469| return FALSE;
1470|
1471| int t = lex->LookAhead(0);
1472| if(t == '='){
1473| lex->GetToken(tk);
1474| if(!rInitializeExpr(e))
1475| return FALSE;
1476|
1477| dw = Ptree::Nconc(d, Ptree::List(new Leaf(tk), e));
1478| return TRUE;
1479| }
1480| else if(t == ':'){
1481| lex->GetToken(tk);
1482| if(!rExpression(e))
1483| return FALSE;
1484|
1485| dw = Ptree::Nconc(d, Ptree::List(new Leaf(tk), e));
1486| return TRUE;
1487| }
1488| else{
1489| dw = d;
1490| return TRUE;
1491| }
1492| }
1493| }
1494|
1495| /*
1496| declarator
1497| : (ptr.operator)* (name | '(' declarator ')')
1498| ('[' comma.expression ']')* {func.args.or.init}
1499|
1500| func.args.or.init
1501| : '(' arg.decl.list.or.init ')' {cv.qualify} {throw.decl}
1502| {member.initializers}
1503|
1504| Note: We assume that '(' declarator ')' is followed by '(' or '['.
1505| This is to avoid accepting a function call F(x) as a pair of
1506| a type F and a declarator x. This assumption is ignored
1507| if should_be_declarator is true.
1508|
1509| Note: An argument declaration list and a function-style initializer
1510| take a different Ptree structure.
1511| e.g.
1512| int f(char) ==> .. [f ( [[[char] nil]] )]
1513| Point f(1) ==> .. [f [( [1] )]]
1514|
1515| Note: is_statement changes the behavior of rArgDeclListOrInit().
1516| */
1517| bool Parser::rDeclarator(Ptree*& decl, DeclKind kind, bool recursive,
1518| Encoding& type_encode, Encoding& name_encode,
1519| bool should_be_declarator, bool is_statement)
1520| {
1521| return rDeclarator2(decl, kind, recursive, type_encode, name_encode,
1522| should_be_declarator, is_statement, nil);
1523| }
1524|
1525| bool Parser::rDeclarator2(Ptree*& decl, DeclKind kind, bool recursive,
1526| Encoding& type_encode, Encoding& name_encode,
1527| bool should_be_declarator, bool is_statement,
1528| Ptree** declared_name)
1529| {
1530| Encoding recursive_encode;
1531| Ptree *d;
1532| int t;
1533| bool recursive_decl = FALSE;
1534| Ptree *declared_name0 = nil;
1535|
1536| if(declared_name == nil)
1537| declared_name = &declared_name0;
1538|
1539| if(!optPtrOperator(d, type_encode))
1540| return FALSE;
1541|
1542| char* lex_save = lex->Save();
1543| t = lex->LookAhead(0);
1544| if(t == '('){
1545| Token op, cp;
1546| Ptree* decl2;
1547| lex->GetToken(op);
1548| recursive_decl = TRUE;
1549| if(!rDeclarator2(decl2, kind, TRUE, recursive_encode, name_encode,
1550| TRUE, FALSE, declared_name))
1551| return FALSE;
1552|
1553| if(lex->GetToken(cp) != ')')
1554| {
1555| if (kind != kCastDeclarator)
1556| return FALSE;
1557| lex->Restore(lex_save);
1558| name_encode.Clear();
1559| }
1560| else
1561| {
1562|
1563| if(!should_be_declarator)
1564| if(kind == kDeclarator && d == nil){
1565| t = lex->LookAhead(0);
1566| if(t != '[' && t != '(')
1567| return FALSE;
1568| }
1569|
1570| d = Ptree::Snoc(d, Ptree::List(new Leaf(op), decl2, new Leaf(cp)));
1571| }
1572| }
1573| else if(kind != kCastDeclarator){
1574| if (t == INLINE){
1575|
1576| Token i;
1577| lex->GetToken(i);
1578| t = lex->LookAhead(0);
1579| }
1580| if (kind == kDeclarator || t == Identifier || t == Scope){
1581|
1582| Ptree* name;
1583| if(rName(name, name_encode))
1584| d = Ptree::Snoc(d, name);
1585| else
1586| return FALSE;
1587|
1588| *declared_name = name;
1589| }
1590| }
1591| else
1592| name_encode.Clear(); // em
1593|
1594| for(;;){
1595| t = lex->LookAhead(0);
1596| if(t == '('){
1597| Encoding args_encode;
1598| Token op, cp;
1599| Ptree *args, *cv, *throw_decl, *mi;
1600| bool is_args = TRUE;
1601|
1602| lex->GetToken(op);
1603| if(lex->LookAhead(0) == ')'){
1604| args = nil;
1605| args_encode.StartFuncArgs();
1606| args_encode.Void();
1607| args_encode.EndFuncArgs();
1608| }
1609| else
1610| if(!rArgDeclListOrInit(args, is_args, args_encode,
1611| is_statement))
1612| return FALSE;
1613|
1614| if(lex->GetToken(cp) != ')')
1615| return FALSE;
1616|
1617| if(is_args){
1618| d = Ptree::Nconc(d, Ptree::List(new Leaf(op), args,
1619| new Leaf(cp)));
1620| optCvQualify(cv);
1621| if(cv != nil){
1622| args_encode.CvQualify(cv);
1623| d = Ptree::Nconc(d, cv);
1624| }
1625| }
1626| else
1627| d = Ptree::Snoc(d, Ptree::List(new Leaf(op), args,
1628| new Leaf(cp)));
1629|
1630| if(!args_encode.IsEmpty())
1631| type_encode.Function(args_encode);
1632|
1633| optThrowDecl(throw_decl); // ignore in this versi
1634|
1635| if(lex->LookAhead(0) == ':')
1636| if(rMemberInitializers(mi))
1637| d = Ptree::Snoc(d, mi);
1638| else
1639| return FALSE;
1640|
1641| break;
1642| }
1643| else if(t == '['){
1644| Token ob, cb;
1645| Ptree* expr;
1646| lex->GetToken(ob);
1647| if(lex->LookAhead(0) == ']')
1648| expr = nil;
1649| else
1650| if(!rCommaExpression(expr))
1651| return FALSE;
1652|
1653| if(lex->GetToken(cb) != ']')
1654| return FALSE;
1655|
1656| type_encode.Array();
1657| d = Ptree::Nconc(d, Ptree::List(new Leaf(ob), expr,
1658| new Leaf(cb)));
1659| }
1660| else
1661| break;
1662| }
1663|
1664| if(recursive_decl)
1665| type_encode.Recursion(recursive_encode);
1666|
1667| if(recursive)
1668| decl = d;
1669| else
1670| if(d == nil)
1671| decl = new PtreeDeclarator(type_encode, name_encode,
1672| *declared_name);
1673| else
1674| decl = new PtreeDeclarator(d, type_encode, name_encode,
1675| *declared_name);
1676|
1677| return TRUE;
1678| }
1679|
1680| /*
1681| ptr.operator
1682| : (('*' | '&' | ptr.to.member) {cv.qualify})+
1683| */
1684| bool Parser::optPtrOperator(Ptree*& ptrs, Encoding& encode)
1685| {
1686| ptrs = nil;
1687| for(;;){
1688| int t = lex->LookAhead(0);
1689| if(t != '*' && t != '&' && !isPtrToMember(0))
1690| break;
1691| else{
1692| Ptree *op, *cv;
1693| if(t == '*' || t == '&'){
1694| Token tk;
1695| lex->GetToken(tk);
1696| op = new Leaf(tk);
1697| encode.PtrOperator(t);
1698| }
1699| else
1700| if(!rPtrToMember(op, encode))
1701| return FALSE;
1702|
1703| ptrs = Ptree::Snoc(ptrs, op);
1704| optCvQualify(cv);
1705| if(cv != nil){
1706| ptrs = Ptree::Nconc(ptrs, cv);
1707| encode.CvQualify(cv);
1708| }
1709| }
1710| }
1711|
1712| return TRUE;
1713| }
1714|
1715| /*
1716| member.initializers
1717| : ':' member.init (',' member.init)*
1718| */
1719| bool Parser::rMemberInitializers(Ptree*& init)
1720| {
1721| Token tk;
1722| Ptree* m;
1723|
1724| if(lex->GetToken(tk) != ':')
1725| return FALSE;
1726|
1727| init = Ptree::List(new Leaf(tk));
1728| if(!rMemberInit(m))
1729| return FALSE;
1730|
1731| init = Ptree::Snoc(init, m);
1732| while(lex->LookAhead(0) == ','){
1733| lex->GetToken(tk);
1734| init = Ptree::Snoc(init, new Leaf(tk));
1735| if(!rMemberInit(m))
1736| return FALSE;
1737|
1738| init = Ptree::Snoc(init, m);
1739| }
1740|
1741| return TRUE;
1742| }
1743|
1744| /*
1745| member.init
1746| : name '(' function.arguments ')'
1747| */
1748| bool Parser::rMemberInit(Ptree*& init)
1749| {
1750| Ptree *name, *args;
1751| Token tk1, tk2;
1752| Encoding encode;
1753|
1754| if(!rName(name, encode))
1755| return FALSE;
1756|
1757| if(!name->IsLeaf())
1758| name = new PtreeName(name, encode);
1759|
1760| if(lex->GetToken(tk1) != '(')
1761| return FALSE;
1762|
1763| if(!rFunctionArguments(args))
1764| return FALSE;
1765|
1766| if(lex->GetToken(tk2) != ')')
1767| return FALSE;
1768|
1769| init = Ptree::List(name, new Leaf(tk1), args, new Leaf(tk2));
1770| return TRUE;
1771| }
1772|
1773| /*
1774| name : {'::'} name2 ('::' name2)*
1775|
1776| name2
1777| : Identifier {template.args}
1778| | '~' Identifier
1779| | OPERATOR operator.name {template.args}
1780|
1781| Don't use this function for parsing an expression
1782| It always regards '<' as the beginning of template arguments.
1783| */
1784| bool Parser::rName(Ptree*& name, Encoding& encode)
1785| {
1786| Token tk, tk2;
1787| int t;
1788| int length = 0;
1789|
1790| if(lex->LookAhead(0) == Scope){
1791| lex->GetToken(tk);
1792| name = Ptree::List(new Leaf(tk));
1793| encode.GlobalScope();
1794| ++length;
1795| }
1796| else
1797| {
1798| name = nil;
1799|
1800| // gcc keyword typeof(rName) means type of the given name
1801| if(lex->LookAhead(0) == TYPEOF){
1802| t = lex->GetToken(tk);
1803| if ((t = lex->GetToken(tk2)) != '(')
1804| return FALSE;
1805| Ptree* type = Ptree::List(new Leaf(tk2));
1806| Encoding name_encode;
1807| if (!rName(name, name_encode))
1808| return FALSE;
1809| if (!name->IsLeaf())
1810| name = new PtreeName(name, name_encode);
1811| else
1812| name = new PtreeName(Ptree::List(name), name_encode);
1813| type = Ptree::Snoc(type, name);
1814| if ((t = lex->GetToken(tk2)) != ')')
1815| return FALSE;
1816| type = Ptree::Snoc(type, new Leaf(tk2));
1817| name = new PtreeTypeofExpr(new Leaf(tk), type);
1818| return TRUE;
1819| }
1820| }
1821|
1822|
1823| for(;;){
1824| t = lex->GetToken(tk);
1825| if(t == TEMPLATE) {
1826| // Skip template token, next will be identifier
1827| t = lex->GetToken(tk);
1828| }
1829| if(t == Identifier){
1830| Ptree* n = new Leaf(tk);
1831| t = lex->LookAhead(0);
1832| if(t == '<'){
1833| Ptree* args;
1834| Encoding args_encode;
1835| if(!rTemplateArgs(args, args_encode))
1836| return FALSE;
1837|
1838| encode.Template(n, args_encode);
1839| ++length;
1840| n = Ptree::List(n, args);
1841| t = lex->LookAhead(0);
1842| }
1843| else{
1844| encode.SimpleName(n);
1845| ++length;
1846| }
1847|
1848| if(t == Scope){
1849| lex->GetToken(tk);
1850| name = Ptree::Nconc(name, Ptree::List(n, new Leaf(tk)));
1851| }
1852| else{
1853| if(name == nil)
1854| name = n;
1855| else
1856| name = Ptree::Snoc(name, n);
1857|
1858| if(length > 1)
1859| encode.Qualified(length);
1860|
1861| return TRUE;
1862| }
1863| }
1864| else if(t == '~'){
1865| if(lex->LookAhead(0) != Identifier)
1866| return FALSE;
1867|
1868| lex->GetToken(tk2);
1869| Ptree* class_name = new Leaf(tk2);
1870| Ptree* dt = Ptree::List(new Leaf(tk), class_name);
1871| if(name == nil)
1872| name = dt;
1873| else
1874| name = Ptree::Snoc(name, dt);
1875|
1876| encode.Destructor(class_name);
1877| if(length > 0)
1878| encode.Qualified(length + 1);
1879|
1880| return TRUE;
1881| }
1882| else if(t == OPERATOR){
1883| Ptree* op;
1884| Ptree* opf;
1885| if(!rOperatorName(op, encode))
1886| return FALSE;
1887|
1888| t = lex->LookAhead(0);
1889| if(t != '<')
1890| opf = Ptree::List(new LeafReserved(tk), op);
1891| else {
1892| Ptree* args;
1893| Encoding args_encode;
1894| if(!rTemplateArgs(args, args_encode))
1895| return FALSE;
1896|
1897| // here, I must merge args_encode into encode.
1898| // I'll do it in future. :p
1899|
1900| opf = Ptree::List(new LeafReserved(tk), op, args);
1901| }
1902|
1903| if(name == nil)
1904| name = opf;
1905| else
1906| name = Ptree::Snoc(name, opf);
1907|
1908| if(length > 0)
1909| encode.Qualified(length + 1);
1910|
1911| return TRUE;
1912| }
1913| else
1914| return FALSE;
1915| }
1916| }
1917|
1918| /*
1919| operator.name
1920| : '+' | '-' | '*' | '/' | '%' | '^' | '&' | '|' | '~'
1921| | '!' | '=' | '<' | '>' | AssignOp | ShiftOp | EqualOp
1922| | RelOp | LogAndOp | LogOrOp | IncOp | ',' | PmOp | ArrowOp
1923| | NEW {'[' ']'}
1924| | DELETE {'[' ']'}
1925| | '(' ')'
1926| | '[' ']'
1927| | cast.operator.name
1928| */
1929| bool Parser::rOperatorName(Ptree*& name, Encoding& encode)
1930| {
1931| Token tk;
1932|
1933| int t = lex->LookAhead(0);
1934| if(t == '+' || t == '-' || t == '*' || t == '/' || t == '%' || t == '^'
1935| || t == '&' || t == '|' || t == '~' || t == '!' || t == '=' || t == '<'
1936| || t == '>' || t == AssignOp || t == ShiftOp || t == EqualOp
1937| || t == RelOp || t == LogAndOp || t == LogOrOp || t == IncOp
1938| || t == ',' || t == PmOp || t == ArrowOp){
1939| lex->GetToken(tk);
1940| name = new Leaf(tk);
1941| encode.SimpleName(name);
1942| return TRUE;
1943| }
1944| else if(t == NEW || t == DELETE){
1945| lex->GetToken(tk);
1946| if(lex->LookAhead(0) != '['){
1947| name = new LeafReserved(tk);
1948| encode.SimpleName(name);
1949| return TRUE;
1950| }
1951| else{
1952| name = Ptree::List(new LeafReserved(tk));
1953| lex->GetToken(tk);
1954| name = Ptree::Snoc(name, new Leaf(tk));
1955| if(lex->GetToken(tk) != ']')
1956| return FALSE;
1957|
1958| name = Ptree::Snoc(name, new Leaf(tk));
1959| if(t == NEW)
1960| encode.AppendWithLen("new[]", 5);
1961| else
1962| encode.AppendWithLen("delete[]", 8);
1963|
1964| return TRUE;
1965| }
1966| }
1967| else if(t == '('){
1968| lex->GetToken(tk);
1969| name = Ptree::List(new Leaf(tk));
1970| if(lex->GetToken(tk) != ')')
1971| return FALSE;
1972|
1973| encode.AppendWithLen("()", 2);
1974| name = Ptree::Snoc(name, new Leaf(tk));
1975| return TRUE;
1976| }
1977| else if(t == '['){
1978| lex->GetToken(tk);
1979| name = Ptree::List(new Leaf(tk));
1980| if(lex->GetToken(tk) != ']')
1981| return FALSE;
1982|
1983| encode.AppendWithLen("[]", 2);
1984| name = Ptree::Snoc(name, new Leaf(tk));
1985| return TRUE;
1986| }
1987| else
1988| return rCastOperatorName(name, encode);
1989| }
1990|
1991| /*
1992| cast.operator.name
1993| : {cv.qualify} (integral.or.class.spec | name) {cv.qualify}
1994| {(ptr.operator)*}
1995| */
1996| bool Parser::rCastOperatorName(Ptree*& name, Encoding& encode)
1997| {
1998| Ptree *cv1, *cv2, *type_name, *ptr;
1999| Encoding type_encode;
2000|
2001| if(!optCvQualify(cv1))
2002| return FALSE;
2003|
2004| if(!optIntegralTypeOrClassSpec(type_name, type_encode))
2005| return FALSE;
2006|
2007| if(type_name == nil){
2008| type_encode.Clear();
2009| if(!rName(type_name, type_encode))
2010| return FALSE;
2011| }
2012|
2013| if(!optCvQualify(cv2))
2014| return FALSE;
2015|
2016| if(cv1 != nil)
2017| if(cv2 == nil)
2018| type_name = Ptree::Snoc(cv1, type_name);
2019| else
2020| type_name = Ptree::Nconc(cv1, Ptree::Cons(type_name, cv2));
2021| else if(cv2 != nil)
2022| type_name = Ptree::Cons(type_name, cv2);
2023|
2024| type_encode.CvQualify(cv1, cv2);
2025|
2026| if(!optPtrOperator(ptr, type_encode))
2027| return FALSE;
2028|
2029| encode.CastOperator(type_encode);
2030| if(ptr == nil){
2031| name = type_name;
2032| return TRUE;
2033| }
2034| else{
2035| name = Ptree::List(type_name, ptr);
2036| return TRUE;
2037| }
2038| }
2039|
2040| /*
2041| ptr.to.member
2042| : {'::'} (identifier {template.args} '::')+ '*'
2043| */
2044| bool Parser::rPtrToMember(Ptree*& ptr_to_mem, Encoding& encode)
2045| {
2046| Token tk;
2047| Ptree *p, *n;
2048| Encoding pm_encode;
2049| int length = 0;
2050|
2051| if(lex->LookAhead(0) == Scope){
2052| lex->GetToken(tk);
2053| p = Ptree::List(new Leaf(tk));
2054| pm_encode.GlobalScope();
2055| ++length;
2056| }
2057| else
2058| p = nil;
2059|
2060| for(;;){
2061| if(lex->GetToken(tk) == Identifier)
2062| n = new Leaf(tk);
2063| else
2064| return FALSE;
2065|
2066| int t = lex->LookAhead(0);
2067| if(t == '<'){
2068| Ptree* args;
2069| Encoding args_encode;
2070| if(!rTemplateArgs(args, args_encode))
2071| return FALSE;
2072|
2073| pm_encode.Template(n, args_encode);
2074| ++length;
2075| n = Ptree::List(n, args);
2076| t = lex->LookAhead(0);
2077| }
2078| else{
2079| pm_encode.SimpleName(n);
2080| ++length;
2081| }
2082|
2083| if(lex->GetToken(tk) != Scope)
2084| return FALSE;
2085|
2086| p = Ptree::Nconc(p, Ptree::List(n, new Leaf(tk)));
2087| if(lex->LookAhead(0) == '*'){
2088| lex->GetToken(tk);
2089| p = Ptree::Snoc(p, new Leaf(tk));
2090| break;
2091| }
2092| }
2093|
2094| ptr_to_mem = p;
2095| encode.PtrToMember(pm_encode, length);
2096| return TRUE;
2097| }
2098|
2099| /*
2100| template.args
2101| : '<' '>'
2102| | '<' template.argument {',' template.argument} '>'
2103|
2104| template.argument
2105| : type.name
2106| | logical.or.expr
2107| */
2108| bool Parser::rTemplateArgs(Ptree*& temp_args, Encoding& encode)
2109| {
2110| Token tk1, tk2;
2111| Encoding type_encode;
2112|
2113| if(lex->GetToken(tk1) != '<')
2114| return FALSE;
2115|
2116| // in case of Foo<>
2117| if(lex->LookAhead(0) == '>') {
2118| lex->GetToken(tk2);
2119| temp_args = Ptree::List(new Leaf(tk1), new Leaf(tk2));
2120| return TRUE;
2121| }
2122|
2123| Ptree* args = nil;
2124| for(;;){
2125| Ptree* a;
2126| char* pos = lex->Save();
2127| type_encode.Clear();
2128|
2129| // Prefer type name, but if not ',' or '>' then must be expression
2130| if(rTypeName(a, type_encode) && (lex->LookAhead(0) == ',' || lex->LookAhead(0) == '>'))
2131| encode.Append(type_encode);
2132| else {
2133| lex->Restore(pos);
2134| if(!rLogicalOrExpr(a, TRUE))
2135| return FALSE;
2136|
2137| encode.ValueTempParam();
2138| }
2139|
2140| args = Ptree::Snoc(args, a);
2141| switch(lex->GetToken(tk2)){
2142| case '>' :
2143| temp_args = Ptree::List(new Leaf(tk1), args, new Leaf(tk2));
2144| return TRUE;
2145| case ',' :
2146| args = Ptree::Snoc(args, new Leaf(tk2));
2147| break;
2148| case ShiftOp :
2149| if(*tk2.ptr == '>'){
2150| lex->GetOnlyClosingBracket(tk2);
2151| temp_args = Ptree::List(new Leaf(tk1), args,
2152| new Leaf(tk2.ptr, 1));
2153| return TRUE;
2154| }
2155|
2156| default :
2157| return FALSE;
2158| }
2159| }
2160| }
2161|
2162| /*
2163| arg.decl.list.or.init
2164| : arg.decl.list
2165| | function.arguments
2166|
2167| This rule accepts function.arguments to parse declarations like:
2168| Point p(1, 3);
2169| "(1, 3)" is arg.decl.list.or.init.
2170|
2171| If maybe_init is true, we first examine whether tokens construct
2172| function.arguments. This ordering is significant if tokens are
2173| Point p(s, t);
2174| s and t can be type names or variable names.
2175| */
2176| bool Parser::rArgDeclListOrInit(Ptree*& arglist, bool& is_args,
2177| Encoding& encode, bool maybe_init)
2178| {
2179| char* pos = lex->Save();
2180| if(maybe_init) {
2181| if(rFunctionArguments(arglist))
2182| if(lex->LookAhead(0) == ')') {
2183| is_args = FALSE;
2184| encode.Clear();
2185| return TRUE;
2186| }
2187|
2188| lex->Restore(pos);
2189| return(is_args = rArgDeclList(arglist, encode));
2190| }
2191| else
2192| if(is_args = rArgDeclList(arglist, encode))
2193| return TRUE;
2194| else{
2195| lex->Restore(pos);
2196| encode.Clear();
2197| return rFunctionArguments(arglist);
2198| }
2199| }
2200|
2201| /*
2202| arg.decl.list
2203| : empty
2204| | arg.declaration ( ',' arg.declaration )* {{ ',' } Ellipses}
2205| */
2206| bool Parser::rArgDeclList(Ptree*& arglist, Encoding& encode)
2207| {
2208| Ptree* list;
2209| Ptree* d;
2210| int t;
2211| Token tk;
2212| Encoding arg_encode;
2213|
2214| encode.StartFuncArgs();
2215| list = nil;
2216| for(;;){
2217| arg_encode.Clear();
2218| t = lex->LookAhead(0);
2219| if(t == ')'){
2220| if(list == nil)
2221| encode.Void();
2222|
2223| arglist = list;
2224| break;
2225| }
2226| else if(t == Ellipsis){
2227| lex->GetToken(tk);
2228| encode.EllipsisArg();
2229| arglist = Ptree::Snoc(list, new Leaf(tk));
2230| break;
2231| }
2232| else if(rArgDeclaration(d, arg_encode)){
2233| encode.Append(arg_encode);
2234| list = Ptree::Snoc(list, d);
2235| t = lex->LookAhead(0);
2236| if(t == ','){
2237| lex->GetToken(tk);
2238| list = Ptree::Snoc(list, new Leaf(tk));
2239| }
2240| else if(t != ')' && t != Ellipsis)
2241| return FALSE;
2242| }
2243| else{
2244| arglist = nil;
2245| return FALSE;
2246| }
2247| }
2248|
2249| encode.EndFuncArgs();
2250| return TRUE;
2251| }
2252|
2253| /*
2254| arg.declaration
2255| : {userdef.keyword | REGISTER} type.specifier arg.declarator
2256| {'=' expression}
2257| */
2258| bool Parser::rArgDeclaration(Ptree*& decl, Encoding& encode)
2259| {
2260| Ptree *header, *type_name, *arg, *e;
2261| Token tk;
2262| Encoding name_encode;
2263|
2264| switch(lex->LookAhead(0)){
2265| case REGISTER :
2266| lex->GetToken(tk);
2267| header = new LeafREGISTER(tk);
2268| break;
2269| case UserKeyword :
2270| if(!rUserdefKeyword(header))
2271| return FALSE;
2272| break;
2273| default :
2274| header = nil;
2275| break;
2276| }
2277|
2278| if(!rTypeSpecifier(type_name, TRUE, encode))
2279| return FALSE;
2280|
2281| if(!rDeclarator(arg, kArgDeclarator, FALSE, encode, name_encode, TRUE))
2282| return FALSE;
2283|
2284| if(header == nil)
2285| decl = Ptree::List(type_name, arg);
2286| else
2287| decl = Ptree::List(header, type_name, arg);
2288|
2289| int t = lex->LookAhead(0);
2290| if(t == '='){
2291| lex->GetToken(tk);
2292| if(!rInitializeExpr(e))
2293| return FALSE;
2294|
2295| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk), e));
2296| }
2297|
2298| return TRUE;
2299| }
2300|
2301| /*
2302| initialize.expr
2303| : expression
2304| | '{' initialize.expr (',' initialize.expr)* {','} '}'
2305| */
2306| bool Parser::rInitializeExpr(Ptree*& exp)
2307| {
2308| Token tk;
2309| Ptree *e, *elist;
2310|
2311| if(lex->LookAhead(0) != '{')
2312| return rExpression(exp);
2313| else{
2314| lex->GetToken(tk);
2315| Ptree* ob = new Leaf(tk);
2316| elist = nil;
2317| int t = lex->LookAhead(0);
2318| while(t != '}'){
2319| if(!rInitializeExpr(e)){
2320| if(!SyntaxError())
2321| return FALSE; // too many e
2322|
2323| SkipTo('}');
2324| lex->GetToken(tk);
2325| exp = Ptree::List(ob, nil, new Leaf(tk));
2326| return TRUE;
2327| }
2328|
2329| elist = Ptree::Snoc(elist, e);
2330| t = lex->LookAhead(0);
2331| if(t == '}')
2332| break;
2333| else if(t == ','){
2334| lex->GetToken(tk);
2335| elist = Ptree::Snoc(elist, new Leaf(tk));
2336| t = lex->LookAhead(0);
2337| }
2338| else{
2339| if(!SyntaxError())
2340| return FALSE; // too many e
2341|
2342| SkipTo('}');
2343| lex->GetToken(tk);
2344| exp = Ptree::List(ob, nil, new Leaf(tk));
2345| return TRUE;
2346| }
2347| }
2348|
2349| lex->GetToken(tk);
2350| exp = new PtreeBrace(ob, elist, new Leaf(tk));
2351| return TRUE;
2352| }
2353| }
2354|
2355| /*
2356| function.arguments
2357| : empty
2358| | expression (',' expression)*
2359|
2360| This assumes that the next token following function.arguments is ')'.
2361| */
2362| bool Parser::rFunctionArguments(Ptree*& args)
2363| {
2364| Ptree* exp;
2365| Token tk;
2366|
2367| args = nil;
2368| if(lex->LookAhead(0) == ')')
2369| return TRUE;
2370|
2371| for(;;){
2372| if(!rExpression(exp))
2373| return FALSE;
2374|
2375| args = Ptree::Snoc(args, exp);
2376| if(lex->LookAhead(0) != ',')
2377| return TRUE;
2378| else{
2379| lex->GetToken(tk);
2380| args = Ptree::Snoc(args, new Leaf(tk));
2381| }
2382| }
2383| }
2384|
2385| /*
2386| enum.spec
2387| : ENUM Identifier
2388| | ENUM {Identifier} '{' {enum.body} '}'
2389| */
2390| bool Parser::rEnumSpec(Ptree*& spec, Encoding& encode)
2391| {
2392| Token tk, tk2;
2393| Ptree* body;
2394|
2395| if(lex->GetToken(tk) != ENUM)
2396| return FALSE;
2397|
2398| spec = new PtreeEnumSpec(new Leaf(tk));
2399| int t = lex->GetToken(tk);
2400| if(t == Identifier){
2401| Ptree* name = new Leaf(tk);
2402| encode.SimpleName(name);
2403| ((PtreeEnumSpec*)spec)->encoded_name = encode.Get();
2404| spec = Ptree::Snoc(spec, name);
2405| if(lex->LookAhead(0) == '{')
2406| t = lex->GetToken(tk);
2407| else
2408| return TRUE;
2409| }
2410| else{
2411| encode.NoName();
2412| ((PtreeEnumSpec*)spec)->encoded_name = encode.Get();
2413| spec = Ptree::Snoc(spec, nil);
2414| }
2415|
2416| if(t != '{')
2417| return FALSE;
2418|
2419| if(lex->LookAhead(0) == '}')
2420| body = nil;
2421| else
2422| if(!rEnumBody(body))
2423| return FALSE;
2424|
2425| if(lex->GetToken(tk2) != '}')
2426| return FALSE;
2427|
2428| spec = Ptree::Snoc(spec,
2429| new PtreeBrace(
2430| new Leaf(tk), body,
2431| new CommentedLeaf(tk2, lex->GetComments())));
2432| return TRUE;
2433| }
2434|
2435| /*
2436| enum.body
2437| : Identifier {'=' expression} (',' Identifier {'=' expression})* {','}
2438| */
2439| bool Parser::rEnumBody(Ptree*& body)
2440| {
2441| Token tk, tk2;
2442| Ptree *name, *exp;
2443|
2444| body = nil;
2445| for(;;){
2446| if(lex->LookAhead(0) == '}')
2447| return TRUE;
2448|
2449| if(lex->GetToken(tk) != Identifier)
2450| return FALSE;
2451|
2452| Ptree* comments = lex->GetComments();
2453|
2454| if(lex->LookAhead(0, tk2) != '=')
2455| name = new CommentedLeaf(tk, comments);
2456| else{
2457| lex->GetToken(tk2);
2458| if(!rExpression(exp)){
2459| if(!SyntaxError())
2460| return FALSE; // too many e
2461|
2462| SkipTo('}');
2463| body = nil;
2464| return TRUE;
2465| }
2466|
2467| name = Ptree::List(new CommentedLeaf(tk, comments), new Leaf(tk2), exp);
2468| }
2469|
2470| if(lex->LookAhead(0) != ','){
2471| body = Ptree::Snoc(body, name);
2472| return TRUE;
2473| }
2474| else{
2475| lex->GetToken(tk);
2476| body = Ptree::Nconc(body, Ptree::List(name, new Leaf(tk)));
2477| }
2478| }
2479| }
2480|
2481| /*
2482| class.spec
2483| : {userdef.keyword} class.key class.body
2484| | {userdef.keyword} class.key name {class.body}
2485| | {userdef.keyword} class.key name ':' base.specifiers class.body
2486|
2487| class.key
2488| : CLASS | STRUCT | UNION
2489| */
2490| bool Parser::rClassSpec(Ptree*& spec, Encoding& encode)
2491| {
2492| Ptree *head, *bases, *body, *name;
2493| Token tk;
2494|
2495| head = nil;
2496| if(lex->LookAhead(0) == UserKeyword)
2497| if(!rUserdefKeyword(head))
2498| return FALSE;
2499|
2500| int t = lex->GetToken(tk);
2501| if(t != CLASS && t != STRUCT && t != UNION)
2502| return FALSE;
2503|
2504| spec = new PtreeClassSpec(new LeafReserved(tk), nil, comments);
2505| if(head != nil)
2506| spec = new PtreeClassSpec(head, spec, comments);
2507|
2508| if(lex->LookAhead(0) == '{'){
2509| encode.NoName();
2510| spec = Ptree::Snoc(spec, Ptree::List(nil, nil));
2511| }
2512| else{
2513| if(!rName(name, encode))
2514| return FALSE;
2515|
2516| spec = Ptree::Snoc(spec, name);
2517| t = lex->LookAhead(0);
2518| if(t == ':'){
2519| if(!rBaseSpecifiers(bases))
2520| return FALSE;
2521|
2522| spec = Ptree::Snoc(spec, bases);
2523| }
2524| else if(t == '{')
2525| spec = Ptree::Snoc(spec, nil);
2526| else{
2527| ((PtreeClassSpec*)spec)->encoded_name = encode.Get();
2528| return TRUE;
2529| }
2530| }
2531|
2532| ((PtreeClassSpec*)spec)->encoded_name = encode.Get();
2533| if(!rClassBody(body))
2534| return FALSE;
2535|
2536| spec = Ptree::Snoc(spec, body);
2537| return TRUE;
2538| }
2539|
2540| /*
2541| base.specifiers
2542| : ':' base.specifier (',' base.specifier)*
2543|
2544| base.specifier
2545| : {{VIRTUAL} (PUBLIC | PROTECTED | PRIVATE) {VIRTUAL}} name
2546| */
2547| bool Parser::rBaseSpecifiers(Ptree*& bases)
2548| {
2549| Token tk;
2550| int t;
2551| Ptree* name;
2552| Encoding encode;
2553|
2554| if(lex->GetToken(tk) != ':')
2555| return FALSE;
2556|
2557| bases = Ptree::List(new Leaf(tk));
2558| for(;;){
2559| Ptree* super = nil;
2560| t = lex->LookAhead(0);
2561| if(t == VIRTUAL){
2562| lex->GetToken(tk);
2563| super = Ptree::Snoc(super, new LeafVIRTUAL(tk));
2564| t = lex->LookAhead(0);
2565| }
2566|
2567| if(t == PUBLIC | t == PROTECTED | t == PRIVATE){
2568| Ptree* lf;
2569| switch(lex->GetToken(tk)){
2570| case PUBLIC :
2571| lf = new LeafPUBLIC(tk);
2572| break;
2573| case PROTECTED :
2574| lf = new LeafPROTECTED(tk);
2575| break;
2576| case PRIVATE :
2577| lf = new LeafPRIVATE(tk);
2578| break;
2579| default :
2580| MopErrorMessage("rBaseSpecifiers()", "fatal");
2581| lf = nil;
2582| break;
2583| }
2584|
2585| super = Ptree::Snoc(super, lf);
2586| t = lex->LookAhead(0);
2587| }
2588|
2589| if(t == VIRTUAL){
2590| lex->GetToken(tk);
2591| super = Ptree::Snoc(super, new LeafVIRTUAL(tk));
2592| }
2593|
2594| encode.Clear();
2595| if(!rName(name, encode))
2596| return FALSE;
2597|
2598| if(!name->IsLeaf())
2599| name = new PtreeName(name, encode);
2600|
2601| super = Ptree::Snoc(super, name);
2602| bases = Ptree::Snoc(bases, super);
2603| if(lex->LookAhead(0) != ',')
2604| return TRUE;
2605| else{
2606| lex->GetToken(tk);
2607| bases = Ptree::Snoc(bases, new Leaf(tk));
2608| }
2609| }
2610| }
2611|
2612| /*
2613| class.body : '{' (class.members)* '}'
2614| */
2615| bool Parser::rClassBody(Ptree*& body)
2616| {
2617| Token tk;
2618| Ptree *mems, *m;
2619|
2620| if(lex->GetToken(tk) != '{')
2621| return FALSE;
2622|
2623| Ptree* ob = new Leaf(tk);
2624| mems = nil;
2625| while(lex->LookAhead(0) != '}'){
2626| if(!rClassMember(m)){
2627| if(!SyntaxError())
2628| return FALSE; // too many error
2629|
2630| SkipTo('}');
2631| lex->GetToken(tk);
2632| body = Ptree::List(ob, nil, new Leaf(tk));
2633| return TRUE;
2634| }
2635|
2636| lex->GetComments();
2637| mems = Ptree::Snoc(mems, m);
2638| }
2639|
2640| lex->GetToken(tk);
2641| body = new PtreeClassBody(ob, mems,
2642| new CommentedLeaf(tk, lex->GetComments()));
2643| return TRUE;
2644| }
2645|
2646| /*
2647| class.member
2648| : (PUBLIC | PROTECTED | PRIVATE) ':'
2649| | user.access.spec
2650| | ';'
2651| | type.def
2652| | template.decl
2653| | using.declaration
2654| | metaclass.decl
2655| | declaration
2656| | access.decl
2657|
2658| Note: if you modify this function, see ClassWalker::TranslateClassSpec()
2659| as well.
2660| */
2661| bool Parser::rClassMember(Ptree*& mem)
2662| {
2663| Token tk1, tk2;
2664|
2665| int t = lex->LookAhead(0);
2666| if(t == PUBLIC || t == PROTECTED || t == PRIVATE){
2667| Ptree* lf;
2668| switch(lex->GetToken(tk1)){
2669| case PUBLIC :
2670| lf = new LeafPUBLIC(tk1);
2671| break;
2672| case PROTECTED :
2673| lf = new LeafPROTECTED(tk1);
2674| break;
2675| case PRIVATE :
2676| lf = new LeafPRIVATE(tk1);
2677| break;
2678| default :
2679| MopErrorMessage("rClassMember()", "fatal");
2680| lf = nil;
2681| break;
2682| }
2683|
2684| if(lex->GetToken(tk2) != ':')
2685| return FALSE;
2686|
2687| mem = new PtreeAccessSpec(lf, Ptree::List(new Leaf(tk2)));
2688| return TRUE;
2689| }
2690| else if(t == UserKeyword4)
2691| return rUserAccessSpec(mem);
2692| else if(t == ';')
2693| return rNullDeclaration(mem);
2694| else if(t == TYPEDEF)
2695| return rTypedef(mem);
2696| else if(t == TEMPLATE)
2697| return rTemplateDecl(mem);
2698| else if(t == USING)
2699| return rUsing(mem);
2700| else if(t == METACLASS)
2701| return rMetaclassDecl(mem);
2702| else{
2703| char* pos = lex->Save();
2704| if(rDeclaration(mem)) {
2705| Ptree* comments = lex->GetComments();
2706| if (comments) {
2707| //cout << "Warning: rClassMember setting comments to ";
2708| //comments->Display();
2709| Walker::SetDeclaratorComments(mem, comments);
2710| }
2711| return TRUE;
2712| }
2713|
2714| lex->Restore(pos);
2715| return rAccessDecl(mem);
2716| }
2717| }
2718|
2719| /*
2720| access.decl
2721| : name ';' e.g. <qualified class>::<me
2722| */
2723| bool Parser::rAccessDecl(Ptree*& mem)
2724| {
2725| Ptree* name;
2726| Encoding encode;
2727| Token tk;
2728|
2729| if(!rName(name, encode))
2730| return FALSE;
2731|
2732| if(lex->GetToken(tk) != ';')
2733| return FALSE;
2734|
2735| mem = new PtreeAccessDecl(new PtreeName(name, encode),
2736| Ptree::List(new Leaf(tk)));
2737| return TRUE;
2738| }
2739|
2740| /*
2741| user.access.spec
2742| : UserKeyword4 ':'
2743| | UserKeyword4 '(' function.arguments ')' ':'
2744| */
2745| bool Parser::rUserAccessSpec(Ptree*& mem)
2746| {
2747| Token tk1, tk2, tk3, tk4;
2748| Ptree* args;
2749|
2750| if(lex->GetToken(tk1) != UserKeyword4)
2751| return FALSE;
2752|
2753| int t = lex->GetToken(tk2);
2754| if(t == ':'){
2755| mem = new PtreeUserAccessSpec(new Leaf(tk1),
2756| Ptree::List(new Leaf(tk2)));
2757| return TRUE;
2758| }
2759| else if(t == '('){
2760| if(!rFunctionArguments(args))
2761| return FALSE;
2762|
2763| if(lex->GetToken(tk3) != ')')
2764| return FALSE;
2765|
2766| if(lex->GetToken(tk4) != ':')
2767| return FALSE;
2768|
2769| mem = new PtreeUserAccessSpec(new Leaf(tk1),
2770| Ptree::List(new Leaf(tk2), args,
2771| new Leaf(tk3),
2772| new Leaf(tk4)));
2773| return TRUE;
2774| }
2775| else
2776| return FALSE;
2777| }
2778|
2779| /*
2780| comma.expression
2781| : expression
2782| | comma.expression ',' expression (left-to-r
2783| */
2784| bool Parser::rCommaExpression(Ptree*& exp)
2785| {
2786| Token tk;
2787| Ptree *right;
2788|
2789| if(!rExpression(exp))
2790| return FALSE;
2791|
2792| while(lex->LookAhead(0) == ','){
2793| lex->GetToken(tk);
2794| if(!rExpression(right))
2795| return FALSE;
2796|
2797| exp = new PtreeCommaExpr(exp, Ptree::List(new Leaf(tk), right));
2798| }
2799|
2800| return TRUE;
2801| }
2802|
2803| /*
2804| expression
2805| : conditional.expr {(AssignOp | '=') expression} right-t
2806| */
2807| bool Parser::rExpression(Ptree*& exp)
2808| {
2809| Token tk;
2810| Ptree *left, *right;
2811|
2812| if(!rConditionalExpr(left))
2813| return FALSE;
2814|
2815| int t = lex->LookAhead(0);
2816| if(t != '=' && t != AssignOp)
2817| exp = left;
2818| else{
2819| lex->GetToken(tk);
2820| if(!rExpression(right))
2821| return FALSE;
2822|
2823| exp = new PtreeAssignExpr(left, Ptree::List(new Leaf(tk), right));
2824| }
2825|
2826| return TRUE;
2827| }
2828|
2829| /*
2830| conditional.expr
2831| : logical.or.expr {'?' comma.expression ':' conditional.expr} right-to-left
2832| */
2833| bool Parser::rConditionalExpr(Ptree*& exp)
2834| {
2835| Token tk1, tk2;
2836| Ptree *then, *otherwise;
2837|
2838| if(!rLogicalOrExpr(exp, FALSE))
2839| return FALSE;
2840|
2841| if(lex->LookAhead(0) == '?'){
2842| lex->GetToken(tk1);
2843| if(!rCommaExpression(then))
2844| return FALSE;
2845|
2846| if(lex->GetToken(tk2) != ':')
2847| return FALSE;
2848|
2849| if(!rConditionalExpr(otherwise))
2850| return FALSE;
2851|
2852| exp = new PtreeCondExpr(exp, Ptree::List(new Leaf(tk1), then,
2853| new Leaf(tk2), otherwise));
2854| }
2855|
2856| return TRUE;
2857| }
2858|
2859| /*
2860| logical.or.expr
2861| : logical.and.expr
2862| | logical.or.expr LogOrOp logical.and.expr le
2863| */
2864| bool Parser::rLogicalOrExpr(Ptree*& exp, bool temp_args)
2865| {
2866| Token tk;
2867| Ptree *right;
2868|
2869| if(!rLogicalAndExpr(exp, temp_args))
2870| return FALSE;
2871|
2872| while(lex->LookAhead(0) == LogOrOp){
2873| lex->GetToken(tk);
2874| if(!rLogicalAndExpr(right, temp_args))
2875| return FALSE;
2876|
2877| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2878| }
2879|
2880| return TRUE;
2881| }
2882|
2883| /*
2884| logical.and.expr
2885| : inclusive.or.expr
2886| | logical.and.expr LogAndOp inclusive.or.expr
2887| */
2888| bool Parser::rLogicalAndExpr(Ptree*& exp, bool temp_args)
2889| {
2890| Token tk;
2891| Ptree *right;
2892|
2893| if(!rInclusiveOrExpr(exp, temp_args))
2894| return FALSE;
2895|
2896| while(lex->LookAhead(0) == LogAndOp){
2897| lex->GetToken(tk);
2898| if(!rInclusiveOrExpr(right, temp_args))
2899| return FALSE;
2900|
2901| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2902| }
2903|
2904| return TRUE;
2905| }
2906|
2907| /*
2908| inclusive.or.expr
2909| : exclusive.or.expr
2910| | inclusive.or.expr '|' exclusive.or.expr
2911| */
2912| bool Parser::rInclusiveOrExpr(Ptree*& exp, bool temp_args)
2913| {
2914| Token tk;
2915| Ptree *right;
2916|
2917| if(!rExclusiveOrExpr(exp, temp_args))
2918| return FALSE;
2919|
2920| while(lex->LookAhead(0) == '|'){
2921| lex->GetToken(tk);
2922| if(!rExclusiveOrExpr(right, temp_args))
2923| return FALSE;
2924|
2925| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2926| }
2927|
2928| return TRUE;
2929| }
2930|
2931| /*
2932| exclusive.or.expr
2933| : and.expr
2934| | exclusive.or.expr '^' and.expr
2935| */
2936| bool Parser::rExclusiveOrExpr(Ptree*& exp, bool temp_args)
2937| {
2938| Token tk;
2939| Ptree *right;
2940|
2941| if(!rAndExpr(exp, temp_args))
2942| return FALSE;
2943|
2944| while(lex->LookAhead(0) == '^'){
2945| lex->GetToken(tk);
2946| if(!rAndExpr(right, temp_args))
2947| return FALSE;
2948|
2949| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2950| }
2951|
2952| return TRUE;
2953| }
2954|
2955| /*
2956| and.expr
2957| : equality.expr
2958| | and.expr '&' equality.expr
2959| */
2960| bool Parser::rAndExpr(Ptree*& exp, bool temp_args)
2961| {
2962| Token tk;
2963| Ptree *right;
2964|
2965| if(!rEqualityExpr(exp, temp_args))
2966| return FALSE;
2967|
2968| while(lex->LookAhead(0) == '&'){
2969| lex->GetToken(tk);
2970| if(!rEqualityExpr(right, temp_args))
2971| return FALSE;
2972|
2973| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2974| }
2975|
2976| return TRUE;
2977| }
2978|
2979| /*
2980| equality.expr
2981| : relational.expr
2982| | equality.expr EqualOp relational.expr
2983| */
2984| bool Parser::rEqualityExpr(Ptree*& exp, bool temp_args)
2985| {
2986| Token tk;
2987| Ptree *right;
2988|
2989| if(!rRelationalExpr(exp, temp_args))
2990| return FALSE;
2991|
2992| while(lex->LookAhead(0) == EqualOp){
2993| lex->GetToken(tk);
2994| if(!rRelationalExpr(right, temp_args))
2995| return FALSE;
2996|
2997| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
2998| }
2999|
3000| return TRUE;
3001| }
3002|
3003| /*
3004| relational.expr
3005| : shift.expr
3006| | relational.expr (RelOp | '<' | '>') shift.expr
3007| */
3008| bool Parser::rRelationalExpr(Ptree*& exp, bool temp_args)
3009| {
3010| int t;
3011| Token tk;
3012| Ptree *right;
3013|
3014| if(!rShiftExpr(exp))
3015| return FALSE;
3016|
3017| while(t = lex->LookAhead(0),
3018| (t == RelOp || t == '<' || (t == '>' && !temp_args))){
3019| lex->GetToken(tk);
3020| if(!rShiftExpr(right))
3021| return FALSE;
3022|
3023| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
3024| }
3025|
3026| return TRUE;
3027| }
3028|
3029| /*
3030| shift.expr
3031| : additive.expr
3032| | shift.expr ShiftOp additive.expr
3033| */
3034| bool Parser::rShiftExpr(Ptree*& exp)
3035| {
3036| Token tk;
3037| Ptree *right;
3038|
3039| if(!rAdditiveExpr(exp))
3040| return FALSE;
3041|
3042| while(lex->LookAhead(0) == ShiftOp){
3043| lex->GetToken(tk);
3044| if(!rAdditiveExpr(right))
3045| return FALSE;
3046|
3047| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
3048| }
3049|
3050| return TRUE;
3051| }
3052|
3053| /*
3054| additive.expr
3055| : multiply.expr
3056| | additive.expr ('+' | '-') multiply.expr
3057| */
3058| bool Parser::rAdditiveExpr(Ptree*& exp)
3059| {
3060| int t;
3061| Token tk;
3062| Ptree *right;
3063|
3064| if(!rMultiplyExpr(exp))
3065| return FALSE;
3066|
3067| while(t = lex->LookAhead(0), (t == '+' || t == '-')){
3068| lex->GetToken(tk);
3069| if(!rMultiplyExpr(right))
3070| return FALSE;
3071|
3072| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
3073| }
3074|
3075| return TRUE;
3076| }
3077|
3078| /*
3079| multiply.expr
3080| : pm.expr
3081| | multiply.expr ('*' | '/' | '%') pm.expr
3082| */
3083| bool Parser::rMultiplyExpr(Ptree*& exp)
3084| {
3085| int t;
3086| Token tk;
3087| Ptree *right;
3088|
3089| if(!rPmExpr(exp))
3090| return FALSE;
3091|
3092| while(t = lex->LookAhead(0), (t == '*' || t == '/' || t == '%')){
3093| lex->GetToken(tk);
3094| if(!rPmExpr(right))
3095| return FALSE;
3096|
3097| exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
3098| }
3099|
3100| return TRUE;
3101| }
3102|
3103| /*
3104| pm.expr (pointer to member .
3105| : cast.expr
3106| | pm.expr PmOp cast.expr
3107| */
3108| bool Parser::rPmExpr(Ptree*& exp)
3109| {
3110| Token tk;
3111| Ptree *right;
3112|
3113| if(!rCastExpr(exp))
3114| return FALSE;
3115|
3116| while(lex->LookAhead(0) == PmOp){
3117| lex->GetToken(tk);
3118| if(!rCastExpr(right))
3119| return FALSE;
3120|
3121| exp = new PtreePmExpr(exp, Ptree::List(new Leaf(tk), right));
3122| }
3123|
3124| return TRUE;
3125| }
3126|
3127| /*
3128| cast.expr
3129| : unary.expr
3130| | '(' type.name ')' cast.expr
3131| */
3132| bool Parser::rCastExpr(Ptree*& exp)
3133| {
3134| if(lex->LookAhead(0) != '(')
3135| return rUnaryExpr(exp);
3136| else{
3137| Token tk1, tk2;
3138| Ptree* tname;
3139| char* pos = lex->Save();
3140| lex->GetToken(tk1);
3141| if(rTypeName(tname))
3142| if(lex->GetToken(tk2) == ')')
3143| if(rCastExpr(exp)){
3144| exp = new PtreeCastExpr(new Leaf(tk1),
3145| Ptree::List(tname, new Leaf(tk2),
3146| exp));
3147| return TRUE;
3148| }
3149|
3150| lex->Restore(pos);
3151| return rUnaryExpr(exp);
3152| }
3153| }
3154|
3155| /*
3156| type.name
3157| : type.specifier cast.declarator
3158| */
3159| bool Parser::rTypeName(Ptree*& tname)
3160| {
3161| Encoding type_encode;
3162| return rTypeName(tname, type_encode);
3163| }
3164|
3165| bool Parser::rTypeName(Ptree*& tname, Encoding& type_encode)
3166| {
3167| Ptree *type_name, *arg;
3168| Encoding name_encode;
3169|
3170| if(!rTypeSpecifier(type_name, TRUE, type_encode))
3171| return FALSE;
3172|
3173| if(!rDeclarator(arg, kCastDeclarator, FALSE, type_encode, name_encode,
3174| FALSE))
3175| return FALSE;
3176|
3177| tname = Ptree::List(type_name, arg);
3178| return TRUE;
3179| }
3180|
3181| /*
3182| unary.expr
3183| : postfix.expr
3184| | ('*' | '&' | '+' | '-' | '!' | '~' | IncOp) cast.expr
3185| | sizeof.expr
3186| | allocate.expr
3187| | throw.expression
3188| */
3189| bool Parser::rUnaryExpr(Ptree*& exp)
3190| {
3191| int t = lex->LookAhead(0);
3192| if(t == '*' || t == '&' || t == '+' || t == '-' || t == '!'
3193| || t == '~' || t == IncOp){
3194| Token tk;
3195| Ptree* right;
3196|
3197| lex->GetToken(tk);
3198| if(!rCastExpr(right))
3199| return FALSE;
3200|
3201| exp = new PtreeUnaryExpr(new Leaf(tk), Ptree::List(right));
3202| return TRUE;
3203| }
3204| else if(t == SIZEOF)
3205| return rSizeofExpr(exp);
3206| else if(t == THROW)
3207| return rThrowExpr(exp);
3208| else if(isAllocateExpr(t))
3209| return rAllocateExpr(exp);
3210| else
3211| return rPostfixExpr(exp);
3212| }
3213|
3214| /*
3215| throw.expression
3216| : THROW {expression}
3217| */
3218| bool Parser::rThrowExpr(Ptree*& exp)
3219| {
3220| Token tk;
3221| Ptree* e;
3222|
3223| if(lex->GetToken(tk) != THROW)
3224| return FALSE;
3225|
3226| int t = lex->LookAhead(0);
3227| if(t == ':' || t == ';')
3228| e = nil;
3229| else
3230| if(!rExpression(e))
3231| return FALSE;
3232|
3233| exp = new PtreeThrowExpr(new LeafReserved(tk), Ptree::List(e));
3234| return TRUE;
3235| }
3236|
3237| /*
3238| sizeof.expr
3239| : SIZEOF unary.expr
3240| | SIZEOF '(' type.name ')'
3241| */
3242| bool Parser::rSizeofExpr(Ptree*& exp)
3243| {
3244| Token tk;
3245| Ptree* unary;
3246|
3247| if(lex->GetToken(tk) != SIZEOF)
3248| return FALSE;
3249|
3250| if(lex->LookAhead(0) == '('){
3251| Ptree* tname;
3252| Token op, cp;
3253|
3254| char* pos = lex->Save();
3255| lex->GetToken(op);
3256| if(rTypeName(tname))
3257| if(lex->GetToken(cp) == ')'){
3258| exp = new PtreeSizeofExpr(new Leaf(tk),
3259| Ptree::List(new Leaf(op), tname,
3260| new Leaf(cp)));
3261| return TRUE;
3262| }
3263|
3264| lex->Restore(pos);
3265| }
3266|
3267| if(!rUnaryExpr(unary))
3268| return FALSE;
3269|
3270| exp = new PtreeSizeofExpr(new Leaf(tk), Ptree::List(unary));
3271| return TRUE;
3272| }
3273|
3274| /*
3275| typeid.expr
3276| : TYPEID unary.expr
3277| | TYPEID '(' type.name ')'
3278| */
3279| bool Parser::rTypeidExpr(Ptree*& exp)
3280| {
3281| Token tk;
3282| Ptree* unary;
3283|
3284| if(lex->GetToken(tk) != TYPEID)
3285| return FALSE;
3286|
3287| if(lex->LookAhead(0) == '('){
3288| Ptree* tname;
3289| Token op, cp;
3290|
3291| char* pos = lex->Save();
3292| lex->GetToken(op);
3293| if(rTypeName(tname))
3294| if(lex->GetToken(cp) == ')'){
3295| exp = new PtreeTypeidExpr(new Leaf(tk),
3296| Ptree::List(new Leaf(op), tname,
3297| new Leaf(cp)));
3298| return TRUE;
3299| }
3300|
3301| lex->Restore(pos);
3302| }
3303|
3304| if(!rUnaryExpr(unary))
3305| return FALSE;
3306|
3307| exp = new PtreeTypeidExpr(new Leaf(tk), Ptree::List(unary));
3308| return TRUE;
3309| }
3310|
3311| bool Parser::isAllocateExpr(int t)
3312| {
3313| if(t == UserKeyword)
3314| return TRUE;
3315| else{
3316| if(t == Scope)
3317| t = lex->LookAhead(1);
3318|
3319| if(t == NEW || t == DELETE)
3320| return TRUE;
3321| else
3322| return FALSE;
3323| }
3324| }
3325|
3326| /*
3327| allocate.expr
3328| : {Scope | userdef.keyword} NEW allocate.type
3329| | {Scope} DELETE {'[' ']'} cast.expr
3330| */
3331| bool Parser::rAllocateExpr(Ptree*& exp)
3332| {
3333| Token tk;
3334| Ptree* head = nil;
3335|
3336| bool ukey = FALSE;
3337| int t = lex->LookAhead(0);
3338| if(t == Scope){
3339| lex->GetToken(tk);
3340| head = new Leaf(tk);
3341| }
3342| else if(t == UserKeyword){
3343| if(!rUserdefKeyword(head))
3344| return FALSE;
3345|
3346| ukey = TRUE;
3347| }
3348|
3349| t = lex->GetToken(tk);
3350| if(t == DELETE){
3351| Ptree* obj;
3352| if(ukey)
3353| return FALSE;
3354|
3355| if(head == nil)
3356| exp = new PtreeDeleteExpr(new LeafReserved(tk), nil);
3357| else
3358| exp = new PtreeDeleteExpr(head,
3359| Ptree::List(new LeafReserved(tk)));
3360|
3361| if(lex->LookAhead(0) == '['){
3362| lex->GetToken(tk);
3363| exp = Ptree::Snoc(exp, new Leaf(tk));
3364| if(lex->GetToken(tk) != ']')
3365| return FALSE;
3366|
3367| exp = Ptree::Snoc(exp, new Leaf(tk));
3368| }
3369|
3370| if(!rCastExpr(obj))
3371| return FALSE;
3372|
3373| exp = Ptree::Snoc(exp, obj);
3374| return TRUE;
3375| }
3376| else if(t == NEW){
3377| Ptree *atype;
3378| if(head == nil)
3379| exp = new PtreeNewExpr(new LeafReserved(tk), nil);
3380| else
3381| exp = new PtreeNewExpr(head, Ptree::List(new LeafReserved(tk)));
3382|
3383| if(!rAllocateType(atype))
3384| return FALSE;
3385|
3386| exp = Ptree::Nconc(exp, atype);
3387| return TRUE;
3388| }
3389| else
3390| return FALSE;
3391| }
3392|
3393| /*
3394| userdef.keyword
3395| : [UserKeyword | UserKeyword5] {'(' function.arguments ')'}
3396| */
3397| bool Parser::rUserdefKeyword(Ptree*& ukey)
3398| {
3399| Token tk;
3400|
3401| int t = lex->GetToken(tk);
3402| if(t != UserKeyword && t != UserKeyword5)
3403| return FALSE;
3404|
3405| if(lex->LookAhead(0) != '(')
3406| ukey = new PtreeUserdefKeyword(new Leaf(tk), nil);
3407| else{
3408| Ptree* args;
3409| Token op, cp;
3410| lex->GetToken(op);
3411| if(!rFunctionArguments(args))
3412| return FALSE;
3413|
3414| if(lex->GetToken(cp) != ')')
3415| return FALSE;
3416|
3417| ukey = new PtreeUserdefKeyword(new Leaf(tk),
3418| Ptree::List(new Leaf(op), args, new Leaf(cp)));
3419| }
3420|
3421| return TRUE;
3422| }
3423|
3424| /*
3425| allocate.type
3426| : {'(' function.arguments ')'} type.specifier new.declarator
3427| {allocate.initializer}
3428| | {'(' function.arguments ')'} '(' type.name ')' {allocate.initializer}
3429| */
3430| bool Parser::rAllocateType(Ptree*& atype)
3431| {
3432| Token op, cp;
3433| Ptree *tname, *init, *exp;
3434|
3435| if(lex->LookAhead(0) != '(')
3436| atype = Ptree::List(nil);
3437| else{
3438| lex->GetToken(op);
3439|
3440| char* pos = lex->Save();
3441| if(rTypeName(tname))
3442| if(lex->GetToken(cp) == ')')
3443| if(lex->LookAhead(0) != '('){
3444| atype = Ptree::List(nil, Ptree::List(new Leaf(op), tname,
3445| new Leaf(cp)));
3446| if(!isTypeSpecifier())
3447| return TRUE;
3448| }
3449| else if(rAllocateInitializer(init)){
3450| atype = Ptree::List(nil,
3451| Ptree::List(new Leaf(op), tname,
3452| new Leaf(cp)),
3453| init);
3454| // the next token cannot be '('
3455| if(lex->LookAhead(0) != '(')
3456| return TRUE;
3457| }
3458|
3459| // if we reach here, we have to process '(' function.arguments ')'.
3460| lex->Restore(pos);
3461| if(!rFunctionArguments(exp))
3462| return FALSE;
3463|
3464| if(lex->GetToken(cp) != ')')
3465| return FALSE;
3466|
3467| atype = Ptree::List(Ptree::List(new Leaf(op), exp, new Leaf(cp)));
3468| }
3469|
3470| if(lex->LookAhead(0) == '('){
3471| lex->GetToken(op);
3472| if(!rTypeName(tname))
3473| return FALSE;
3474|
3475| if(lex->GetToken(cp) != ')')
3476| return FALSE;
3477|
3478| atype = Ptree::Snoc(atype, Ptree::List(new Leaf(op), tname,
3479| new Leaf(cp)));
3480| }
3481| else{
3482| Ptree* decl;
3483| Encoding type_encode;
3484| if(!rTypeSpecifier(tname, FALSE, type_encode))
3485| return FALSE;
3486|
3487| if(!rNewDeclarator(decl, type_encode))
3488| return FALSE;
3489|
3490| atype = Ptree::Snoc(atype, Ptree::List(tname, decl));
3491| }
3492|
3493| if(lex->LookAhead(0) == '('){
3494| if(!rAllocateInitializer(init))
3495| return FALSE;
3496|
3497| atype = Ptree::Snoc(atype, init);
3498| }
3499|
3500| return TRUE;
3501| }
3502|
3503| /*
3504| new.declarator
3505| : empty
3506| | ptr.operator
3507| | {ptr.operator} ('[' comma.expression ']')+
3508| */
3509| bool Parser::rNewDeclarator(Ptree*& decl, Encoding& encode)
3510| {
3511| decl = nil;
3512| if(lex->LookAhead(0) != '[')
3513| if(!optPtrOperator(decl, encode))
3514| return FALSE;
3515|
3516| while(lex->LookAhead(0) == '['){
3517| Token ob, cb;
3518| Ptree* exp;
3519| lex->GetToken(ob);
3520| if(!rCommaExpression(exp))
3521| return FALSE;
3522|
3523| if(lex->GetToken(cb) != ']')
3524| return FALSE;
3525|
3526| encode.Array();
3527| decl = Ptree::Nconc(decl, Ptree::List(new Leaf(ob), exp,
3528| new Leaf(cb)));
3529| }
3530|
3531| if(decl == nil)
3532| decl = new PtreeDeclarator(encode);
3533| else
3534| decl = new PtreeDeclarator(decl, encode);
3535|
3536| return TRUE;
3537| }
3538|
3539| /*
3540| allocate.initializer
3541| : '(' {initialize.expr (',' initialize.expr)* } ')'
3542| */
3543| bool Parser::rAllocateInitializer(Ptree*& init)
3544| {
3545| Token op, cp;
3546|
3547| if(lex->GetToken(op) != '(')
3548| return FALSE;
3549|
3550| if(lex->LookAhead(0) == ')'){
3551| lex->GetToken(cp);
3552| init = Ptree::List(new Leaf(op), nil, new Leaf(cp));
3553| return TRUE;
3554| }
3555|
3556| init = nil;
3557| for(;;){
3558| Ptree* exp;
3559| if(!rInitializeExpr(exp))
3560| return FALSE;
3561|
3562| init = Ptree::Snoc(init, exp);
3563| if(lex->LookAhead(0) != ',')
3564| break;
3565| else{
3566| Token tk;
3567| lex->GetToken(tk);
3568| init = Ptree::Snoc(init, new Leaf(tk));
3569| }
3570| }
3571|
3572| lex->GetToken(cp);
3573| init = Ptree::List(new Leaf(op), init, new Leaf(cp));
3574| return TRUE;
3575| }
3576|
3577| /*
3578| postfix.exp
3579| : primary.exp
3580| | postfix.expr '[' comma.expression ']'
3581| | postfix.expr '(' function.arguments ')'
3582| | postfix.expr '.' var.name
3583| | postfix.expr ArrowOp var.name
3584| | postfix.expr IncOp
3585| | openc++.postfix.expr
3586|
3587| openc++.postfix.expr
3588| : postfix.expr '.' userdef.statement
3589| | postfix.expr ArrowOp userdef.statement
3590|
3591| Note: function-style casts are accepted as function calls.
3592| */
3593| bool Parser::rPostfixExpr(Ptree*& exp)
3594| {
3595| Ptree* e;
3596| Token cp, op;
3597| int t, t2;
3598|
3599| if(!rPrimaryExpr(exp))
3600| return FALSE;
3601|
3602| for(;;){
3603| switch(lex->LookAhead(0)){
3604| case '[' :
3605| lex->GetToken(op);
3606| if(!rCommaExpression(e))
3607| return FALSE;
3608|
3609| if(lex->GetToken(cp) != ']')
3610| return FALSE;
3611|
3612| exp = new PtreeArrayExpr(exp, Ptree::List(new Leaf(op),
3613| e, new Leaf(cp)));
3614| break;
3615| case '(' :
3616| lex->GetToken(op);
3617| if(!rFunctionArguments(e))
3618| return FALSE;
3619|
3620| if(lex->GetToken(cp) != ')')
3621| return FALSE;
3622|
3623| exp = new PtreeFuncallExpr(exp, Ptree::List(new Leaf(op),
3624| e, new Leaf(cp)));
3625| break;
3626| case IncOp :
3627| lex->GetToken(op);
3628| exp = new PtreePostfixExpr(exp, Ptree::List(new Leaf(op)));
3629| break;
3630| case '.' :
3631| case ArrowOp :
3632| t2 = lex->GetToken(op);
3633| t = lex->LookAhead(0);
3634| if(t == UserKeyword || t == UserKeyword2 || t == UserKeyword3){
3635| if(!rUserdefStatement(e))
3636| return FALSE;
3637|
3638| exp = new PtreeUserStatementExpr(exp,
3639| Ptree::Cons(new Leaf(op), e));
3640| break;
3641| }
3642| else{
3643| if(!rVarName(e))
3644| return FALSE;
3645|
3646| if(t2 == '.')
3647| exp = new PtreeDotMemberExpr(exp,
3648| Ptree::List(new Leaf(op), e));
3649| else
3650| exp = new PtreeArrowMemberExpr(exp,
3651| Ptree::List(new Leaf(op), e));
3652| break;
3653| }
3654| default :
3655| return TRUE;
3656| }
3657| }
3658| }
3659|
3660| /*
3661| primary.exp
3662| : Constant
3663| | CharConst
3664| | StringL
3665| | THIS
3666| | var.name
3667| | '(' comma.expression ')'
3668| | integral.or.class.spec '(' function.arguments ')'
3669| | openc++.primary.exp
3670| | typeid '(' typething ')'
3671|
3672| openc++.primary.exp
3673| : var.name '::' userdef.statement
3674| */
3675| bool Parser::rPrimaryExpr(Ptree*& exp)
3676| {
3677| Token tk, tk2;
3678| Ptree* exp2;
3679| Encoding cast_type_encode;
3680|
3681| switch(lex->LookAhead(0)){
3682| case Constant : case CharConst : case StringL :
3683| lex->GetToken(tk);
3684| exp = new Leaf(tk);
3685| return TRUE;
3686| case THIS :
3687| lex->GetToken(tk);
3688| exp = new LeafThis(tk);
3689| return TRUE;
3690| case TYPEID :
3691| return rTypeidExpr(exp);
3692| case '(' :
3693| lex->GetToken(tk);
3694| if(!rCommaExpression(exp2))
3695| return FALSE;
3696|
3697| if(lex->GetToken(tk2) != ')')
3698| return FALSE;
3699|
3700| exp = new PtreeParenExpr(new Leaf(tk),
3701| Ptree::List(exp2, new Leaf(tk2)));
3702| return TRUE;
3703| default :
3704| if(!optIntegralTypeOrClassSpec(exp, cast_type_encode))
3705| return FALSE;
3706|
3707| if(exp != nil){ // if integra
3708| if(lex->GetToken(tk) != '(')
3709| return FALSE;
3710|
3711| if(!rFunctionArguments(exp2))
3712| return FALSE;
3713|
3714| if(lex->GetToken(tk2) != ')')
3715| return FALSE;
3716|
3717| exp = new PtreeFstyleCastExpr(cast_type_encode, exp,
3718| Ptree::List(new Leaf(tk), exp2,
3719| new Leaf(tk2)));
3720| return TRUE;
3721| }
3722| else{
3723| if(!rVarName(exp))
3724| return FALSE;
3725|
3726| if(lex->LookAhead(0) == Scope){
3727| lex->GetToken(tk);
3728| if(!rUserdefStatement(exp2))
3729| return FALSE;
3730|
3731| exp = new PtreeStaticUserStatementExpr(exp,
3732| Ptree::Cons(new Leaf(tk), exp2));
3733| }
3734|
3735| return TRUE;
3736| }
3737| }
3738| }
3739|
3740| /*
3741| userdef.statement
3742| : UserKeyword '(' function.arguments ')' compound.statement
3743| | UserKeyword2 '(' arg.decl.list ')' compound.statement
3744| | UserKeyword3 '(' expr.statement {comma.expression} ';'
3745| {comma.expression} ')' compound.statement
3746| */
3747| bool Parser::rUserdefStatement(Ptree*& st)
3748| {
3749| Token tk, tk2, tk3, tk4;
3750| Ptree *keyword, *exp, *body, *exp2, *exp3;
3751| Encoding dummy_encode;
3752|
3753| int t = lex->GetToken(tk);
3754| if(lex->GetToken(tk2) != '(')
3755| return FALSE;
3756|
3757| switch(t){
3758| case UserKeyword :
3759| keyword = new LeafReserved(tk);
3760| if(!rFunctionArguments(exp))
3761| return FALSE;
3762| goto rest;
3763| case UserKeyword2 :
3764| keyword = new LeafUserKeyword2(tk);
3765| if(!rArgDeclList(exp, dummy_encode))
3766| return FALSE;
3767| rest:
3768| if(lex->GetToken(tk3) != ')')
3769| return FALSE;
3770|
3771| if(!rCompoundStatement(body))
3772| return FALSE;
3773|
3774| st = Ptree::List(keyword, new Leaf(tk2), exp, new Leaf(tk3),
3775| body);
3776| return TRUE;
3777| case UserKeyword3 :
3778| if(!rExprStatement(exp))
3779| return FALSE;
3780|
3781| if(lex->LookAhead(0) == ';')
3782| exp2 = nil;
3783| else
3784| if(!rCommaExpression(exp2))
3785| return FALSE;
3786|
3787| if(lex->GetToken(tk3) != ';')
3788| return FALSE;
3789|
3790| if(lex->LookAhead(0) == ')')
3791| exp3 = nil;
3792| else
3793| if(!rCommaExpression(exp3))
3794| return FALSE;
3795|
3796| if(lex->GetToken(tk4) != ')')
3797| return FALSE;
3798|
3799| if(!rCompoundStatement(body))
3800| return FALSE;
3801|
3802| st = Ptree::List(new Leaf(tk), new Leaf(tk2), exp, exp2,
3803| new Leaf(tk3), exp3, new Leaf(tk4), body);
3804| return TRUE;
3805| default :
3806| return FALSE;
3807| }
3808| }
3809|
3810| /*
3811| var.name : {'::'} name2 ('::' name2)*
3812|
3813| name2
3814| : Identifier {template.args}
3815| | '~' Identifier
3816| | OPERATOR operator.name
3817|
3818| if var.name ends with a template type, the next token must be '('
3819| */
3820| bool Parser::rVarName(Ptree*& name)
3821| {
3822| Encoding encode;
3823|
3824| if(rVarNameCore(name, encode)){
3825| if(!name->IsLeaf())
3826| name = new PtreeName(name, encode);
3827|
3828| return TRUE;
3829| }
3830| else
3831| return FALSE;
3832| }
3833|
3834| bool Parser::rVarNameCore(Ptree*& name, Encoding& encode)
3835| {
3836| Token tk;
3837| int length = 0;
3838|
3839| if(lex->LookAhead(0) == Scope){
3840| lex->GetToken(tk);
3841| name = Ptree::List(new Leaf(tk));
3842| encode.GlobalScope();
3843| ++length;
3844| }
3845| else
3846| name = nil;
3847|
3848| for(;;){
3849| int t = lex->GetToken(tk);
3850| if(t == TEMPLATE) {
3851| // Skip template token, next will be identifier
3852| t = lex->GetToken(tk);
3853| }
3854| if(t == Identifier){
3855| Ptree* n = new LeafName(tk);
3856| if(isTemplateArgs()){
3857| Ptree* args;
3858| Encoding args_encode;
3859| if(!rTemplateArgs(args, args_encode))
3860| return FALSE;
3861|
3862| encode.Template(n, args_encode);
3863| ++length;
3864| n = Ptree::List(n, args);
3865| }
3866| else{
3867| encode.SimpleName(n);
3868| ++length;
3869| }
3870|
3871| if(moreVarName()){
3872| lex->GetToken(tk);
3873| name = Ptree::Nconc(name, Ptree::List(n, new Leaf(tk)));
3874| }
3875| else{
3876| if(name == nil)
3877| name = n;
3878| else
3879| name = Ptree::Snoc(name, n);
3880|
3881| if(length > 1)
3882| encode.Qualified(length);
3883|
3884| return TRUE;
3885| }
3886| }
3887| else if(t == '~'){
3888| Token tk2;
3889| if(lex->LookAhead(0) != Identifier)
3890| return FALSE;
3891|
3892| lex->GetToken(tk2);
3893| Ptree* class_name = new Leaf(tk2);
3894| Ptree* dt = Ptree::List(new Leaf(tk), class_name);
3895| if(name == nil)
3896| name = dt;
3897| else
3898| name = Ptree::Snoc(name, dt);
3899|
3900| encode.Destructor(class_name);
3901| if(length > 0)
3902| encode.Qualified(length + 1);
3903|
3904| return TRUE;
3905| }
3906| else if(t == OPERATOR){
3907| Ptree* op;
3908| if(!rOperatorName(op, encode))
3909| return FALSE;
3910|
3911| Ptree* opf = Ptree::List(new LeafReserved(tk), op);
3912| if(name == nil)
3913| name = opf;
3914| else
3915| name = Ptree::Snoc(name, opf);
3916|
3917| if(length > 0)
3918| encode.Qualified(length + 1);
3919|
3920| return TRUE;
3921| }
3922| else
3923| return FALSE;
3924| }
3925| }
3926|
3927| bool Parser::moreVarName()
3928| {
3929| if(lex->LookAhead(0) == Scope){
3930| int t = lex->LookAhead(1);
3931| if(t == Identifier || t == '~' || t == OPERATOR || t == TEMPLATE)
3932| return TRUE;
3933| }
3934|
3935| return FALSE;
3936| }
3937|
3938| /*
3939| template.args : '<' any* '>'
3940|
3941| template.args must be followed by '(' or '::'
3942| */
3943| bool Parser::isTemplateArgs()
3944| {
3945| int i = 0;
3946| int t = lex->LookAhead(i++);
3947| if(t == '<'){
3948| int n = 1;
3949| while(n > 0){
3950| int u = lex->LookAhead(i++);
3951| if(u == '<')
3952| ++n;
3953| else if(u == '>')
3954| --n;
3955| else if(u == '('){
3956| int m = 1;
3957| while(m > 0){
3958| int v = lex->LookAhead(i++);
3959| if(v == '(')
3960| ++m;
3961| else if(v == ')')
3962| --m;
3963| else if(v == '\0' || v == ';' || v == '}')
3964| return FALSE;
3965| }
3966| }
3967| else if(u == '\0' || u == ';' || u == '}')
3968| return FALSE;
3969| }
3970|
3971| t = lex->LookAhead(i);
3972| return bool(t == Scope || t == '(');
3973| }
3974|
3975| return FALSE;
3976| }
3977|
3978| /*
3979| condition
3980| : comma.expression
3981| | declarator.with.init
3982|
3983| Condition is used inside if, switch statements where a declarator can be
3984| used if it is initialised.
3985| */
3986| bool Parser::rCondition(Ptree*& exp)
3987| {
3988| Encoding type_encode;
3989| char* save;
3990|
3991| // Do declarator first, otherwise "T*foo = blah" gets matched as a
3992| // multiplication infix expression inside an assignment expression!
3993| save = lex->Save();
3994| do {
3995| Ptree *storage_s, *cv_q, *cv_q2, *integral, *head, *decl;
3996|
3997| if (!optStorageSpec(storage_s))
3998| break;
3999|
4000| if (storage_s == nil)
4001| head = nil;
4002| else
4003| head = storage_s;
4004|
4005| if (!optCvQualify(cv_q)
4006| || !optIntegralTypeOrClassSpec(integral, type_encode))
4007| break;
4008|
4009| if (integral != nil) {
4010| // Integral Declaration
4011| // Find const after type
4012| if (!optCvQualify(cv_q2))
4013| break;
4014| // Make type ptree with pre and post const ptrees
4015| if (cv_q != nil)
4016| if (cv_q2 == nil)
4017| integral = Ptree::Snoc(cv_q, integral);
4018| else
4019| integral = Ptree::Nconc(cv_q,
4020| Ptree::Cons(integral, cv_q2));
4021| else if (cv_q2 != nil)
4022| integral = Ptree::Cons(integral, cv_q2);
4023| // Store type of CV's
4024| type_encode.CvQualify(cv_q, cv_q2);
4025| // Parse declarator
4026| if (!rDeclaratorWithInit(decl, type_encode, TRUE, FALSE))
4027| break;
4028| // *must* be end of condition, condition is in a () pair
4029| if (lex->LookAhead(0) != ')')
4030| break;
4031| exp = new PtreeDeclaration(head,
4032| Ptree::List(integral, decl));
4033| } else {
4034|
4035| Ptree *type_name;
4036| // Find name of type
4037| if (!rName(type_name, type_encode))
4038| break;
4039| // Find const after type
4040| if (!optCvQualify(cv_q2))
4041| break;
4042| // Make type ptree with pre and post const ptrees
4043| if (cv_q != nil)
4044| if (cv_q2 == nil)
4045| type_name = Ptree::Snoc(cv_q, type_name);
4046| else
4047| type_name = Ptree::Nconc(cv_q,
4048| Ptree::Cons(type_name, cv_q2));
4049| else if (cv_q2 != nil)
4050| type_name = Ptree::Cons(type_name, cv_q2);
4051| // Store type of CV's
4052| type_encode.CvQualify(cv_q, cv_q2);
4053| // Parse declarator
4054| if (!rDeclaratorWithInit(decl, type_encode, TRUE, FALSE))
4055| break;
4056| // *must* be end of condition, condition is in a () pair
4057| if (lex->LookAhead(0) != ')')
4058| break;
4059| exp = new PtreeDeclaration(head,
4060| Ptree::List(type_name, decl));
4061| }
4062| return TRUE;
4063| } while(0);
4064|
4065| // Must be a comma expression
4066| lex->Restore(save);
4067| return rCommaExpression(exp);
4068| }
4069|
4070| /*
4071| function.body : compound.statement
4072| */
4073| bool Parser::rFunctionBody(Ptree*& body)
4074| {
4075| return rCompoundStatement(body);
4076| }
4077|
4078| /*
4079| compound.statement
4080| : '{' (statement)* '}'
4081| */
4082| bool Parser::rCompoundStatement(Ptree*& body)
4083| {
4084| Token ob, cb;
4085| Ptree *ob_comments, *cb_comments;
4086|
4087| if(lex->GetToken(ob) != '{')
4088| return FALSE;
4089|
4090| ob_comments = lex->GetComments();
4091| Ptree* sts = nil;
4092| while(lex->LookAhead(0) != '}'){
4093| Ptree* st;
4094| if(!rStatement(st)){
4095| if(!SyntaxError())
4096| return FALSE; // too many error
4097|
4098| SkipTo('}');
4099| lex->GetToken(cb);
4100| body = Ptree::List(new Leaf(ob), nil, new Leaf(cb));
4101| return TRUE;
4102| }
4103|
4104| sts = Ptree::Snoc(sts, st);
4105| }
4106|
4107| if(lex->GetToken(cb) != '}')
4108| return FALSE;
4109|
4110| cb_comments = lex->GetComments();
4111| body = new PtreeBlock(new CommentedLeaf(ob, ob_comments), sts,
4112| new CommentedLeaf(cb, cb_comments));
4113| return TRUE;
4114| }
4115|
4116| /*
4117| statement
4118| : compound.statement
4119| | typedef
4120| | if.statement
4121| | switch.statement
4122| | while.statement
4123| | do.statement
4124| | for.statement
4125| | try.statement
4126| | BREAK ';'
4127| | CONTINUE ';'
4128| | RETURN { comma.expression } ';'
4129| | GOTO Identifier ';'
4130| | CASE expression ':' statement
4131| | DEFAULT ':' statement
4132| | Identifier ':' statement
4133| | expr.statement
4134| */
4135| bool Parser::rStatement(Ptree*& st)
4136| {
4137| Token tk1, tk2, tk3;
4138| Ptree *st2, *exp, *comments;
4139| int k;
4140|
4141| // Get the comments - if we dont make it past the switch then it is a
4142| // parse error anyway!
4143| comments = lex->GetComments();
4144|
4145| // Whichever case we get, it must succeed
4146| switch(k = lex->LookAhead(0)){
4147| case '{' :
4148| if (!rCompoundStatement(st)) return FALSE;
4149| break;
4150| case USING :
4151| if (!rUsing(st)) return FALSE;
4152| break;
4153| case TYPEDEF :
4154| if (!rTypedef(st)) return FALSE;
4155| break;
4156| case IF :
4157| if (!rIfStatement(st)) return FALSE;
4158| break;
4159| case SWITCH :
4160| if (!rSwitchStatement(st)) return FALSE;
4161| break;
4162| case WHILE :
4163| if (!rWhileStatement(st)) return FALSE;
4164| break;
4165| case DO :
4166| if (!rDoStatement(st)) return FALSE;
4167| break;
4168| case FOR :
4169| if (!rForStatement(st)) return FALSE;
4170| break;
4171| case TRY :
4172| if (!rTryStatement(st)) return FALSE;
4173| break;
4174| case BREAK :
4175| case CONTINUE :
4176| lex->GetToken(tk1);
4177| if(lex->GetToken(tk2) != ';')
4178| return FALSE;
4179|
4180| if(k == BREAK)
4181| st = new PtreeBreakStatement(new LeafReserved(tk1),
4182| Ptree::List(new Leaf(tk2)));
4183| else
4184| st = new PtreeContinueStatement(new LeafReserved(tk1),
4185| Ptree::List(new Leaf(tk2)));
4186| break;
4187| case RETURN :
4188| lex->GetToken(tk1);
4189| if(lex->LookAhead(0) == ';'){
4190| lex->GetToken(tk2);
4191| st = new PtreeReturnStatement(new LeafReserved(tk1),
4192| Ptree::List(new Leaf(tk2)));
4193| } else {
4194| if(!rCommaExpression(exp))
4195| return FALSE;
4196|
4197| if(lex->GetToken(tk2) != ';')
4198| return FALSE;
4199|
4200| st = new PtreeReturnStatement(new LeafReserved(tk1),
4201| Ptree::List(exp, new Leaf(tk2)));
4202| }
4203| break;
4204| case GOTO :
4205| lex->GetToken(tk1);
4206| if(lex->GetToken(tk2) != Identifier)
4207| return FALSE;
4208|
4209| if(lex->GetToken(tk3) != ';')
4210| return FALSE;
4211|
4212| st = new PtreeGotoStatement(new LeafReserved(tk1),
4213| Ptree::List(new Leaf(tk2), new Leaf(tk3)));
4214| break;
4215| case CASE :
4216| lex->GetToken(tk1);
4217| if(!rExpression(exp))
4218| return FALSE;
4219|
4220| if(lex->GetToken(tk2) != ':')
4221| return FALSE;
4222|
4223| if(!rStatement(st2))
4224| return FALSE;
4225|
4226| st = new PtreeCaseStatement(new LeafReserved(tk1),
4227| Ptree::List(exp, new Leaf(tk2), st2));
4228| break;
4229| case DEFAULT :
4230| lex->GetToken(tk1);
4231| if(lex->GetToken(tk2) != ':')
4232| return FALSE;
4233|
4234| if(!rStatement(st2))
4235| return FALSE;
4236|
4237| st = new PtreeDefaultStatement(new LeafReserved(tk1),
4238| Ptree::List(new Leaf(tk2), st2));
4239| break;
4240| case Identifier :
4241| if(lex->LookAhead(1) == ':'){ // label stateme
4242| lex->GetToken(tk1);
4243| lex->GetToken(tk2);
4244| if(!rStatement(st2))
4245| return FALSE;
4246|
4247| st = new PtreeLabelStatement(new Leaf(tk1),
4248| Ptree::List(new Leaf(tk2), st2));
4249| return TRUE;
4250| }
4251| // don't break here!
4252| default :
4253| if (!rExprStatement(st)) return FALSE;
4254| }
4255|
4256| // No parse error, attach comment to whatever was returned
4257| Walker::SetLeafComments(st, comments);
4258| return TRUE;
4259| }
4260|
4261| /*
4262| if.statement
4263| : IF '(' declaration.statement ')' statement { ELSE statement }
4264| : IF '(' comma.expression ')' statement { ELSE statement }
4265| */
4266| bool Parser::rIfStatement(Ptree*& st)
4267| {
4268| Token tk1, tk2, tk3, tk4;
4269| Ptree *exp, *then, *otherwise;
4270|
4271| if(lex->GetToken(tk1) != IF)
4272| return FALSE;
4273|
4274| if(lex->GetToken(tk2) != '(')
4275| return FALSE;
4276|
4277| if(!rCondition(exp))
4278| return FALSE;
4279|
4280| if(lex->GetToken(tk3) != ')')
4281| return FALSE;
4282|
4283| if(!rStatement(then))
4284| return FALSE;
4285|
4286| st = new PtreeIfStatement(new LeafReserved(tk1),
4287| Ptree::List(new Leaf(tk2), exp, new Leaf(tk3),
4288| then));
4289| if(lex->LookAhead(0) == ELSE){
4290| lex->GetToken(tk4);
4291| if(!rStatement(otherwise))
4292| return FALSE;
4293|
4294| st = Ptree::Nconc(st, Ptree::List(new Leaf(tk4), otherwise));
4295| }
4296|
4297| return TRUE;
4298| }
4299|
4300| /*
4301| switch.statement
4302| : SWITCH '(' comma.expression ')' statement
4303| */
4304| bool Parser::rSwitchStatement(Ptree*& st)
4305| {
4306| Token tk1, tk2, tk3;
4307| Ptree *exp, *body;
4308|
4309| if(lex->GetToken(tk1) != SWITCH)
4310| return FALSE;
4311|
4312| if(lex->GetToken(tk2) != '(')
4313| return FALSE;
4314|
4315| if(!rCondition(exp))
4316| return FALSE;
4317|
4318| if(lex->GetToken(tk3) != ')')
4319| return FALSE;
4320|
4321| if(!rStatement(body))
4322| return FALSE;
4323|
4324| st = new PtreeSwitchStatement(new LeafReserved(tk1),
4325| Ptree::List(new Leaf(tk2), exp,
4326| new Leaf(tk3), body));
4327| return TRUE;
4328| }
4329|
4330| /*
4331| while.statement
4332| : WHILE '(' comma.expression ')' statement
4333| */
4334| bool Parser::rWhileStatement(Ptree*& st)
4335| {
4336| Token tk1, tk2, tk3;
4337| Ptree *exp, *body;
4338|
4339| if(lex->GetToken(tk1) != WHILE)
4340| return FALSE;
4341|
4342| if(lex->GetToken(tk2) != '(')
4343| return FALSE;
4344|
4345| if(!rCommaExpression(exp))
4346| return FALSE;
4347|
4348| if(lex->GetToken(tk3) != ')')
4349| return FALSE;
4350|
4351| if(!rStatement(body))
4352| return FALSE;
4353|
4354| st = new PtreeWhileStatement(new LeafReserved(tk1),
4355| Ptree::List(new Leaf(tk2), exp,
4356| new Leaf(tk3), body));
4357| return TRUE;
4358| }
4359|
4360| /*
4361| do.statement
4362| : DO statement WHILE '(' comma.expression ')' ';'
4363| */
4364| bool Parser::rDoStatement(Ptree*& st)
4365| {
4366| Token tk0, tk1, tk2, tk3, tk4;
4367| Ptree *exp, *body;
4368|
4369| if(lex->GetToken(tk0) != DO)
4370| return FALSE;
4371|
4372| if(!rStatement(body))
4373| return FALSE;
4374|
4375| if(lex->GetToken(tk1) != WHILE)
4376| return FALSE;
4377|
4378| if(lex->GetToken(tk2) != '(')
4379| return FALSE;
4380|
4381| if(!rCommaExpression(exp))
4382| return FALSE;
4383|
4384| if(lex->GetToken(tk3) != ')')
4385| return FALSE;
4386|
4387| if(lex->GetToken(tk4) != ';')
4388| return FALSE;
4389|
4390| st = new PtreeDoStatement(new LeafReserved(tk0),
4391| Ptree::List(body, new LeafReserved(tk1),
4392| new Leaf(tk2), exp,
4393| new Leaf(tk3), new Leaf(tk4)));
4394| return TRUE;
4395| }
4396|
4397| /*
4398| for.statement
4399| : FOR '(' expr.statement {comma.expression} ';' {comma.expression} ')'
4400| statement
4401| */
4402| bool Parser::rForStatement(Ptree*& st)
4403| {
4404| Token tk1, tk2, tk3, tk4;
4405| Ptree *exp1, *exp2, *exp3, *body;
4406|
4407| if(lex->GetToken(tk1) != FOR)
4408| return FALSE;
4409|
4410| if(lex->GetToken(tk2) != '(')
4411| return FALSE;
4412|
4413| if(!rExprStatement(exp1))
4414| return FALSE;
4415|
4416| if(lex->LookAhead(0) == ';')
4417| exp2 = nil;
4418| else
4419| if(!rCommaExpression(exp2))
4420| return FALSE;
4421|
4422| if(lex->GetToken(tk3) != ';')
4423| return FALSE;
4424|
4425| if(lex->LookAhead(0) == ')')
4426| exp3 = nil;
4427| else
4428| if(!rCommaExpression(exp3))
4429| return FALSE;
4430|
4431| if(lex->GetToken(tk4) != ')')
4432| return FALSE;
4433|
4434| if(!rStatement(body))
4435| return FALSE;
4436|
4437|
4438| st = new PtreeForStatement(new LeafReserved(tk1),
4439| Ptree::List(new Leaf(tk2), exp1, exp2,
4440| new Leaf(tk3), exp3,
4441| new Leaf(tk4), body));
4442| return TRUE;
4443| }
4444|
4445| /*
4446| try.statement
4447| : TRY compound.statement (exception.handler)+ ';'
4448|
4449| exception.handler
4450| : CATCH '(' (arg.declaration | Ellipsis) ')' compound.statement
4451| */
4452| bool Parser::rTryStatement(Ptree*& st)
4453| {
4454| Token tk, op, cp;
4455| Ptree *body, *handler;
4456|
4457| if(lex->GetToken(tk) != TRY)
4458| return FALSE;
4459|
4460| if(!rCompoundStatement(body))
4461| return FALSE;
4462|
4463| st = new PtreeTryStatement(new LeafReserved(tk), Ptree::List(body));
4464|
4465| do{
4466| if(lex->GetToken(tk) != CATCH)
4467| return FALSE;
4468|
4469| if(lex->GetToken(op) != '(')
4470| return FALSE;
4471|
4472| if(lex->LookAhead(0) == Ellipsis){
4473| lex->GetToken(cp);
4474| handler = new Leaf(cp);
4475| }
4476| else{
4477| Encoding encode;
4478| if(!rArgDeclaration(handler, encode))
4479| return FALSE;
4480| }
4481|
4482| if(lex->GetToken(cp) != ')')
4483| return FALSE;
4484|
4485| if(!rCompoundStatement(body))
4486| return FALSE;
4487|
4488| st = Ptree::Snoc(st, Ptree::List(new LeafReserved(tk),
4489| new Leaf(op), handler, new Leaf(cp),
4490| body));
4491| } while(lex->LookAhead(0) == CATCH);
4492| return TRUE;
4493| }
4494|
4495| /*
4496| expr.statement
4497| : ';'
4498| | declaration.statement
4499| | comma.expression ';'
4500| | openc++.postfix.expr
4501| | openc++.primary.exp
4502| */
4503| bool Parser::rExprStatement(Ptree*& st)
4504| {
4505| Token tk;
4506|
4507| if(lex->LookAhead(0) == ';'){
4508| lex->GetToken(tk);
4509| st = new PtreeExprStatement(nil, Ptree::List(new Leaf(tk)));
4510| return TRUE;
4511| }
4512| else{
4513| char* pos = lex->Save();
4514| if(rDeclarationStatement(st))
4515| return TRUE;
4516| else{
4517| Ptree* exp;
4518| lex->Restore(pos);
4519| if(!rCommaExpression(exp))
4520| return FALSE;
4521|
4522| if(exp->IsA(ntUserStatementExpr, ntStaticUserStatementExpr)){
4523| st = exp;
4524| return TRUE;
4525| }
4526|
4527| if(lex->GetToken(tk) != ';')
4528| return FALSE;
4529|
4530| st = new PtreeExprStatement(exp, Ptree::List(new Leaf(tk)));
4531| return TRUE;
4532| }
4533| }
4534| }
4535|
4536| /*
4537| declaration.statement
4538| : decl.head integral.or.class.spec {cv.qualify} {declarators} ';'
4539| | decl.head name {cv.qualify} declarators ';'
4540| | const.declaration
4541|
4542| decl.head
4543| : {storage.spec} {cv.qualify}
4544|
4545| const.declaration
4546| : cv.qualify {'*'} Identifier '=' expression {',' declarators} ';'
4547|
4548| Note: if you modify this function, take a look at rDeclaration(), too.
4549| */
4550| bool Parser::rDeclarationStatement(Ptree*& statement)
4551| {
4552| Ptree *storage_s, *cv_q, *integral;
4553| Encoding type_encode;
4554|
4555| if(!optStorageSpec(storage_s)
4556| || !optCvQualify(cv_q)
4557| || !optIntegralTypeOrClassSpec(integral, type_encode))
4558| return FALSE;
4559|
4560| Ptree* head = nil;
4561| if(storage_s != nil)
4562| head = Ptree::Snoc(head, storage_s);
4563|
4564| if(integral != nil)
4565| return rIntegralDeclStatement(statement, type_encode, integral,
4566| cv_q, head);
4567| else{
4568| type_encode.Clear();
4569| int t = lex->LookAhead(0);
4570| if(cv_q != nil && ((t == Identifier && lex->LookAhead(1) == '=')
4571| || t == '*'))
4572| return rConstDeclaration(statement, type_encode, head, cv_q);
4573| else
4574| return rOtherDeclStatement(statement, type_encode, cv_q, head);
4575| }
4576| }
4577|
4578| /*
4579| integral.decl.statement
4580| : decl.head integral.or.class.spec {cv.qualify} {declarators} ';'
4581| */
4582| bool Parser::rIntegralDeclStatement(Ptree*& statement, Encoding& type_encode,
4583| Ptree* integral, Ptree* cv_q, Ptree* head)
4584| {
4585| Ptree *cv_q2, *decl;
4586| Token tk;
4587|
4588| if(!optCvQualify(cv_q2))
4589| return FALSE;
4590|
4591| if(cv_q != nil)
4592| if(cv_q2 == nil)
4593| integral = Ptree::Snoc(cv_q, integral);
4594| else
4595| integral = Ptree::Nconc(cv_q, Ptree::Cons(integral, cv_q2));
4596| else if(cv_q2 != nil)
4597| integral = Ptree::Cons(integral, cv_q2);
4598|
4599| type_encode.CvQualify(cv_q, cv_q2);
4600| if(lex->LookAhead(0) == ';'){
4601| lex->GetToken(tk);
4602| statement = new PtreeDeclaration(head, Ptree::List(integral,
4603| new Leaf(tk)));
4604| return TRUE;
4605| }
4606| else{
4607| if(!rDeclarators(decl, type_encode, FALSE, TRUE))
4608| return FALSE;
4609|
4610| if(lex->GetToken(tk) != ';')
4611| return FALSE;
4612|
4613| statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
4614| new Leaf(tk)));
4615| return TRUE;
4616| }
4617| }
4618|
4619| /*
4620| other.decl.statement
4621| :decl.head name {cv.qualify} declarators ';'
4622| */
4623| bool Parser::rOtherDeclStatement(Ptree*& statement, Encoding& type_encode,
4624| Ptree* cv_q, Ptree* head)
4625| {
4626| Ptree *type_name, *cv_q2, *decl;
4627| Token tk;
4628|
4629| if(!rName(type_name, type_encode))
4630| return FALSE;
4631|
4632| if(!optCvQualify(cv_q2))
4633| return FALSE;
4634|
4635| if(cv_q != nil)
4636| if(cv_q2 == nil)
4637| type_name = Ptree::Snoc(cv_q, type_name);
4638| else
4639| type_name = Ptree::Nconc(cv_q, Ptree::Cons(type_name, cv_q2));
4640| else if(cv_q2 != nil)
4641| type_name = Ptree::Cons(type_name, cv_q2);
4642|
4643| type_encode.CvQualify(cv_q, cv_q2);
4644| if(!rDeclarators(decl, type_encode, FALSE, TRUE))
4645| return FALSE;
4646|
4647| if(lex->GetToken(tk) != ';')
4648| return FALSE;
4649|
4650| statement = new PtreeDeclaration(head, Ptree::List(type_name, decl,
4651| new Leaf(tk)));
4652| return TRUE;
4653| }
4654|
4655| bool Parser::MaybeTypeNameOrClassTemplate(Token&)
4656| {
4657| return TRUE;
4658| }
4659|
4660| void Parser::SkipTo(int token)
4661| {
4662| Token tk;
4663|
4664| for(;;){
4665| int t = lex->LookAhead(0);
4666| if(t == token || t == '\0')
4667| break;
4668| else
4669| lex->GetToken(tk);
4670| }
4671| }
4672|
4673| #ifdef TEST
4674|
4675| #include "buffer.h"
4676| #include "walker.h"
4677|
4678| main()
4679| {
4680| ProgramFromStdin p
4681| Lex
4682| Parser
4683| Walker
4684| Ptree*
4685|
4686| while(parse.rProgram(def)){
4687| def->Display2(std::cout);
4688| w.Translate(def);
4689| }
4690|
4691| std::cerr << parse.NumOfErrors() << " errors\n";
4692| }
4693| #endif