Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

parse.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
00013 */
00014 
00015 /*
00016    C++ Parser
00017 
00018    This parser is a LL(k) parser with ad hoc rules such as
00019    backtracking.
00020 
00021    r<name>() is the grammer rule for a non-terminal <name>.
00022    opt<name>() is the grammer fule for an optional non-terminal <name>.
00023    is<name>() looks ahead and returns TRUE if the next symbol is <name>.
00024 */
00025 
00026 #include <iostream.h>
00027 #include "parse.h"
00028 #include "token.h"
00029 #include "env.h"
00030 #include "ptree.h"
00031 #include "encoding.h"
00032 #include "metaclass.h"
00033 #include "walker.h"
00034 
00035 #if defined(_PARSE_VCC)
00036 #define _MSC_VER        1100
00037 #endif
00038 
00039 const int MaxErrors = 10;
00040 
00041 Parser::Parser(Lex* l)
00042 {
00043     lex = l;
00044     nerrors = 0;
00045 }
00046 
00047 bool Parser::ErrorMessage(const char* msg, Ptree* name, Ptree* where)
00048 {
00049     if(where != nil){
00050         Ptree* head = where->Ca_ar();
00051         if(head != nil)
00052             ShowMessageHead(head->GetPosition());
00053     }
00054 
00055     cerr << msg;
00056     if(name != nil)
00057         name->Write(cerr);
00058 
00059     cerr << '\n';
00060     return bool(++nerrors < MaxErrors);
00061 }
00062 
00063 void Parser::WarningMessage(const char* msg, Ptree* name, Ptree* where)
00064 {
00065     if(where != nil){
00066         Ptree* head = where->Ca_ar();
00067         if(head != nil)
00068             ShowMessageHead(head->GetPosition());
00069     }
00070 
00071     cerr << "warning: " << msg;
00072     if(name != nil)
00073         name->Write(cerr);
00074 
00075     cerr << '\n';
00076 }
00077 
00078 bool Parser::SyntaxError()
00079 {
00080     Token t, t2;
00081     int i;
00082 
00083     lex->LookAhead(0, t);
00084     lex->LookAhead(1, t2);
00085 
00086     ShowMessageHead(t.ptr);
00087     cerr << "parse error before `";
00088     if(t.kind != '\0')
00089         for(i = 0; i < t.len; ++i)
00090             cerr << t.ptr[i];
00091 
00092     if(t2.kind != '\0'){
00093         cerr << ' ';
00094         for(i = 0; i < t2.len; ++i)
00095             cerr << t2.ptr[i];
00096     }
00097 
00098     cerr << "'\n";
00099     return bool(++nerrors < MaxErrors);
00100 }
00101 
00102 uint Parser::LineNumber(char* pos, char*& fname, int& fname_len)
00103 {
00104     uint line_number = lex->LineNumber(pos, fname, fname_len);
00105     if(fname_len > 1){
00106         if(fname[0] == '"') {
00107             ++fname;
00108             --fname_len;
00109         }
00110 
00111         if(fname[fname_len - 1] == '"')
00112             --fname_len;
00113     }
00114 
00115     return line_number;
00116 }
00117 
00118 void Parser::ShowMessageHead(char* pos)
00119 {
00120     char* fname;
00121     int fname_len;
00122 
00123     uint line_number = LineNumber(pos, fname, fname_len);
00124     int i = 0;
00125     while(i < fname_len)
00126         cerr << fname[i++];
00127 
00128 #if defined(_MSC_VER)
00129     cerr << '(' << line_number << ") : ";
00130 #else
00131     cerr << ':' << line_number << ": ";
00132 #endif
00133 }
00134 
00135 bool Parser::rProgram(Ptree*& def)
00136 {
00137     while(lex->LookAhead(0) != '\0')
00138         if(rDefinition(def))
00139             return TRUE;
00140         else{
00141             Token tk;
00142             if(!SyntaxError())
00143                 return FALSE;           // too many errors
00144 
00145             SkipTo(';');
00146             lex->GetToken(tk);  // ignore ';'
00147         }
00148 
00149     return FALSE;
00150 }
00151 
00152 /*
00153   definition
00154   : null.declaration
00155   | typedef
00156   | template.decl
00157   | metaclass.decl
00158   | linkage.spec
00159   | namespace.spec
00160   | using.declaration
00161   | extern.template.decl
00162   | declaration
00163 */
00164 bool Parser::rDefinition(Ptree*& p)
00165 {
00166     bool res;
00167     int t = lex->LookAhead(0);
00168     if(t == ';')
00169         res = rNullDeclaration(p);
00170     else if(t == TYPEDEF)
00171         res = rTypedef(p);
00172     else if(t == TEMPLATE)
00173         res = rTemplateDecl(p);
00174     else if(t == METACLASS)
00175         res = rMetaclassDecl(p);
00176     else if(t == EXTERN && lex->LookAhead(1) == StringL)
00177         res = rLinkageSpec(p);
00178     else if(t == EXTERN && lex->LookAhead(1) == TEMPLATE)
00179         res = rExternTemplateDecl(p);
00180     else if(t == NAMESPACE)
00181         res = rNamespaceSpec(p);
00182     else if(t == USING)
00183         res = rUsing(p);
00184     else {
00185         Ptree* c = lex->GetComments2();
00186         if (res = rDeclaration(p))
00187             Walker::SetDeclaratorComments(p, c);
00188     }
00189 
00190     lex->GetComments();
00191     return res;
00192 }
00193 
00194 bool Parser::rNullDeclaration(Ptree*& decl)
00195 {
00196     Token tk;
00197 
00198     if(lex->GetToken(tk) != ';')
00199         return FALSE;
00200 
00201     decl = new PtreeDeclaration(nil, Ptree::List(nil, new Leaf(tk)));
00202     return TRUE;
00203 }
00204 
00205 /*
00206   typedef
00207   : TYPEDEF type.specifier declarators ';'
00208 */
00209 bool Parser::rTypedef(Ptree*& def)
00210 {
00211     Token tk;
00212     Ptree *type_name, *decl;
00213     Encoding type_encode;
00214 
00215     if(lex->GetToken(tk) != TYPEDEF)
00216         return FALSE;
00217 
00218     def = new PtreeTypedef(new LeafReserved(tk));
00219     if(!rTypeSpecifier(type_name, FALSE, type_encode))
00220         return FALSE;
00221 
00222     def = Ptree::Snoc(def, type_name);
00223     if(!rDeclarators(decl, type_encode, TRUE))
00224         return FALSE;
00225 
00226     if(lex->GetToken(tk) != ';')
00227         return FALSE;
00228 
00229     def = Ptree::Nconc(def, Ptree::List(decl, new Leaf(tk)));
00230     return TRUE;
00231 }
00232 
00233 /*
00234   type.specifier
00235   : {cv.qualify} (integral.or.class.spec | name) {cv.qualify}
00236 */
00237 bool Parser::rTypeSpecifier(Ptree*& tspec, bool check, Encoding& encode)
00238 {
00239     Ptree *cv_q, *cv_q2;
00240 
00241     if(!optCvQualify(cv_q) || !optIntegralTypeOrClassSpec(tspec, encode))
00242         return FALSE;
00243 
00244     if(tspec == nil){
00245         if(check){
00246             Token tk;
00247             lex->LookAhead(0, tk);
00248             if(!MaybeTypeNameOrClassTemplate(tk))
00249                 return FALSE;
00250         }
00251 
00252         if(!rName(tspec, encode))
00253             return FALSE;
00254     }
00255 
00256     if(!optCvQualify(cv_q2))
00257         return FALSE;
00258 
00259     if(cv_q != nil){
00260         tspec = Ptree::Snoc(cv_q, tspec);
00261         if(cv_q2 != nil)
00262             tspec = Ptree::Nconc(tspec, cv_q2);
00263     }
00264     else if(cv_q2 != nil)
00265         tspec = Ptree::Cons(tspec, cv_q2);
00266 
00267     encode.CvQualify(cv_q, cv_q2);
00268     return TRUE;
00269 }
00270 
00271 // isTypeSpecifier() returns TRUE if the next is probably a type specifier.
00272 
00273 bool Parser::isTypeSpecifier()
00274 {
00275     int t = lex->LookAhead(0);
00276     if(t == Identifier || t == Scope
00277        ||t == CONST || t == VOLATILE
00278        || t == CHAR || t == INT || t == SHORT || t == LONG
00279        || t == SIGNED || t == UNSIGNED || t == FLOAT || t == DOUBLE
00280        || t == VOID || t == BOOLEAN
00281        || t == CLASS || t == STRUCT || t == UNION || t == ENUM
00282 #if defined(_MSC_VER)
00283        || t == INT64
00284 #endif
00285        )
00286         return TRUE;
00287     else
00288         return FALSE;
00289 }
00290 
00291 /*
00292   metaclass.decl
00293   : METACLASS Identifier {{':'} Identifier {'(' meta.arguments ')'}} ';'
00294 
00295   We allow two kinds of syntax:
00296 
00297   metaclass <metaclass> <class>(...);
00298   metaclass <metaclass>;
00299   metaclass <class> : <metaclass>(...);         // for backward compatibility
00300 */
00301 bool Parser::rMetaclassDecl(Ptree*& decl)
00302 {
00303     int t;
00304     Token tk1, tk2, tk3, tk4;
00305     Ptree* metaclass_name;
00306 
00307     if(lex->GetToken(tk1) != METACLASS)
00308         return FALSE;
00309 
00310     if(lex->GetToken(tk2) != Identifier)
00311         return FALSE;
00312 
00313     t = lex->GetToken(tk3);
00314     if(t == Identifier){
00315         metaclass_name = new Leaf(tk2);
00316         decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
00317                                       Ptree::List(metaclass_name,
00318                                                   new Leaf(tk3)));
00319     }
00320     else if(t == ':'){
00321         if(lex->GetToken(tk4) != Identifier)
00322             return FALSE;
00323 
00324         metaclass_name = new Leaf(tk4);
00325         decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
00326                                       Ptree::List(metaclass_name,
00327                                                   new Leaf(tk2)));
00328     }
00329     else if(t == ';'){
00330         metaclass_name = new Leaf(tk2);
00331         decl = new PtreeMetaclassDecl(new LeafReserved(tk1),
00332                                       Ptree::List(metaclass_name, nil,
00333                                                   new Leaf(tk3)));
00334         Metaclass::Load(metaclass_name);
00335         return TRUE;
00336     }
00337     else
00338         return FALSE;
00339 
00340     t = lex->GetToken(tk1);
00341     if(t == '('){
00342         Ptree* args;
00343         if(!rMetaArguments(args))
00344             return FALSE;
00345 
00346         if(lex->GetToken(tk2) != ')')
00347             return FALSE;
00348 
00349         decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1), args,
00350                                               new Leaf(tk2)));
00351         t = lex->GetToken(tk1);
00352     }
00353 
00354     if(t == ';'){
00355         decl = Ptree::Snoc(decl, new Leaf(tk1));
00356         Metaclass::Load(metaclass_name);
00357         return TRUE;
00358     }
00359     else
00360         return FALSE;
00361 }
00362 
00363 /*
00364   meta.arguments : (anything but ')')*
00365 */
00366 bool Parser::rMetaArguments(Ptree*& args)
00367 {
00368     int t;
00369     Token tk;
00370 
00371     int n = 1;
00372     args = nil;
00373     for(;;){
00374         t = lex->LookAhead(0);
00375         if(t == '\0')
00376             return FALSE;
00377         else if(t == '(')
00378             ++n;
00379         else if(t == ')')
00380             if(--n <= 0)
00381                 return TRUE;
00382 
00383         lex->GetToken(tk);
00384         args = Ptree::Snoc(args, new Leaf(tk));
00385     }
00386 }
00387 
00388 /*
00389   linkage.spec
00390   : EXTERN StringL definition
00391   |  EXTERN StringL linkage.body
00392 */
00393 bool Parser::rLinkageSpec(Ptree*& spec)
00394 {
00395     Token tk1, tk2;
00396     Ptree* body;
00397 
00398     if(lex->GetToken(tk1) != EXTERN)
00399         return FALSE;
00400 
00401     if(lex->GetToken(tk2) != StringL)
00402         return FALSE;
00403 
00404     spec = new PtreeLinkageSpec(new LeafEXTERN(tk1),
00405                                 Ptree::List(new Leaf(tk2)));
00406     if(lex->LookAhead(0) == '{'){
00407         if(!rLinkageBody(body))
00408             return FALSE;
00409     }
00410     else
00411         if(!rDefinition(body))
00412             return FALSE;
00413 
00414     spec = Ptree::Snoc(spec, body);
00415     return TRUE;
00416 }
00417 
00418 /*
00419   namespace.spec
00420   : NAMESPACE Identifier definition
00421   | NAMESPACE { Identifier } linkage.body
00422 */
00423 bool Parser::rNamespaceSpec(Ptree*& spec)
00424 {
00425     Token tk1, tk2;
00426     Ptree* name;
00427     Ptree* body;
00428 
00429     if(lex->GetToken(tk1) != NAMESPACE)
00430         return FALSE;
00431 
00432     if(lex->LookAhead(0) == '{')
00433         name = nil;
00434     else
00435         if(lex->GetToken(tk2) == Identifier)
00436             name = new Leaf(tk2);
00437         else
00438             return FALSE;
00439 
00440     if(lex->LookAhead(0) == '{'){
00441         if(!rLinkageBody(body))
00442             return FALSE;
00443     }
00444     else
00445         if(!rDefinition(body))
00446             return FALSE;
00447 
00448     spec = new PtreeNamespaceSpec(new LeafNAMESPACE(tk1),
00449                                   Ptree::List(name, body));
00450     return TRUE;
00451 }
00452 
00453 
00454 /*
00455   using.declaration : USING { NAMESPACE } name ';'
00456 */
00457 bool Parser::rUsing(Ptree*& decl)
00458 {
00459     Token tk;
00460     Ptree* name;
00461     Encoding encode;
00462 
00463     if(lex->GetToken(tk) != USING)
00464         return FALSE;
00465 
00466     Ptree* using0 = new LeafUSING(tk);
00467     Ptree* using1;
00468     if (lex->LookAhead(0) != NAMESPACE)
00469         using1 = nil;
00470     else {
00471         lex->GetToken(tk);
00472         using1 = new LeafNAMESPACE(tk);
00473     }
00474 
00475     if (!rName(name, encode))
00476         return FALSE;
00477 
00478     if (lex->GetToken(tk) != ';')
00479         return FALSE;
00480 
00481     decl = new PtreeUsing(using0, using1, name, encode, new Leaf(tk));
00482     return TRUE;
00483 }
00484 
00485 
00486 /*
00487   linkage.body : '{' (definition)* '}'
00488 
00489   Note: this is also used to construct namespace.spec
00490 */
00491 bool Parser::rLinkageBody(Ptree*& body)
00492 {
00493     Token op, cp;
00494     Ptree* def;
00495 
00496     if(lex->GetToken(op) != '{')
00497         return FALSE;
00498 
00499     body = nil;
00500     while(lex->LookAhead(0) != '}'){
00501         if(!rDefinition(def)){
00502             if(!SyntaxError())
00503                 return FALSE;           // too many errors
00504 
00505             SkipTo('}');
00506             lex->GetToken(cp);
00507             body = Ptree::List(new Leaf(op), nil, new Leaf(cp));
00508             return TRUE;                // error recovery
00509         }
00510 
00511         body = Ptree::Snoc(body, def);
00512     }
00513 
00514     lex->GetToken(cp);
00515     body = new PtreeBrace(new Leaf(op), body, new Leaf(cp));
00516     return TRUE;
00517 }
00518 
00519 /*
00520   template.decl
00521   : TEMPLATE '<' temp.arg.list '>' declaration
00522   | TEMPLATE declaration
00523   | TEMPLATE '<' '>' declaration
00524 
00525   The second case is an explicit template instantiation.  declaration must
00526   be a class declaration.  For example,
00527 
00528       template class Foo<int, char>;
00529 
00530   explicitly instantiates the template Foo with int and char.
00531 
00532   The third case is a specialization of a template function.  declaration
00533   must be a function template.  For example,
00534 
00535       template <> int count(String x) { return x.length; }
00536 */
00537 bool Parser::rTemplateDecl(Ptree*& decl)
00538 {
00539     Ptree *body;
00540     TemplateDeclKind kind = tdk_unknown;
00541 
00542     if(!rTemplateDecl2(decl, kind))
00543         return FALSE;
00544 
00545     if(!rDeclaration(body))
00546         return FALSE;
00547 
00548     // Repackage the decl and body depending upon what kind of template
00549     // declaration was observed.
00550     switch (kind) {
00551     case tdk_instantiation:
00552         // Repackage the decl as a PtreeTemplateInstantiation
00553         decl = body;
00554         // assumes that decl has the form: [nil [class ...] ;]
00555         if (Ptree::Length(decl) != 3)
00556             return FALSE;
00557 
00558         if (Ptree::First(decl) != nil)
00559             return FALSE;
00560 
00561         if (Ptree::Second(decl)->What() != ntClassSpec)
00562             return FALSE;
00563 
00564         if (!Ptree::Eq(Ptree::Third(decl), ';'))
00565             return FALSE;
00566 
00567         decl = new PtreeTemplateInstantiation(Ptree::Second(decl));
00568         break;
00569     case tdk_decl:
00570     case tdk_specialization:
00571         decl = Ptree::Snoc(decl, body);
00572         break;
00573     default:
00574         MopErrorMessage("rTemplateDecl()", "fatal");
00575         break;
00576     }
00577 
00578     return TRUE;
00579 }
00580 
00581 bool Parser::rTemplateDecl2(Ptree*& decl, TemplateDeclKind &kind)
00582 {
00583     Token tk;
00584     Ptree *args;
00585 
00586     if(lex->GetToken(tk) != TEMPLATE)
00587         return FALSE;
00588 
00589     if(lex->LookAhead(0) != '<') {
00590         // template instantiation
00591         decl = nil;
00592         kind = tdk_instantiation;
00593         return TRUE;    // ignore TEMPLATE
00594     }
00595 
00596     decl = new PtreeTemplateDecl(new LeafReserved(tk));
00597     if(lex->GetToken(tk) != '<')
00598         return FALSE;
00599 
00600     decl = Ptree::Snoc(decl, new Leaf(tk));
00601     if(!rTempArgList(args))
00602         return FALSE;
00603 
00604     if(lex->GetToken(tk) != '>')
00605         return FALSE;
00606 
00607     decl = Ptree::Nconc(decl, Ptree::List(args, new Leaf(tk)));
00608 
00609     // ignore nested TEMPLATE
00610     while (lex->LookAhead(0) == TEMPLATE) {
00611         lex->GetToken(tk);
00612         if(lex->LookAhead(0) != '<')
00613             break;
00614 
00615         lex->GetToken(tk);
00616         if(!rTempArgList(args))
00617             return FALSE;
00618 
00619         if(lex->GetToken(tk) != '>')
00620             return FALSE;
00621     }
00622 
00623     if (args == nil)
00624         // template < > declaration
00625         kind = tdk_specialization;
00626     else
00627         // template < ... > declaration
00628         kind = tdk_decl;
00629 
00630     return TRUE;
00631 }
00632 
00633 /*
00634   temp.arg.list
00635   : empty
00636   | temp.arg.declaration (',' temp.arg.declaration)*
00637 */
00638 bool Parser::rTempArgList(Ptree*& args)
00639 {
00640     Token tk;
00641     Ptree* a;
00642 
00643     if(lex->LookAhead(0) == '>'){
00644         args = nil;
00645         return TRUE;
00646     }
00647 
00648     if(!rTempArgDeclaration(a))
00649         return FALSE;
00650 
00651     args = Ptree::List(a);
00652     while(lex->LookAhead(0) == ','){
00653         lex->GetToken(tk);
00654         args = Ptree::Snoc(args, new Leaf(tk));
00655         if(!rTempArgDeclaration(a))
00656             return FALSE;
00657 
00658         args = Ptree::Snoc(args, a);
00659     }
00660 
00661     return TRUE;
00662 }
00663 
00664 /*
00665   temp.arg.declaration
00666   : CLASS Identifier {'=' type.name}
00667   | type.specifier arg.declarator {'=' additive.expr}
00668   | template.decl2 CLASS Identifier {'=' type.name}
00669 */
00670 bool Parser::rTempArgDeclaration(Ptree*& decl)
00671 {
00672     Token tk1, tk2;
00673 
00674     int t0 = lex->LookAhead(0);
00675     if(t0 == CLASS && lex->LookAhead(1) == Identifier){
00676         lex->GetToken(tk1);
00677         lex->GetToken(tk2);
00678         Ptree* name = new Leaf(tk2);
00679         decl = Ptree::List(new Leaf(tk1), name);
00680 
00681         if(lex->LookAhead(0) == '='){
00682             Ptree* default_type;
00683 
00684             lex->GetToken(tk1);
00685             if(!rTypeName(default_type))
00686                 return FALSE;
00687 
00688             decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
00689                                                   default_type));
00690         }
00691     }
00692     else if (t0 == TEMPLATE) {
00693         TemplateDeclKind kind;
00694         if(!rTemplateDecl2(decl, kind))
00695             return FALSE;
00696 
00697         if (lex->GetToken(tk1) != CLASS || lex->GetToken(tk2) != Identifier)
00698             return FALSE;
00699 
00700         Ptree* cspec = new PtreeClassSpec(new LeafReserved(tk1),
00701                                           Ptree::Cons(new Leaf(tk2),nil),
00702                                           nil);
00703         decl = Ptree::Snoc(decl, cspec);
00704         if(lex->LookAhead(0) == '='){
00705             Ptree* default_type;
00706             lex->GetToken(tk1);
00707             if(!rTypeName(default_type))
00708                 return FALSE;
00709 
00710             decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1),
00711                                                   default_type));
00712         }
00713     }
00714     else{
00715         Ptree *type_name, *arg;
00716         Encoding type_encode, name_encode;
00717         if(!rTypeSpecifier(type_name, TRUE, type_encode))
00718             return FALSE;
00719 
00720         if(!rDeclarator(arg, kArgDeclarator, FALSE, type_encode, name_encode,
00721                         TRUE))
00722             return FALSE;
00723 
00724         decl = Ptree::List(type_name, arg);
00725         if(lex->LookAhead(0) == '='){
00726             Ptree* exp;
00727             lex->GetToken(tk1);
00728             if(!rAdditiveExpr(exp))
00729                 return FALSE;
00730 
00731             decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk1), exp));
00732         }
00733     }
00734 
00735     return TRUE;
00736 }
00737 
00738 /*
00739    extern.template.decl
00740    : EXTERN TEMPLATE declaration
00741 */
00742 bool Parser::rExternTemplateDecl(Ptree*& decl)
00743 {
00744     Token tk1, tk2;
00745     Ptree* body;
00746 
00747     if(lex->GetToken(tk1) != EXTERN)
00748         return FALSE;
00749 
00750     if(lex->GetToken(tk2) != TEMPLATE)
00751         return FALSE;
00752 
00753     if(!rDeclaration(body))
00754         return FALSE;
00755 
00756     decl = new PtreeExternTemplate(new Leaf(tk1),
00757                                    Ptree::List(new Leaf(tk2), body));
00758     return TRUE;
00759 }
00760 
00761 /*
00762   declaration
00763   : integral.declaration
00764   | const.declaration
00765   | other.declaration
00766 
00767   decl.head
00768   : {member.spec} {storage.spec} {member.spec} {cv.qualify}
00769 
00770   integral.declaration
00771   : integral.decl.head declarators (';' | function.body)
00772   | integral.decl.head ';'
00773   | integral.decl.head ':' expression ';'
00774 
00775   integral.decl.head
00776   : decl.head integral.or.class.spec {cv.qualify}
00777 
00778   other.declaration
00779   : decl.head name {cv.qualify} declarators (';' | function.body)
00780   | decl.head name constructor.decl (';' | function.body)
00781   | FRIEND name ';'
00782 
00783   const.declaration
00784   : cv.qualify {'*'} Identifier '=' expression {',' declarators} ';'
00785 
00786   Note: if you modify this function, look at declaration.statement, too.
00787   Note: this regards a statement like "T (a);" as a constructor
00788         declaration.  See isConstructorDecl().
00789 */
00790 bool Parser::rDeclaration(Ptree*& statement)
00791 {
00792     Ptree *mem_s, *storage_s, *cv_q, *integral, *head;
00793     Encoding type_encode;
00794 
00795     if(!optMemberSpec(mem_s) || !optStorageSpec(storage_s))
00796         return FALSE;
00797 
00798     if(mem_s == nil)
00799         head = nil;
00800     else
00801         head = mem_s;   // mem_s is a list.
00802 
00803     if(storage_s != nil)
00804         head = Ptree::Snoc(head, storage_s);
00805 
00806     if(mem_s == nil)
00807         if(optMemberSpec(mem_s))
00808             head = Ptree::Nconc(head, mem_s);
00809         else
00810             return FALSE;
00811 
00812     if(!optCvQualify(cv_q)
00813        || !optIntegralTypeOrClassSpec(integral, type_encode))
00814         return FALSE;
00815 
00816     if(integral != nil)
00817         return rIntegralDeclaration(statement, type_encode,
00818                                     head, integral, cv_q);
00819     else{
00820         type_encode.Clear();
00821         int t = lex->LookAhead(0);
00822         if(cv_q != nil && ((t == Identifier && lex->LookAhead(1) == '=')
00823                            || t == '*'))
00824             return rConstDeclaration(statement, type_encode, head, cv_q);
00825         else
00826             return rOtherDeclaration(statement, type_encode,
00827                                      mem_s, cv_q, head);
00828     }
00829 }
00830 
00831 bool Parser::rIntegralDeclaration(Ptree*& statement, Encoding& type_encode,
00832                                   Ptree* head, Ptree* integral, Ptree* cv_q)
00833 {
00834     Token tk;
00835     Ptree *cv_q2, *decl;
00836 
00837     if(!optCvQualify(cv_q2))
00838         return FALSE;
00839 
00840     if(cv_q != nil)
00841         if(cv_q2 == nil)
00842             integral = Ptree::Snoc(cv_q, integral);
00843         else
00844             integral = Ptree::Nconc(cv_q, Ptree::Cons(integral, cv_q2));
00845     else if(cv_q2 != nil)
00846         integral = Ptree::Cons(integral, cv_q2);
00847 
00848     type_encode.CvQualify(cv_q, cv_q2);
00849     switch(lex->LookAhead(0)){
00850     case ';' :
00851         lex->GetToken(tk);
00852         statement = new PtreeDeclaration(head, Ptree::List(integral,
00853                                                            new Leaf(tk)));
00854         return TRUE;
00855     case ':' :  // bit field
00856         lex->GetToken(tk);
00857         if(!rExpression(decl))
00858             return FALSE;
00859 
00860         decl = Ptree::List(Ptree::List(new Leaf(tk), decl));
00861         if(lex->GetToken(tk) != ';')
00862             return FALSE;
00863 
00864         statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
00865                                                            new Leaf(tk)));
00866         return TRUE;
00867     default :
00868         if(!rDeclarators(decl, type_encode, TRUE))
00869             return FALSE;
00870 
00871         if(lex->LookAhead(0) == ';'){
00872             lex->GetToken(tk);
00873             statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
00874                                                                new Leaf(tk)));
00875             return TRUE;
00876         }
00877         else{
00878             Ptree* body;
00879             if(!rFunctionBody(body))
00880                 return FALSE;
00881 
00882             if(Ptree::Length(decl) != 1)
00883                 return FALSE;
00884 
00885             statement = new PtreeDeclaration(head,
00886                                              Ptree::List(integral,
00887                                                          decl->Car(), body));
00888             return TRUE;
00889         }
00890     }
00891 }
00892 
00893 bool Parser::rConstDeclaration(Ptree*& statement, Encoding&,
00894                                Ptree* head, Ptree* cv_q)
00895 {
00896     Ptree* decl;
00897     Token tk;
00898     Encoding type_encode;
00899 
00900     type_encode.SimpleConst();
00901     if(!rDeclarators(decl, type_encode, FALSE))
00902         return FALSE;
00903 
00904     if(lex->LookAhead(0) != ';')
00905         return FALSE;
00906 
00907     lex->GetToken(tk);
00908     statement = new PtreeDeclaration(head, Ptree::List(cv_q, decl,
00909                                                        new Leaf(tk)));
00910     return TRUE;
00911 }
00912 
00913 bool Parser::rOtherDeclaration(Ptree*& statement, Encoding& type_encode,
00914                                Ptree* mem_s, Ptree* cv_q, Ptree* head)
00915 {
00916     Ptree *type_name, *decl, *cv_q2;
00917     Token tk;
00918 
00919     if(!rName(type_name, type_encode))
00920         return FALSE;
00921 
00922     if(cv_q == nil && isConstructorDecl()){
00923         Encoding ftype_encode;
00924         if(!rConstructorDecl(decl, ftype_encode))
00925             return FALSE;
00926 
00927         decl = Ptree::List(new PtreeDeclarator(type_name, decl,
00928                                                ftype_encode, type_encode,
00929                                                type_name));
00930         type_name = nil;
00931     }
00932     else if(mem_s != nil && lex->LookAhead(0) == ';'){
00933         // FRIEND name ';'
00934         if(Ptree::Length(mem_s) == 1 && mem_s->Car()->What() == FRIEND){
00935             lex->GetToken(tk);
00936             statement = new PtreeDeclaration(head, Ptree::List(type_name,
00937                                                                new Leaf(tk)));
00938             return TRUE;
00939         }
00940         else
00941             return FALSE;
00942     }
00943     else{
00944         if(!optCvQualify(cv_q2))
00945             return FALSE;
00946 
00947         if(cv_q != nil)
00948             if(cv_q2 == nil)
00949                 type_name = Ptree::Snoc(cv_q, type_name);
00950             else
00951                 type_name = Ptree::Nconc(cv_q, Ptree::Cons(type_name, cv_q2));
00952         else if(cv_q2 != nil)
00953             type_name = Ptree::Cons(type_name, cv_q2);
00954 
00955         type_encode.CvQualify(cv_q, cv_q2);
00956         if(!rDeclarators(decl, type_encode, FALSE))
00957             return FALSE;
00958     }
00959 
00960     if(lex->LookAhead(0) == ';'){
00961         lex->GetToken(tk);
00962         statement = new PtreeDeclaration(head, Ptree::List(type_name, decl,
00963                                                            new Leaf(tk)));
00964     }
00965     else{
00966         Ptree* body;
00967         if(!rFunctionBody(body))
00968             return FALSE;
00969 
00970         if(Ptree::Length(decl) != 1)
00971             return FALSE;
00972 
00973         statement = new PtreeDeclaration(head, Ptree::List(type_name,
00974                                                            decl->Car(), body));
00975     }
00976 
00977     return TRUE;
00978 }
00979 
00980 /*
00981   This returns TRUE for an declaration like:
00982         T (a);
00983   even if a is not a type name.  This is a bug according to the ANSI
00984   specification, but I believe none says "T (a);" for a variable
00985   declaration.
00986 */
00987 bool Parser::isConstructorDecl()
00988 {
00989     if(lex->LookAhead(0) != '(')
00990         return FALSE;
00991     else{
00992         int t = lex->LookAhead(1);
00993         if(t == '*' || t == '&' || t == '(')
00994             return FALSE;       // declarator
00995         else if(t == CONST || t == VOLATILE)
00996             return TRUE;        // constructor or declarator
00997         else if(isPtrToMember(1))
00998             return FALSE;       // declarator (::*)
00999         else
01000             return TRUE;        // maybe constructor
01001     }
01002 }
01003 
01004 /*
01005   ptr.to.member
01006   : {'::'} (identifier {'<' any* '>'} '::')+ '*'
01007 */
01008 bool Parser::isPtrToMember(int i)
01009 {
01010     int t0 = lex->LookAhead(i++);
01011 
01012     if(t0 == Scope)
01013         t0 = lex->LookAhead(i++);
01014 
01015     while(t0 == Identifier){
01016         int t = lex->LookAhead(i++);
01017         if(t == '<'){
01018             int n = 1;
01019             while(n > 0){
01020                 int u = lex->LookAhead(i++);
01021                 if(u == '<')
01022                     ++n;
01023                 else if(u == '>')
01024                     --n;
01025                 else if(u == '('){
01026                     int m = 1;
01027                     while(m > 0){
01028                         int v = lex->LookAhead(i++);
01029                         if(v == '(')
01030                             ++m;
01031                         else if(v == ')')
01032                             --m;
01033                         else if(v == '\0' || v == ';' || v == '}')
01034                             return FALSE;
01035                     }
01036                 }
01037                 else if(u == '\0' || u == ';' || u == '}')
01038                     return FALSE;
01039             }
01040 
01041             t = lex->LookAhead(i++);
01042         }
01043 
01044         if(t != Scope)
01045             return FALSE;
01046 
01047         t0 = lex->LookAhead(i++);
01048         if(t0 == '*')
01049             return TRUE;
01050     }
01051 
01052     return FALSE;
01053 }
01054 
01055 /*
01056   member.spec
01057   : (FRIEND | INLINE | VIRTUAL | userdef.keyword)+
01058 */
01059 bool Parser::optMemberSpec(Ptree*& p)
01060 {
01061     Token tk;
01062     Ptree* lf;
01063     int t = lex->LookAhead(0);
01064 
01065     p = nil;
01066     while(t == FRIEND || t == INLINE || t == VIRTUAL || t == UserKeyword5){
01067         if(t == UserKeyword5){
01068             if(!rUserdefKeyword(lf))
01069                 return FALSE;
01070         }
01071         else{
01072             lex->GetToken(tk);
01073             if(t == INLINE)
01074                 lf = new LeafINLINE(tk);
01075             else if(t == VIRTUAL)
01076                 lf = new LeafVIRTUAL(tk);
01077             else
01078                 lf = new LeafFRIEND(tk);
01079         }
01080 
01081         p = Ptree::Snoc(p, lf);
01082         t = lex->LookAhead(0);
01083     }
01084 
01085     return TRUE;
01086 }
01087 
01088 /*
01089   storage.spec : STATIC | EXTERN | AUTO | REGISTER | MUTABLE
01090 */
01091 bool Parser::optStorageSpec(Ptree*& p)
01092 {
01093     int t = lex->LookAhead(0);
01094     if(t == STATIC || t == EXTERN || t == AUTO || t == REGISTER
01095        || t == MUTABLE){
01096         Token tk;
01097         lex->GetToken(tk);
01098         switch(t){
01099         case STATIC :
01100             p = new LeafSTATIC(tk);
01101             break;
01102         case EXTERN :
01103             p = new LeafEXTERN(tk);
01104             break;
01105         case AUTO :
01106             p = new LeafAUTO(tk);
01107             break;
01108         case REGISTER :
01109             p = new LeafREGISTER(tk);
01110             break;
01111         case MUTABLE :
01112             p = new LeafMUTABLE(tk);
01113             break;
01114         default :
01115             MopErrorMessage("optStorageSpec()", "fatal");
01116             break;
01117         }
01118     }
01119     else
01120         p = nil;        // no storage specifier
01121 
01122     return TRUE;
01123 }
01124 
01125 /*
01126   cv.qualify : (CONST | VOLATILE)+
01127 */
01128 bool Parser::optCvQualify(Ptree*& cv)
01129 {
01130     Ptree* p = nil;
01131     for(;;){
01132         int t = lex->LookAhead(0);
01133         if(t == CONST || t == VOLATILE){
01134             Token tk;
01135             lex->GetToken(tk);
01136             switch(t){
01137             case CONST :
01138                 p = Ptree::Snoc(p, new LeafCONST(tk));
01139                 break;
01140             case VOLATILE :
01141                 p = Ptree::Snoc(p, new LeafVOLATILE(tk));
01142                 break;
01143             default :
01144                 MopErrorMessage("optCvQualify()", "fatal");
01145                 break;
01146             }
01147         }
01148         else
01149             break;
01150     }
01151 
01152     cv = p;
01153     return TRUE;
01154 }
01155 
01156 /*
01157   integral.or.class.spec
01158   : (CHAR | INT | SHORT | LONG | SIGNED | UNSIGNED | FLOAT | DOUBLE
01159      | VOID | BOOLEAN)+
01160   | class.spec
01161   | enum.spec
01162 
01163   Note: if editing this, see also isTypeSpecifier().
01164 */
01165 bool Parser::optIntegralTypeOrClassSpec(Ptree*& p, Encoding& encode)
01166 {
01167     bool is_integral;
01168     int t;
01169     char type = ' ', flag = ' ';
01170 
01171     is_integral = FALSE;
01172     p = nil;
01173     for(;;){
01174         t = lex->LookAhead(0);
01175         if(t == CHAR || t == INT || t == SHORT || t == LONG || t == SIGNED
01176            || t == UNSIGNED || t == FLOAT || t == DOUBLE || t == VOID
01177            || t == BOOLEAN
01178 #if defined(_MSC_VER)
01179            || t == INT64
01180 #endif
01181            ){
01182             Token tk;
01183             Ptree* kw;
01184             lex->GetToken(tk);
01185             switch(t){
01186             case CHAR :
01187                 type = 'c';
01188                 kw = new LeafCHAR(tk);
01189                 break;
01190             case INT :
01191 #if defined(_MSC_VER)
01192             case INT64 : // an int64 is *NOT* an int but...
01193 #endif
01194                 if(type != 's' && type != 'l' && type != 'j' && type != 'r')
01195                     type = 'i';
01196 
01197                 kw = new LeafINT(tk);
01198                 break;
01199             case SHORT :
01200                 type = 's';
01201                 kw = new LeafSHORT(tk);
01202                 break;
01203             case LONG :
01204                 if(type == 'l')
01205                     type = 'j';         // long long
01206                 else if(type == 'd')
01207                     type = 'r';         // double long
01208                 else
01209                     type = 'l';
01210 
01211                 kw = new LeafLONG(tk);
01212                 break;
01213             case SIGNED :
01214                 flag = 'S';
01215                 kw = new LeafSIGNED(tk);
01216                 break;
01217             case UNSIGNED :
01218                 flag = 'U';
01219                 kw = new LeafUNSIGNED(tk);
01220                 break;
01221             case FLOAT :
01222                 type = 'f';
01223                 kw = new LeafFLOAT(tk);
01224                 break;
01225             case DOUBLE :
01226                 if(type == 'l')
01227                     type = 'r';         // long double
01228                 else
01229                     type = 'd';
01230 
01231                 kw = new LeafDOUBLE(tk);
01232                 break;
01233             case VOID :
01234                 type = 'v';
01235                 kw = new LeafVOID(tk);
01236                 break;
01237             case BOOLEAN :
01238                 type = 'b';
01239                 kw = new LeafBOOLEAN(tk);
01240                 break;
01241             default :
01242                 MopErrorMessage("optIntegralTypeOrClassSpec()", "fatal");
01243                 kw = nil;
01244                 break;
01245             }
01246 
01247             p = Ptree::Snoc(p, kw);
01248             is_integral = TRUE;
01249         }
01250         else
01251             break;
01252     }
01253 
01254     if(is_integral){
01255         if(flag == 'S' && type != 'c')
01256             flag = ' ';
01257 
01258         if(flag != ' ')
01259             encode.Append(flag);
01260 
01261         if(type == ' ')
01262             type = 'i';         // signed, unsigned
01263 
01264         encode.Append(type);
01265         return TRUE;
01266     }
01267 
01268     if(t == CLASS || t == STRUCT || t == UNION || t == UserKeyword)
01269         return rClassSpec(p, encode);
01270     else if(t == ENUM)
01271         return rEnumSpec(p, encode);
01272     else{
01273         p = nil;
01274         return TRUE;
01275     }
01276 }
01277 
01278 /*
01279   constructor.decl
01280   : '(' {arg.decl.list} ')' {cv.qualify} {throw.decl}
01281   {member.initializers} {'=' Constant}
01282 */
01283 bool Parser::rConstructorDecl(Ptree*& constructor, Encoding& encode)
01284 {
01285     Token op, cp;
01286     Ptree *args, *cv, *throw_decl, *mi;
01287 
01288     if(lex->GetToken(op) != '(')
01289         return FALSE;
01290 
01291     if(lex->LookAhead(0) == ')'){
01292         args = nil;
01293         encode.StartFuncArgs();
01294         encode.Void();
01295         encode.EndFuncArgs();
01296     }
01297     else
01298         if(!rArgDeclList(args, encode))
01299             return FALSE;
01300 
01301     lex->GetToken(cp);
01302     constructor = Ptree::List(new Leaf(op), args, new Leaf(cp));
01303     optCvQualify(cv);
01304     if(cv != nil){
01305         encode.CvQualify(cv);
01306         constructor = Ptree::Nconc(constructor, cv);
01307     }
01308 
01309     optThrowDecl(throw_decl);   // ignore in this version
01310 
01311     if(lex->LookAhead(0) == ':')
01312         if(rMemberInitializers(mi))
01313             constructor = Ptree::Snoc(constructor, mi);
01314         else
01315             return FALSE;
01316 
01317     if(lex->LookAhead(0) == '='){
01318         Token eq, zero;
01319         lex->GetToken(eq);
01320         if(lex->GetToken(zero) != Constant)
01321             return FALSE;
01322 
01323         constructor = Ptree::Nconc(constructor,
01324                                    Ptree::List(new Leaf(eq), new Leaf(zero)));
01325     }
01326 
01327     encode.NoReturnType();
01328     return TRUE;
01329 }
01330 
01331 /*
01332   throw.decl : THROW '(' (name {','})* {name} ')'
01333 */
01334 bool Parser::optThrowDecl(Ptree*& throw_decl)
01335 {
01336     Token tk;
01337     int t;
01338     Ptree* p = nil;
01339 
01340     if(lex->LookAhead(0) == THROW){
01341         lex->GetToken(tk);
01342         p = Ptree::Snoc(p, new LeafReserved(tk));
01343 
01344         if(lex->GetToken(tk) != '(')
01345             return FALSE;
01346 
01347         p = Ptree::Snoc(p, new Leaf(tk));
01348 
01349         for(;;){
01350             Ptree* q;
01351             Encoding encode;
01352             t = lex->LookAhead(0);
01353             if(t == '\0')
01354                 return FALSE;
01355             else if(t == ')')
01356                 break;
01357             else if(rName(q, encode))
01358                 p = Ptree::Snoc(p, q);
01359             else
01360                 return FALSE;
01361 
01362             if(lex->LookAhead(0) == ','){
01363                 lex->GetToken(tk);
01364                 p = Ptree::Snoc(p, new Leaf(tk));
01365             }
01366             else
01367                 break;
01368         }
01369 
01370         if(lex->GetToken(tk) != ')')
01371             return FALSE;
01372 
01373         p = Ptree::Snoc(p, new Leaf(tk));
01374     }
01375 
01376     throw_decl = p;
01377     return TRUE;
01378 }
01379 
01380 /*
01381   declarators : declarator.with.init (',' declarator.with.init)*
01382 
01383   is_statement changes the behavior of rArgDeclListOrInit().
01384 */
01385 bool Parser::rDeclarators(Ptree*& decls, Encoding& type_encode,
01386                           bool should_be_declarator, bool is_statement)
01387 {
01388     Ptree* d;
01389     Token tk;
01390     Encoding encode;
01391 
01392     decls = nil;
01393     for(;;){
01394         encode.Reset(type_encode);
01395         if(!rDeclaratorWithInit(d, encode, should_be_declarator, is_statement))
01396             return FALSE;
01397 
01398         decls = Ptree::Snoc(decls, d);
01399         if(lex->LookAhead(0) == ','){
01400             lex->GetToken(tk);
01401             decls = Ptree::Snoc(decls, new Leaf(tk));
01402         }
01403         else
01404             return TRUE;
01405     };
01406 }
01407 
01408 /*
01409   declarator.with.init
01410   : ':' expression
01411   | declarator {'=' initialize.expr | ':' expression}
01412 */
01413 bool Parser::rDeclaratorWithInit(Ptree*& dw, Encoding& type_encode,
01414                                  bool should_be_declarator,
01415                                  bool is_statement)
01416 {
01417     Ptree *d, *e;
01418     Token tk;
01419     Encoding name_encode;
01420 
01421     if(lex->LookAhead(0) == ':'){       // bit field
01422         lex->GetToken(tk);
01423         if(!rExpression(e))
01424             return FALSE;
01425 
01426         dw = Ptree::List(new Leaf(tk), e);
01427         return TRUE;
01428     }
01429     else{
01430         if(!rDeclarator(d, kDeclarator, FALSE, type_encode, name_encode,
01431                         should_be_declarator, is_statement))
01432             return FALSE;
01433 
01434         int t = lex->LookAhead(0);
01435         if(t == '='){
01436             lex->GetToken(tk);
01437             if(!rInitializeExpr(e))
01438                 return FALSE;
01439 
01440             dw = Ptree::Nconc(d, Ptree::List(new Leaf(tk), e));
01441             return TRUE;
01442         }
01443         else if(t == ':'){              // bit field
01444             lex->GetToken(tk);
01445             if(!rExpression(e))
01446                 return FALSE;
01447 
01448             dw = Ptree::Nconc(d, Ptree::List(new Leaf(tk), e));
01449             return TRUE;
01450         }
01451         else{
01452             dw = d;
01453             return TRUE;
01454         }
01455     }
01456 }
01457 
01458 /*
01459   declarator
01460   : (ptr.operator)* (name | '(' declarator ')')
01461         ('[' comma.expression ']')* {func.args.or.init}
01462 
01463   func.args.or.init
01464   : '(' arg.decl.list.or.init ')' {cv.qualify} {throw.decl}
01465   {member.initializers}
01466 
01467   Note: We assume that '(' declarator ')' is followed by '(' or '['.
01468         This is to avoid accepting a function call F(x) as a pair of
01469         a type F and a declarator x.  This assumption is ignored
01470         if should_be_declarator is true.
01471 
01472   Note: An argument declaration list and a function-style initializer
01473         take a different Ptree structure.
01474         e.g.
01475             int f(char) ==> .. [f ( [[[char] nil]] )]
01476             Point f(1)  ==> .. [f [( [1] )]]
01477 
01478   Note: is_statement changes the behavior of rArgDeclListOrInit().
01479 */
01480 bool Parser::rDeclarator(Ptree*& decl, DeclKind kind, bool recursive,
01481                          Encoding& type_encode, Encoding& name_encode,
01482                          bool should_be_declarator, bool is_statement)
01483 {
01484     return rDeclarator2(decl, kind, recursive, type_encode, name_encode,
01485                         should_be_declarator, is_statement, nil);
01486 }
01487 
01488 bool Parser::rDeclarator2(Ptree*& decl, DeclKind kind, bool recursive,
01489                           Encoding& type_encode, Encoding& name_encode,
01490                           bool should_be_declarator, bool is_statement,
01491                           Ptree** declared_name)
01492 {
01493     Encoding recursive_encode;
01494     Ptree *d;
01495     int t;
01496     bool recursive_decl = FALSE;
01497     Ptree *declared_name0 = nil;
01498 
01499     if(declared_name == nil)
01500         declared_name = &declared_name0;
01501 
01502     if(!optPtrOperator(d, type_encode))
01503         return FALSE;
01504 
01505     t = lex->LookAhead(0);
01506     if(t == '('){
01507         Token op, cp;
01508         Ptree* decl2;
01509         lex->GetToken(op);
01510         recursive_decl = TRUE;
01511         if(!rDeclarator2(decl2, kind, TRUE, recursive_encode, name_encode,
01512                          TRUE, FALSE, declared_name))
01513             return FALSE;
01514 
01515         if(lex->GetToken(cp) != ')')
01516             return FALSE;
01517 
01518         if(!should_be_declarator)
01519             if(kind == kDeclarator && d == nil){
01520                 t = lex->LookAhead(0);
01521                 if(t != '[' && t != '(')
01522                     return FALSE;
01523             }
01524 
01525         d = Ptree::Snoc(d, Ptree::List(new Leaf(op), decl2, new Leaf(cp)));
01526     }
01527     else if(kind != kCastDeclarator
01528            && (kind == kDeclarator || t == Identifier || t == Scope)){
01529         // if this is an argument declarator, "int (*)()" is valid.
01530         Ptree* name;
01531         if(rName(name, name_encode))
01532             d = Ptree::Snoc(d, name);
01533         else
01534             return FALSE;
01535 
01536         *declared_name = name;
01537     }
01538     else
01539         name_encode.Clear();    // empty
01540 
01541     for(;;){
01542         t = lex->LookAhead(0);
01543         if(t == '('){           // function
01544             Encoding args_encode;
01545             Token op, cp;
01546             Ptree *args, *cv, *throw_decl, *mi;
01547             bool is_args = TRUE;
01548 
01549             lex->GetToken(op);
01550             if(lex->LookAhead(0) == ')'){
01551                 args = nil;
01552                 args_encode.StartFuncArgs();
01553                 args_encode.Void();
01554                 args_encode.EndFuncArgs();
01555             }
01556             else
01557                 if(!rArgDeclListOrInit(args, is_args, args_encode,
01558                                        is_statement))
01559                     return FALSE;
01560 
01561             if(lex->GetToken(cp) != ')')
01562                 return FALSE;
01563 
01564             if(is_args){
01565                 d = Ptree::Nconc(d, Ptree::List(new Leaf(op), args,
01566                                                 new Leaf(cp)));
01567                 optCvQualify(cv);
01568                 if(cv != nil){
01569                     args_encode.CvQualify(cv);
01570                     d = Ptree::Nconc(d, cv);
01571                 }
01572             }
01573             else
01574                 d = Ptree::Snoc(d, Ptree::List(new Leaf(op), args,
01575                                                new Leaf(cp)));
01576 
01577             if(!args_encode.IsEmpty())
01578                 type_encode.Function(args_encode);
01579 
01580             optThrowDecl(throw_decl);   // ignore in this version
01581 
01582             if(lex->LookAhead(0) == ':')
01583                 if(rMemberInitializers(mi))
01584                     d = Ptree::Snoc(d, mi);
01585                 else
01586                     return FALSE;
01587 
01588             break;              // "T f(int)(char)" is invalid.
01589         }
01590         else if(t == '['){      // array
01591             Token ob, cb;
01592             Ptree* expr;
01593             lex->GetToken(ob);
01594             if(lex->LookAhead(0) == ']')
01595                 expr = nil;
01596             else
01597                 if(!rCommaExpression(expr))
01598                     return FALSE;
01599 
01600             if(lex->GetToken(cb) != ']')
01601                 return FALSE;
01602 
01603             type_encode.Array();
01604             d = Ptree::Nconc(d, Ptree::List(new Leaf(ob), expr,
01605                                             new Leaf(cb)));
01606         }
01607         else
01608             break;
01609     }
01610 
01611     if(recursive_decl)
01612         type_encode.Recursion(recursive_encode);
01613 
01614     if(recursive)
01615         decl = d;
01616     else
01617         if(d == nil)
01618             decl = new PtreeDeclarator(type_encode, name_encode,
01619                                        *declared_name);
01620         else
01621             decl = new PtreeDeclarator(d, type_encode, name_encode,
01622                                        *declared_name);
01623 
01624     return TRUE;
01625 }
01626 
01627 /*
01628   ptr.operator
01629   : (('*' | '&' | ptr.to.member) {cv.qualify})+
01630 */
01631 bool Parser::optPtrOperator(Ptree*& ptrs, Encoding& encode)
01632 {
01633     ptrs = nil;
01634     for(;;){
01635         int t = lex->LookAhead(0);
01636         if(t != '*' && t != '&' && !isPtrToMember(0))
01637             break;
01638         else{
01639             Ptree *op, *cv;
01640             if(t == '*' || t == '&'){
01641                 Token tk;
01642                 lex->GetToken(tk);
01643                 op = new Leaf(tk);
01644                 encode.PtrOperator(t);
01645             }
01646             else
01647                 if(!rPtrToMember(op, encode))
01648                     return FALSE;
01649 
01650             ptrs = Ptree::Snoc(ptrs, op);
01651             optCvQualify(cv);
01652             if(cv != nil){
01653                 ptrs = Ptree::Nconc(ptrs, cv);
01654                 encode.CvQualify(cv);
01655             }
01656         }
01657     }
01658 
01659     return TRUE;
01660 }
01661 
01662 /*
01663   member.initializers
01664   : ':' member.init (',' member.init)*
01665 */
01666 bool Parser::rMemberInitializers(Ptree*& init)
01667 {
01668     Token tk;
01669     Ptree* m;
01670 
01671     if(lex->GetToken(tk) != ':')
01672         return FALSE;
01673 
01674     init = Ptree::List(new Leaf(tk));
01675     if(!rMemberInit(m))
01676         return FALSE;
01677 
01678     init = Ptree::Snoc(init, m);
01679     while(lex->LookAhead(0) == ','){
01680         lex->GetToken(tk);
01681         init = Ptree::Snoc(init, new Leaf(tk));
01682         if(!rMemberInit(m))
01683             return FALSE;
01684 
01685         init = Ptree::Snoc(init, m);
01686     }
01687 
01688     return TRUE;
01689 }
01690 
01691 /*
01692   member.init
01693   : name '(' function.arguments ')'
01694 */
01695 bool Parser::rMemberInit(Ptree*& init)
01696 {
01697     Ptree *name, *args;
01698     Token tk1, tk2;
01699     Encoding encode;
01700 
01701     if(!rName(name, encode))
01702         return FALSE;
01703 
01704     if(!name->IsLeaf())
01705         name = new PtreeName(name, encode);
01706 
01707     if(lex->GetToken(tk1) != '(')
01708         return FALSE;
01709 
01710     if(!rFunctionArguments(args))
01711         return FALSE;
01712 
01713     if(lex->GetToken(tk2) != ')')
01714         return FALSE;
01715 
01716     init = Ptree::List(name, new Leaf(tk1), args, new Leaf(tk2));
01717     return TRUE;
01718 }
01719 
01720 /*
01721   name : {'::'} name2 ('::' name2)*
01722 
01723   name2
01724   : Identifier {template.args}
01725   | '~' Identifier
01726   | OPERATOR operator.name {template.args}
01727 
01728   Don't use this function for parsing an expression
01729   It always regards '<' as the beginning of template arguments.
01730 */
01731 bool Parser::rName(Ptree*& name, Encoding& encode)
01732 {
01733     Token tk, tk2;
01734     int t;
01735     int length = 0;
01736 
01737     if(lex->LookAhead(0) == Scope){
01738         lex->GetToken(tk);
01739         name = Ptree::List(new Leaf(tk));
01740         encode.GlobalScope();
01741         ++length;
01742     }
01743     else
01744         name = nil;
01745 
01746     for(;;){
01747         t = lex->GetToken(tk);
01748         if(t == Identifier){
01749             Ptree* n = new Leaf(tk);
01750             t = lex->LookAhead(0);
01751             if(t == '<'){
01752                 Ptree* args;
01753                 Encoding args_encode;
01754                 if(!rTemplateArgs(args, args_encode))
01755                     return FALSE;
01756 
01757                 encode.Template(n, args_encode);
01758                 ++length;
01759                 n = Ptree::List(n, args);
01760                 t = lex->LookAhead(0);
01761             }
01762             else{
01763                 encode.SimpleName(n);
01764                 ++length;
01765             }
01766 
01767             if(t == Scope){
01768                 lex->GetToken(tk);
01769                 name = Ptree::Nconc(name, Ptree::List(n, new Leaf(tk)));
01770             }
01771             else{
01772                 if(name == nil)
01773                     name = n;
01774                 else
01775                     name = Ptree::Snoc(name, n);
01776 
01777                 if(length > 1)
01778                     encode.Qualified(length);
01779 
01780                 return TRUE;
01781             }
01782         }
01783         else if(t == '~'){
01784             if(lex->LookAhead(0) != Identifier)
01785                 return FALSE;
01786 
01787             lex->GetToken(tk2);
01788             Ptree* class_name = new Leaf(tk2);
01789             Ptree* dt = Ptree::List(new Leaf(tk), class_name);
01790             if(name == nil)
01791                 name = dt;
01792             else
01793                 name = Ptree::Snoc(name, dt);
01794 
01795             encode.Destructor(class_name);
01796             if(length > 0)
01797                 encode.Qualified(length + 1);
01798 
01799             return TRUE;
01800         }
01801         else if(t == OPERATOR){
01802             Ptree* op;
01803             Ptree* opf;
01804             if(!rOperatorName(op, encode))
01805                 return FALSE;
01806 
01807             t = lex->LookAhead(0);
01808             if(t != '<')
01809                 opf = Ptree::List(new LeafReserved(tk), op);
01810             else {
01811                 Ptree* args;
01812                 Encoding args_encode;
01813                 if(!rTemplateArgs(args, args_encode))
01814                     return FALSE;
01815 
01816                 // here, I must merge args_encode into encode.
01817                 // I'll do it in future. :p
01818 
01819                 opf = Ptree::List(new LeafReserved(tk), op, args);
01820             }
01821 
01822             if(name == nil)
01823                 name = opf;
01824             else
01825                 name = Ptree::Snoc(name, opf);
01826 
01827             if(length > 0)
01828                 encode.Qualified(length + 1);
01829 
01830             return TRUE;
01831         }
01832         else
01833             return FALSE;
01834     }
01835 }
01836 
01837 /*
01838   operator.name
01839   : '+' | '-' | '*' | '/' | '%' | '^' | '&' | '|' | '~'
01840   | '!' | '=' | '<' | '>' | AssignOp | ShiftOp | EqualOp
01841   | RelOp | LogAndOp | LogOrOp | IncOp | ',' | PmOp | ArrowOp
01842   | NEW {'[' ']'}
01843   | DELETE {'[' ']'}
01844   | '(' ')'
01845   | '[' ']'
01846   | cast.operator.name
01847 */
01848 bool Parser::rOperatorName(Ptree*& name, Encoding& encode)
01849 {
01850     Token tk;
01851 
01852     int t = lex->LookAhead(0);
01853     if(t == '+' || t == '-' || t == '*' || t == '/' || t == '%' || t == '^'
01854        || t == '&' || t == '|' || t == '~' || t == '!' || t == '=' || t == '<'
01855        || t == '>' || t == AssignOp || t == ShiftOp || t == EqualOp
01856        || t == RelOp || t == LogAndOp || t == LogOrOp || t == IncOp
01857        || t == ',' || t == PmOp || t == ArrowOp){
01858         lex->GetToken(tk);
01859         name = new Leaf(tk);
01860         encode.SimpleName(name);
01861         return TRUE;
01862     }
01863     else if(t == NEW || t == DELETE){
01864         lex->GetToken(tk);
01865         if(lex->LookAhead(0) != '['){
01866             name = new LeafReserved(tk);
01867             encode.SimpleName(name);
01868             return TRUE;
01869         }
01870         else{
01871             name = Ptree::List(new LeafReserved(tk));
01872             lex->GetToken(tk);
01873             name = Ptree::Snoc(name, new Leaf(tk));
01874             if(lex->GetToken(tk) != ']')
01875                 return FALSE;
01876 
01877             name = Ptree::Snoc(name, new Leaf(tk));
01878             if(t == NEW)
01879                 encode.AppendWithLen("new[]", 5);
01880             else
01881                 encode.AppendWithLen("delete[]", 8);
01882 
01883             return TRUE;
01884         }
01885     }
01886     else if(t == '('){
01887         lex->GetToken(tk);
01888         name = Ptree::List(new Leaf(tk));
01889         if(lex->GetToken(tk) != ')')
01890             return FALSE;
01891 
01892         encode.AppendWithLen("()", 2);
01893         name = Ptree::Snoc(name, new Leaf(tk));
01894         return TRUE;
01895     }
01896     else if(t == '['){
01897         lex->GetToken(tk);
01898         name = Ptree::List(new Leaf(tk));
01899         if(lex->GetToken(tk) != ']')
01900             return FALSE;
01901 
01902         encode.AppendWithLen("[]", 2);
01903         name = Ptree::Snoc(name, new Leaf(tk));
01904         return TRUE;
01905     }
01906     else
01907         return rCastOperatorName(name, encode);
01908 }
01909 
01910 /*
01911   cast.operator.name
01912   : {cv.qualify} (integral.or.class.spec | name) {cv.qualify}
01913     {(ptr.operator)*}
01914 */
01915 bool Parser::rCastOperatorName(Ptree*& name, Encoding& encode)
01916 {
01917     Ptree *cv1, *cv2, *type_name, *ptr;
01918     Encoding type_encode;
01919 
01920     if(!optCvQualify(cv1))
01921         return FALSE;
01922 
01923     if(!optIntegralTypeOrClassSpec(type_name, type_encode))
01924         return FALSE;
01925 
01926     if(type_name == nil){
01927         type_encode.Clear();
01928         if(!rName(type_name, type_encode))
01929             return FALSE;
01930     }
01931 
01932     if(!optCvQualify(cv2))
01933         return FALSE;
01934 
01935     if(cv1 != nil)
01936         if(cv2 == nil)
01937             type_name = Ptree::Snoc(cv1, type_name);
01938         else
01939             type_name = Ptree::Nconc(cv1, Ptree::Cons(type_name, cv2));
01940     else if(cv2 != nil)
01941         type_name = Ptree::Cons(type_name, cv2);
01942 
01943     type_encode.CvQualify(cv1, cv2);
01944 
01945     if(!optPtrOperator(ptr, type_encode))
01946         return FALSE;
01947 
01948     encode.CastOperator(type_encode);
01949     if(ptr == nil){
01950         name = type_name;
01951         return TRUE;
01952     }
01953     else{
01954         name = Ptree::List(type_name, ptr);
01955         return TRUE;
01956     }
01957 }
01958 
01959 /*
01960   ptr.to.member
01961   : {'::'} (identifier {template.args} '::')+ '*'
01962 */
01963 bool Parser::rPtrToMember(Ptree*& ptr_to_mem, Encoding& encode)
01964 {
01965     Token tk;
01966     Ptree *p, *n;
01967     Encoding pm_encode;
01968     int length = 0;
01969 
01970     if(lex->LookAhead(0) == Scope){
01971         lex->GetToken(tk);
01972         p = Ptree::List(new Leaf(tk));
01973         pm_encode.GlobalScope();
01974         ++length;
01975     }
01976     else
01977         p = nil;
01978 
01979     for(;;){
01980         if(lex->GetToken(tk) == Identifier)
01981             n = new Leaf(tk);
01982         else
01983             return FALSE;
01984 
01985         int t = lex->LookAhead(0);
01986         if(t == '<'){
01987             Ptree* args;
01988             Encoding args_encode;
01989             if(!rTemplateArgs(args, args_encode))
01990                 return FALSE;
01991 
01992             pm_encode.Template(n, args_encode);
01993             ++length;
01994             n = Ptree::List(n, args);
01995             t = lex->LookAhead(0);
01996         }
01997         else{
01998             pm_encode.SimpleName(n);
01999             ++length;
02000         }
02001 
02002         if(lex->GetToken(tk) != Scope)
02003             return FALSE;
02004 
02005         p = Ptree::Nconc(p, Ptree::List(n, new Leaf(tk)));
02006         if(lex->LookAhead(0) == '*'){
02007             lex->GetToken(tk);
02008             p = Ptree::Snoc(p, new Leaf(tk));
02009             break;
02010         }
02011     }
02012 
02013     ptr_to_mem = p;
02014     encode.PtrToMember(pm_encode, length);
02015     return TRUE;
02016 }
02017 
02018 /*
02019   template.args
02020   : '<' '>'
02021   | '<' template.argument {',' template.argument} '>'
02022 
02023   template.argument
02024   : type.name
02025   | logical.or.expr
02026 */
02027 bool Parser::rTemplateArgs(Ptree*& temp_args, Encoding& encode)
02028 {
02029     Token tk1, tk2;
02030     Encoding type_encode;
02031 
02032     if(lex->GetToken(tk1) != '<')
02033         return FALSE;
02034 
02035     // in case of Foo<>
02036     if(lex->LookAhead(0) == '>') {
02037         lex->GetToken(tk2);
02038         temp_args = Ptree::List(new Leaf(tk1), new Leaf(tk2));
02039         return TRUE;
02040     }
02041 
02042     Ptree* args = nil;
02043     for(;;){
02044         Ptree* a;
02045         char* pos = lex->Save();
02046         type_encode.Clear();
02047         if(rTypeName(a, type_encode))
02048             encode.Append(type_encode);
02049         else{
02050             lex->Restore(pos);  
02051             if(!rLogicalOrExpr(a, TRUE))
02052                 return FALSE;
02053 
02054             encode.ValueTempParam();
02055         }
02056 
02057         args = Ptree::Snoc(args, a);
02058         switch(lex->GetToken(tk2)){
02059         case '>' :
02060             temp_args = Ptree::List(new Leaf(tk1), args, new Leaf(tk2));
02061             return TRUE;
02062         case ',' :
02063             args = Ptree::Snoc(args, new Leaf(tk2));
02064             break;
02065         case ShiftOp :
02066             if(*tk2.ptr == '>'){
02067                 lex->GetOnlyClosingBracket(tk2);
02068                 temp_args = Ptree::List(new Leaf(tk1), args,
02069                                         new Leaf(tk2.ptr, 1));
02070                 return TRUE;
02071             }
02072 
02073         default :
02074             return FALSE;
02075         }
02076     }
02077 }
02078 
02079 /*
02080   arg.decl.list.or.init
02081     : arg.decl.list
02082     | function.arguments
02083 
02084   This rule accepts function.arguments to parse declarations like:
02085         Point p(1, 3);
02086   "(1, 3)" is arg.decl.list.or.init.
02087 
02088   If maybe_init is true, we first examine whether tokens construct
02089   function.arguments.  This ordering is significant if tokens are
02090         Point p(s, t);
02091   s and t can be type names or variable names.
02092 */
02093 bool Parser::rArgDeclListOrInit(Ptree*& arglist, bool& is_args,
02094                                 Encoding& encode, bool maybe_init)
02095 {
02096     char* pos = lex->Save();
02097     if(maybe_init) {
02098         if(rFunctionArguments(arglist))
02099             if(lex->LookAhead(0) == ')') {
02100                 is_args = FALSE;
02101                 encode.Clear();
02102                 return TRUE;
02103             }
02104 
02105         lex->Restore(pos);
02106         return(is_args = rArgDeclList(arglist, encode));
02107     }
02108     else
02109         if(is_args = rArgDeclList(arglist, encode))
02110             return TRUE;
02111         else{
02112             lex->Restore(pos);
02113             encode.Clear();
02114             return rFunctionArguments(arglist);
02115         }
02116 }
02117 
02118 /*
02119   arg.decl.list
02120     : empty
02121     | arg.declaration ( ',' arg.declaration )* {{ ',' } Ellipses}
02122 */
02123 bool Parser::rArgDeclList(Ptree*& arglist, Encoding& encode)
02124 {
02125     Ptree* list;
02126     Ptree* d;
02127     int t;
02128     Token tk;
02129     Encoding arg_encode;
02130 
02131     encode.StartFuncArgs();
02132     list = nil;
02133     for(;;){
02134         arg_encode.Clear();
02135         t = lex->LookAhead(0);
02136         if(t == ')'){
02137             if(list == nil)
02138                 encode.Void();
02139 
02140             arglist = list;
02141             break;
02142         }
02143         else if(t == Ellipsis){
02144             lex->GetToken(tk);
02145             encode.EllipsisArg();
02146             arglist = Ptree::Snoc(list, new Leaf(tk));
02147             break;
02148         }
02149         else if(rArgDeclaration(d, arg_encode)){
02150             encode.Append(arg_encode);
02151             list = Ptree::Snoc(list, d);
02152             t = lex->LookAhead(0);
02153             if(t == ','){
02154                 lex->GetToken(tk);
02155                 list = Ptree::Snoc(list, new Leaf(tk));
02156             }
02157             else if(t != ')' && t != Ellipsis)
02158                 return FALSE;
02159         }
02160         else{
02161             arglist = nil;
02162             return FALSE;
02163         }
02164     }
02165 
02166     encode.EndFuncArgs();
02167     return TRUE;
02168 }
02169 
02170 /*
02171   arg.declaration
02172     : {userdef.keyword | REGISTER} type.specifier arg.declarator
02173       {'=' expression}
02174 */
02175 bool Parser::rArgDeclaration(Ptree*& decl, Encoding& encode)
02176 {
02177     Ptree *header, *type_name, *arg, *e;
02178     Token tk;
02179     Encoding name_encode;
02180 
02181     switch(lex->LookAhead(0)){
02182     case REGISTER :
02183         lex->GetToken(tk);
02184         header = new LeafREGISTER(tk);
02185         break;
02186     case UserKeyword :
02187         if(!rUserdefKeyword(header))
02188             return FALSE;
02189         break;
02190     default :
02191         header = nil;
02192         break;
02193     }
02194 
02195     if(!rTypeSpecifier(type_name, TRUE, encode))
02196         return FALSE;
02197 
02198     if(!rDeclarator(arg, kArgDeclarator, FALSE, encode, name_encode, TRUE))
02199         return FALSE;
02200 
02201     if(header == nil)
02202         decl = Ptree::List(type_name, arg);
02203     else
02204         decl = Ptree::List(header, type_name, arg);
02205 
02206     int t = lex->LookAhead(0);
02207     if(t == '='){
02208         lex->GetToken(tk);
02209         if(!rInitializeExpr(e))
02210             return FALSE;
02211 
02212         decl = Ptree::Nconc(decl, Ptree::List(new Leaf(tk), e));
02213     }
02214 
02215     return TRUE;
02216 }
02217 
02218 /*
02219   initialize.expr
02220   : expression
02221   | '{' initialize.expr (',' initialize.expr)* {','} '}'
02222 */
02223 bool Parser::rInitializeExpr(Ptree*& exp)
02224 {
02225     Token tk;
02226     Ptree *e, *elist;
02227 
02228     if(lex->LookAhead(0) != '{')
02229         return rExpression(exp);
02230     else{
02231         lex->GetToken(tk);
02232         Ptree* ob = new Leaf(tk);
02233         elist = nil;
02234         int t = lex->LookAhead(0);
02235         while(t != '}'){
02236             if(!rInitializeExpr(e)){
02237                 if(!SyntaxError())
02238                     return FALSE;       // too many errors
02239 
02240                 SkipTo('}');
02241                 lex->GetToken(tk);
02242                 exp = Ptree::List(ob, nil, new Leaf(tk));
02243                 return TRUE;            // error recovery
02244             }
02245 
02246             elist = Ptree::Snoc(elist, e);
02247             t = lex->LookAhead(0);
02248             if(t == '}')
02249                 break;
02250             else if(t == ','){
02251                 lex->GetToken(tk);
02252                 elist = Ptree::Snoc(elist, new Leaf(tk));
02253                 t = lex->LookAhead(0);
02254             }
02255             else{
02256                 if(!SyntaxError())
02257                     return FALSE;       // too many errors
02258 
02259                 SkipTo('}');
02260                 lex->GetToken(tk);
02261                 exp = Ptree::List(ob, nil, new Leaf(tk));
02262                 return TRUE;            // error recovery
02263             }
02264         }
02265 
02266         lex->GetToken(tk);
02267         exp = new PtreeBrace(ob, elist, new Leaf(tk));
02268         return TRUE;
02269     }
02270 }
02271 
02272 /*
02273   function.arguments
02274   : empty
02275   | expression (',' expression)*
02276 
02277   This assumes that the next token following function.arguments is ')'.
02278 */
02279 bool Parser::rFunctionArguments(Ptree*& args)
02280 {
02281     Ptree* exp;
02282     Token tk;
02283 
02284     args = nil;
02285     if(lex->LookAhead(0) == ')')
02286         return TRUE;
02287 
02288     for(;;){
02289         if(!rExpression(exp))
02290             return FALSE;
02291 
02292         args = Ptree::Snoc(args, exp);
02293         if(lex->LookAhead(0) != ',')
02294             return TRUE;
02295         else{
02296             lex->GetToken(tk);
02297             args = Ptree::Snoc(args, new Leaf(tk));
02298         }
02299     }
02300 }
02301 
02302 /*
02303   enum.spec
02304   : ENUM Identifier
02305   | ENUM {Identifier} '{' {enum.body} '}'
02306 */
02307 bool Parser::rEnumSpec(Ptree*& spec, Encoding& encode)
02308 {
02309     Token tk, tk2;
02310     Ptree* body;
02311 
02312     if(lex->GetToken(tk) != ENUM)
02313         return FALSE;
02314 
02315     spec = new PtreeEnumSpec(new Leaf(tk));
02316     int t = lex->GetToken(tk);
02317     if(t == Identifier){
02318         Ptree* name = new Leaf(tk);
02319         encode.SimpleName(name);
02320         ((PtreeEnumSpec*)spec)->encoded_name = encode.Get();
02321         spec = Ptree::Snoc(spec, name);
02322         if(lex->LookAhead(0) == '{')
02323             t = lex->GetToken(tk);
02324         else
02325             return TRUE;
02326     }
02327     else{
02328         encode.NoName();
02329         ((PtreeEnumSpec*)spec)->encoded_name = encode.Get();
02330         spec = Ptree::Snoc(spec, nil);
02331     }
02332 
02333     if(t != '{')
02334         return FALSE;
02335 
02336     if(lex->LookAhead(0) == '}')
02337         body = nil;
02338     else
02339         if(!rEnumBody(body))
02340             return FALSE;
02341 
02342     if(lex->GetToken(tk2) != '}')
02343         return FALSE;
02344 
02345     spec = Ptree::Snoc(spec, new PtreeBrace(new Leaf(tk), body,
02346                                             new Leaf(tk2)));
02347     return TRUE;
02348 }
02349 
02350 /*
02351   enum.body
02352   : Identifier {'=' expression} (',' Identifier {'=' expression})* {','}
02353 */
02354 bool Parser::rEnumBody(Ptree*& body)
02355 {
02356     Token tk, tk2;
02357     Ptree *name, *exp;
02358 
02359     body = nil;
02360     for(;;){
02361         if(lex->LookAhead(0) == '}')
02362             return TRUE;
02363 
02364         if(lex->GetToken(tk) != Identifier)
02365             return FALSE;
02366 
02367         if(lex->LookAhead(0, tk2) != '=')
02368             name = new Leaf(tk);
02369         else{
02370             lex->GetToken(tk2);
02371             if(!rExpression(exp)){
02372                 if(!SyntaxError())
02373                     return FALSE;       // too many errors
02374 
02375                 SkipTo('}');
02376                 body = nil;             // empty
02377                 return TRUE;            // error recovery
02378             }
02379 
02380             name = Ptree::List(new Leaf(tk), new Leaf(tk2), exp);
02381         }
02382 
02383         if(lex->LookAhead(0) != ','){
02384             body = Ptree::Snoc(body, name);
02385             return TRUE;
02386         }
02387         else{
02388             lex->GetToken(tk);
02389             body = Ptree::Nconc(body, Ptree::List(name, new Leaf(tk)));
02390         }
02391     }
02392 }
02393 
02394 /*
02395   class.spec
02396   : {userdef.keyword} class.key class.body
02397   | {userdef.keyword} class.key name {class.body}
02398   | {userdef.keyword} class.key name ':' base.specifiers class.body
02399 
02400   class.key
02401   : CLASS | STRUCT | UNION
02402 */
02403 bool Parser::rClassSpec(Ptree*& spec, Encoding& encode)
02404 {
02405     Ptree *head, *bases, *body, *name;
02406     Token tk;
02407 
02408     head = nil;
02409     if(lex->LookAhead(0) == UserKeyword)
02410         if(!rUserdefKeyword(head))
02411             return FALSE;
02412 
02413     int t = lex->GetToken(tk);
02414     if(t != CLASS && t != STRUCT && t != UNION)
02415         return FALSE;
02416 
02417     Ptree* comments = lex->GetComments();
02418     spec = new PtreeClassSpec(new LeafReserved(tk), nil, comments);
02419     if(head != nil)
02420         spec = new PtreeClassSpec(head, spec, comments);
02421 
02422     if(lex->LookAhead(0) == '{'){
02423         encode.NoName();
02424         spec = Ptree::Snoc(spec, Ptree::List(nil, nil));
02425     }
02426     else{
02427         if(!rName(name, encode))
02428             return FALSE;
02429 
02430         spec = Ptree::Snoc(spec, name);
02431         t = lex->LookAhead(0);
02432         if(t == ':'){
02433             if(!rBaseSpecifiers(bases))
02434                 return FALSE;
02435 
02436             spec = Ptree::Snoc(spec, bases);
02437         }
02438         else if(t == '{')
02439             spec = Ptree::Snoc(spec, nil);
02440         else{
02441             ((PtreeClassSpec*)spec)->encoded_name = encode.Get();
02442             return TRUE;        // class.key Identifier
02443         }
02444     }
02445 
02446     ((PtreeClassSpec*)spec)->encoded_name = encode.Get();
02447     if(!rClassBody(body))
02448         return FALSE;
02449 
02450     spec = Ptree::Snoc(spec, body);
02451     return TRUE;
02452 }
02453 
02454 /*
02455   base.specifiers
02456   : ':' base.specifier (',' base.specifier)*
02457 
02458   base.specifier
02459   : {{VIRTUAL} (PUBLIC | PROTECTED | PRIVATE) {VIRTUAL}} name
02460 */
02461 bool Parser::rBaseSpecifiers(Ptree*& bases)
02462 {
02463     Token tk;
02464     int t;
02465     Ptree* name;
02466     Encoding encode;
02467 
02468     if(lex->GetToken(tk) != ':')
02469         return FALSE;
02470 
02471     bases = Ptree::List(new Leaf(tk));
02472     for(;;){
02473         Ptree* super = nil;
02474         t = lex->LookAhead(0);
02475         if(t == VIRTUAL){
02476             lex->GetToken(tk);
02477             super = Ptree::Snoc(super, new LeafVIRTUAL(tk));
02478             t = lex->LookAhead(0);
02479         }
02480 
02481         if(t == PUBLIC | t == PROTECTED | t == PRIVATE){
02482             Ptree* lf;
02483             switch(lex->GetToken(tk)){
02484             case PUBLIC :
02485                 lf = new LeafPUBLIC(tk);
02486                 break;
02487             case PROTECTED :
02488                 lf = new LeafPROTECTED(tk);
02489                 break;
02490             case PRIVATE :
02491                 lf = new LeafPRIVATE(tk);
02492                 break;
02493             default :
02494                 MopErrorMessage("rBaseSpecifiers()", "fatal");
02495                 lf = nil;
02496                 break;
02497             }
02498 
02499             super = Ptree::Snoc(super, lf);
02500             t = lex->LookAhead(0);
02501         }
02502 
02503         if(t == VIRTUAL){
02504             lex->GetToken(tk);
02505             super = Ptree::Snoc(super, new LeafVIRTUAL(tk));
02506         }
02507 
02508         encode.Clear();
02509         if(!rName(name, encode))
02510             return FALSE;
02511 
02512         if(!name->IsLeaf())
02513             name = new PtreeName(name, encode);
02514 
02515         super = Ptree::Snoc(super, name);
02516         bases = Ptree::Snoc(bases, super);
02517         if(lex->LookAhead(0) != ',')
02518             return TRUE;
02519         else{
02520             lex->GetToken(tk);
02521             bases = Ptree::Snoc(bases, new Leaf(tk));
02522         }
02523     }
02524 }
02525 
02526 /*
02527   class.body : '{' (class.members)* '}'
02528 */
02529 bool Parser::rClassBody(Ptree*& body)
02530 {
02531     Token tk;
02532     Ptree *mems, *m;
02533 
02534     if(lex->GetToken(tk) != '{')
02535         return FALSE;
02536 
02537     Ptree* ob = new Leaf(tk);
02538     mems = nil;
02539     while(lex->LookAhead(0) != '}'){
02540         if(!rClassMember(m)){
02541             if(!SyntaxError())
02542                 return FALSE;   // too many errors
02543 
02544             SkipTo('}');
02545             lex->GetToken(tk);
02546             body = Ptree::List(ob, nil, new Leaf(tk));
02547             return TRUE;        // error recovery
02548         }
02549 
02550         lex->GetComments();
02551         mems = Ptree::Snoc(mems, m);
02552     }
02553 
02554     lex->GetToken(tk);
02555     body = new PtreeClassBody(ob, mems, new Leaf(tk));
02556     return TRUE;
02557 }
02558 
02559 /*
02560   class.member
02561   : (PUBLIC | PROTECTED | PRIVATE) ':'
02562   | user.access.spec
02563   | ';'
02564   | type.def
02565   | template.decl
02566   | using.declaration
02567   | metaclass.decl
02568   | declaration
02569   | access.decl
02570 
02571   Note: if you modify this function, see ClassWalker::TranslateClassSpec()
02572   as well.
02573 */
02574 bool Parser::rClassMember(Ptree*& mem)
02575 {
02576     Token tk1, tk2;
02577 
02578     int t = lex->LookAhead(0);
02579     if(t == PUBLIC || t == PROTECTED || t == PRIVATE){
02580         Ptree* lf;
02581         switch(lex->GetToken(tk1)){
02582         case PUBLIC :
02583             lf = new LeafPUBLIC(tk1);
02584             break;
02585         case PROTECTED :
02586             lf = new LeafPROTECTED(tk1);
02587             break;
02588         case PRIVATE :
02589             lf = new LeafPRIVATE(tk1);
02590             break;
02591         default :
02592             MopErrorMessage("rClassMember()", "fatal");
02593             lf = nil;
02594             break;
02595         }
02596 
02597         if(lex->GetToken(tk2) != ':')
02598             return FALSE;
02599 
02600         mem = new PtreeAccessSpec(lf, Ptree::List(new Leaf(tk2)));
02601         return TRUE;
02602     }
02603     else if(t == UserKeyword4)
02604         return rUserAccessSpec(mem);
02605     else if(t == ';')
02606         return rNullDeclaration(mem);
02607     else if(t == TYPEDEF)
02608         return rTypedef(mem);
02609     else if(t == TEMPLATE)
02610         return rTemplateDecl(mem);
02611     else if(t == USING)
02612         return rUsing(mem);
02613     else if(t == METACLASS)
02614         return rMetaclassDecl(mem);
02615     else{
02616         char* pos = lex->Save();
02617         Ptree* comments = lex->GetComments2();
02618         if(rDeclaration(mem)) {
02619             Walker::SetDeclaratorComments(mem, comments);
02620             return TRUE;
02621         }
02622 
02623         lex->Restore(pos);
02624         return rAccessDecl(mem);
02625     }
02626 }
02627 
02628 /*
02629   access.decl
02630   : name ';'            e.g. <qualified class>::<member name>;
02631 */
02632 bool Parser::rAccessDecl(Ptree*& mem)
02633 {
02634     Ptree* name;
02635     Encoding encode;
02636     Token tk;
02637 
02638     if(!rName(name, encode))
02639         return FALSE;
02640 
02641     if(lex->GetToken(tk) != ';')
02642         return FALSE;
02643 
02644     mem = new PtreeAccessDecl(new PtreeName(name, encode),
02645                                Ptree::List(new Leaf(tk)));
02646     return TRUE;
02647 }
02648 
02649 /*
02650   user.access.spec
02651   : UserKeyword4 ':'
02652   | UserKeyword4 '(' function.arguments ')' ':'
02653 */
02654 bool Parser::rUserAccessSpec(Ptree*& mem)
02655 {
02656     Token tk1, tk2, tk3, tk4;
02657     Ptree* args;
02658 
02659     if(lex->GetToken(tk1) != UserKeyword4)
02660         return FALSE;
02661 
02662     int t = lex->GetToken(tk2);
02663     if(t == ':'){
02664         mem = new PtreeUserAccessSpec(new Leaf(tk1),
02665                                       Ptree::List(new Leaf(tk2)));
02666         return TRUE;
02667     }
02668     else if(t == '('){
02669         if(!rFunctionArguments(args))
02670             return FALSE;
02671 
02672         if(lex->GetToken(tk3) != ')')
02673             return FALSE;
02674 
02675         if(lex->GetToken(tk4) != ':')
02676             return FALSE;
02677 
02678         mem = new PtreeUserAccessSpec(new Leaf(tk1),
02679                                       Ptree::List(new Leaf(tk2), args,
02680                                                   new Leaf(tk3),
02681                                                   new Leaf(tk4)));
02682         return TRUE;
02683     }
02684     else
02685         return FALSE;
02686 }
02687 
02688 /*
02689   comma.expression
02690   : expression
02691   | comma.expression ',' expression     (left-to-right)
02692 */
02693 bool Parser::rCommaExpression(Ptree*& exp)
02694 {
02695     Token tk;
02696     Ptree *right;
02697 
02698     if(!rExpression(exp))
02699         return FALSE;
02700 
02701     while(lex->LookAhead(0) == ','){
02702         lex->GetToken(tk);
02703         if(!rExpression(right))
02704             return FALSE;
02705 
02706         exp = new PtreeCommaExpr(exp, Ptree::List(new Leaf(tk), right));
02707     }
02708 
02709     return TRUE;
02710 }
02711 
02712 /*
02713   expression
02714   : conditional.expr {(AssignOp | '=') expression}      right-to-left
02715 */
02716 bool Parser::rExpression(Ptree*& exp)
02717 {
02718     Token tk;
02719     Ptree *left, *right;
02720 
02721     if(!rConditionalExpr(left))
02722         return FALSE;
02723 
02724     int t = lex->LookAhead(0);
02725     if(t != '=' && t != AssignOp)
02726         exp = left;
02727     else{
02728         lex->GetToken(tk);
02729         if(!rExpression(right))
02730             return FALSE;
02731 
02732         exp = new PtreeAssignExpr(left, Ptree::List(new Leaf(tk), right));
02733     }
02734 
02735     return TRUE;
02736 }
02737 
02738 /*
02739   conditional.expr
02740   : logical.or.expr {'?' comma.expression ':' conditional.expr}  right-to-left
02741 */
02742 bool Parser::rConditionalExpr(Ptree*& exp)
02743 {
02744     Token tk1, tk2;
02745     Ptree *then, *otherwise;
02746 
02747     if(!rLogicalOrExpr(exp, FALSE))
02748         return FALSE;
02749 
02750     if(lex->LookAhead(0) == '?'){
02751         lex->GetToken(tk1);
02752         if(!rCommaExpression(then))
02753             return FALSE;
02754 
02755         if(lex->GetToken(tk2) != ':')
02756             return FALSE;
02757 
02758         if(!rConditionalExpr(otherwise))
02759             return FALSE;
02760 
02761         exp = new PtreeCondExpr(exp, Ptree::List(new Leaf(tk1), then,
02762                                                  new Leaf(tk2), otherwise));
02763     }
02764 
02765     return TRUE;
02766 }
02767 
02768 /*
02769   logical.or.expr
02770   : logical.and.expr
02771   | logical.or.expr LogOrOp logical.and.expr            left-to-right
02772 */
02773 bool Parser::rLogicalOrExpr(Ptree*& exp, bool temp_args)
02774 {
02775     Token tk;
02776     Ptree *right;
02777 
02778     if(!rLogicalAndExpr(exp, temp_args))
02779         return FALSE;
02780 
02781     while(lex->LookAhead(0) == LogOrOp){
02782         lex->GetToken(tk);
02783         if(!rLogicalAndExpr(right, temp_args))
02784             return FALSE;
02785 
02786         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02787     }
02788 
02789     return TRUE;
02790 }
02791 
02792 /*
02793   logical.and.expr
02794   : inclusive.or.expr
02795   | logical.and.expr LogAndOp inclusive.or.expr
02796 */
02797 bool Parser::rLogicalAndExpr(Ptree*& exp, bool temp_args)
02798 {
02799     Token tk;
02800     Ptree *right;
02801 
02802     if(!rInclusiveOrExpr(exp, temp_args))
02803         return FALSE;
02804 
02805     while(lex->LookAhead(0) == LogAndOp){
02806         lex->GetToken(tk);
02807         if(!rInclusiveOrExpr(right, temp_args))
02808             return FALSE;
02809 
02810         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02811     }
02812 
02813     return TRUE;
02814 }
02815 
02816 /*
02817   inclusive.or.expr
02818   : exclusive.or.expr
02819   | inclusive.or.expr '|' exclusive.or.expr
02820 */
02821 bool Parser::rInclusiveOrExpr(Ptree*& exp, bool temp_args)
02822 {
02823     Token tk;
02824     Ptree *right;
02825 
02826     if(!rExclusiveOrExpr(exp, temp_args))
02827         return FALSE;
02828 
02829     while(lex->LookAhead(0) == '|'){
02830         lex->GetToken(tk);
02831         if(!rExclusiveOrExpr(right, temp_args))
02832             return FALSE;
02833 
02834         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02835     }
02836 
02837     return TRUE;
02838 }
02839 
02840 /*
02841   exclusive.or.expr
02842   : and.expr
02843   | exclusive.or.expr '^' and.expr
02844 */
02845 bool Parser::rExclusiveOrExpr(Ptree*& exp, bool temp_args)
02846 {
02847     Token tk;
02848     Ptree *right;
02849 
02850     if(!rAndExpr(exp, temp_args))
02851         return FALSE;
02852 
02853     while(lex->LookAhead(0) == '^'){
02854         lex->GetToken(tk);
02855         if(!rAndExpr(right, temp_args))
02856             return FALSE;
02857 
02858         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02859     }
02860 
02861     return TRUE;
02862 }
02863 
02864 /*
02865   and.expr
02866   : equality.expr
02867   | and.expr '&' equality.expr
02868 */
02869 bool Parser::rAndExpr(Ptree*& exp, bool temp_args)
02870 {
02871     Token tk;
02872     Ptree *right;
02873 
02874     if(!rEqualityExpr(exp, temp_args))
02875         return FALSE;
02876 
02877     while(lex->LookAhead(0) == '&'){
02878         lex->GetToken(tk);
02879         if(!rEqualityExpr(right, temp_args))
02880             return FALSE;
02881 
02882         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02883     }
02884 
02885     return TRUE;
02886 }
02887 
02888 /*
02889   equality.expr
02890   : relational.expr
02891   | equality.expr EqualOp relational.expr
02892 */
02893 bool Parser::rEqualityExpr(Ptree*& exp, bool temp_args)
02894 {
02895     Token tk;
02896     Ptree *right;
02897 
02898     if(!rRelationalExpr(exp, temp_args))
02899         return FALSE;
02900 
02901     while(lex->LookAhead(0) == EqualOp){
02902         lex->GetToken(tk);
02903         if(!rRelationalExpr(right, temp_args))
02904             return FALSE;
02905 
02906         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02907     }
02908 
02909     return TRUE;
02910 }
02911 
02912 /*
02913   relational.expr
02914   : shift.expr
02915   | relational.expr (RelOp | '<' | '>') shift.expr
02916 */
02917 bool Parser::rRelationalExpr(Ptree*& exp, bool temp_args)
02918 {
02919     int t;
02920     Token tk;
02921     Ptree *right;
02922 
02923     if(!rShiftExpr(exp))
02924         return FALSE;
02925 
02926     while(t = lex->LookAhead(0),
02927           (t == RelOp || t == '<' || (t == '>' && !temp_args))){
02928         lex->GetToken(tk);
02929         if(!rShiftExpr(right))
02930             return FALSE;
02931 
02932         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02933     }
02934 
02935     return TRUE;
02936 }
02937 
02938 /*
02939   shift.expr
02940   : additive.expr
02941   | shift.expr ShiftOp additive.expr
02942 */
02943 bool Parser::rShiftExpr(Ptree*& exp)
02944 {
02945     Token tk;
02946     Ptree *right;
02947 
02948     if(!rAdditiveExpr(exp))
02949         return FALSE;
02950 
02951     while(lex->LookAhead(0) == ShiftOp){
02952         lex->GetToken(tk);
02953         if(!rAdditiveExpr(right))
02954             return FALSE;
02955 
02956         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02957     }
02958 
02959     return TRUE;
02960 }
02961 
02962 /*
02963   additive.expr
02964   : multiply.expr
02965   | additive.expr ('+' | '-') multiply.expr
02966 */
02967 bool Parser::rAdditiveExpr(Ptree*& exp)
02968 {
02969     int t;
02970     Token tk;
02971     Ptree *right;
02972 
02973     if(!rMultiplyExpr(exp))
02974         return FALSE;
02975 
02976     while(t = lex->LookAhead(0), (t == '+' || t == '-')){
02977         lex->GetToken(tk);
02978         if(!rMultiplyExpr(right))
02979             return FALSE;
02980 
02981         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
02982     }
02983 
02984     return TRUE;
02985 }
02986 
02987 /*
02988   multiply.expr
02989   : pm.expr
02990   | multiply.expr ('*' | '/' | '%') pm.expr
02991 */
02992 bool Parser::rMultiplyExpr(Ptree*& exp)
02993 {
02994     int t;
02995     Token tk;
02996     Ptree *right;
02997 
02998     if(!rPmExpr(exp))
02999         return FALSE;
03000 
03001     while(t = lex->LookAhead(0), (t == '*' || t == '/' || t == '%')){
03002         lex->GetToken(tk);
03003         if(!rPmExpr(right))
03004             return FALSE;
03005 
03006         exp = new PtreeInfixExpr(exp, Ptree::List(new Leaf(tk), right));
03007     }
03008 
03009     return TRUE;
03010 }
03011 
03012 /*
03013   pm.expr       (pointer to member .*, ->*)
03014   : cast.expr
03015   | pm.expr PmOp cast.expr
03016 */
03017 bool Parser::rPmExpr(Ptree*& exp)
03018 {
03019     Token tk;
03020     Ptree *right;
03021 
03022     if(!rCastExpr(exp))
03023         return FALSE;
03024 
03025     while(lex->LookAhead(0) == PmOp){
03026         lex->GetToken(tk);
03027         if(!rCastExpr(right))
03028             return FALSE;
03029 
03030         exp = new PtreePmExpr(exp, Ptree::List(new Leaf(tk), right));
03031     }
03032 
03033     return TRUE;
03034 }
03035 
03036 /*
03037   cast.expr
03038   : unary.expr
03039   | '(' type.name ')' cast.expr
03040 */
03041 bool Parser::rCastExpr(Ptree*& exp)
03042 {
03043     if(lex->LookAhead(0) != '(')
03044         return rUnaryExpr(exp);
03045     else{
03046         Token tk1, tk2;
03047         Ptree* tname;
03048         char* pos = lex->Save();
03049         lex->GetToken(tk1);
03050         if(rTypeName(tname))
03051             if(lex->GetToken(tk2) == ')')
03052                 if(rCastExpr(exp)){
03053                     exp = new PtreeCastExpr(new Leaf(tk1),
03054                                             Ptree::List(tname, new Leaf(tk2),
03055                                                         exp));
03056                     return TRUE;
03057                 }
03058 
03059         lex->Restore(pos);
03060         return rUnaryExpr(exp);
03061     }
03062 }
03063 
03064 /*
03065   type.name
03066   : type.specifier cast.declarator
03067 */
03068 bool Parser::rTypeName(Ptree*& tname)
03069 {
03070     Encoding type_encode;
03071     return rTypeName(tname, type_encode);
03072 }
03073 
03074 bool Parser::rTypeName(Ptree*& tname, Encoding& type_encode)
03075 {
03076     Ptree *type_name, *arg;
03077     Encoding name_encode;
03078 
03079     if(!rTypeSpecifier(type_name, TRUE, type_encode))
03080         return FALSE;
03081 
03082     if(!rDeclarator(arg, kCastDeclarator, FALSE, type_encode, name_encode,
03083                     FALSE))
03084         return FALSE;
03085 
03086     tname = Ptree::List(type_name, arg);
03087     return TRUE;
03088 }
03089 
03090 /*
03091   unary.expr
03092   : postfix.expr
03093   | ('*' | '&' | '+' | '-' | '!' | '~' | IncOp) cast.expr
03094   | sizeof.expr
03095   | allocate.expr
03096   | throw.expression
03097 */
03098 bool Parser::rUnaryExpr(Ptree*& exp)
03099 {
03100     int t = lex->LookAhead(0);
03101     if(t == '*' || t == '&' || t == '+' || t == '-' || t == '!'
03102        || t == '~' || t == IncOp){
03103         Token tk;
03104         Ptree* right;
03105 
03106         lex->GetToken(tk);
03107         if(!rCastExpr(right))
03108             return FALSE;
03109 
03110         exp = new PtreeUnaryExpr(new Leaf(tk), Ptree::List(right));
03111         return TRUE;
03112     }
03113     else if(t == SIZEOF)
03114         return rSizeofExpr(exp);
03115     else if(t == THROW)
03116         return rThrowExpr(exp);
03117     else if(isAllocateExpr(t))
03118         return rAllocateExpr(exp);
03119     else
03120         return rPostfixExpr(exp);
03121 }
03122 
03123 /*
03124   throw.expression
03125   : THROW {expression}
03126 */
03127 bool Parser::rThrowExpr(Ptree*& exp)
03128 {
03129     Token tk;
03130     Ptree* e;
03131 
03132     if(lex->GetToken(tk) != THROW)
03133         return FALSE;
03134 
03135     int t = lex->LookAhead(0);
03136     if(t == ':' || t == ';')
03137         e = nil;
03138     else
03139         if(!rExpression(e))
03140             return FALSE;
03141 
03142     exp = new PtreeThrowExpr(new LeafReserved(tk), Ptree::List(e));
03143     return TRUE;
03144 }
03145 
03146 /*
03147   sizeof.expr
03148   : SIZEOF unary.expr
03149   | SIZEOF '(' type.name ')'
03150 */
03151 bool Parser::rSizeofExpr(Ptree*& exp)
03152 {
03153     Token tk;
03154     Ptree* unary;
03155 
03156     if(lex->GetToken(tk) != SIZEOF)
03157         return FALSE;
03158 
03159     if(lex->LookAhead(0) == '('){
03160         Ptree* tname;
03161         Token op, cp;
03162 
03163         char* pos = lex->Save();
03164         lex->GetToken(op);
03165         if(rTypeName(tname))
03166             if(lex->GetToken(cp) == ')'){
03167                 exp = new PtreeSizeofExpr(new Leaf(tk),
03168                                           Ptree::List(new Leaf(op), tname,
03169                                                       new Leaf(cp)));
03170                 return TRUE;
03171             }
03172 
03173         lex->Restore(pos);
03174     }
03175 
03176     if(!rUnaryExpr(unary))
03177         return FALSE;
03178 
03179     exp = new PtreeSizeofExpr(new Leaf(tk), Ptree::List(unary));
03180     return TRUE;
03181 }
03182 
03183 bool Parser::isAllocateExpr(int t)
03184 {
03185     if(t == UserKeyword)
03186         return TRUE;
03187     else{
03188         if(t == Scope)
03189             t = lex->LookAhead(1);
03190 
03191         if(t == NEW || t == DELETE)
03192             return TRUE;
03193         else
03194             return FALSE;
03195     }
03196 }
03197 
03198 /*
03199   allocate.expr
03200   : {Scope | userdef.keyword} NEW allocate.type
03201   | {Scope} DELETE {'[' ']'} cast.expr
03202 */
03203 bool Parser::rAllocateExpr(Ptree*& exp)
03204 {
03205     Token tk;
03206     Ptree* head = nil;
03207 
03208     bool ukey = FALSE;
03209     int t = lex->LookAhead(0);
03210     if(t == Scope){
03211         lex->GetToken(tk);
03212         head = new Leaf(tk);
03213     }
03214     else if(t == UserKeyword){
03215         if(!rUserdefKeyword(head))
03216             return FALSE;
03217 
03218         ukey = TRUE;
03219     }
03220 
03221     t = lex->GetToken(tk);
03222     if(t == DELETE){
03223         Ptree* obj;
03224         if(ukey)
03225             return FALSE;
03226 
03227         if(head == nil)
03228             exp = new PtreeDeleteExpr(new LeafReserved(tk), nil);
03229         else
03230             exp = new PtreeDeleteExpr(head,
03231                                       Ptree::List(new LeafReserved(tk)));
03232 
03233         if(lex->LookAhead(0) == '['){
03234             lex->GetToken(tk);
03235             exp = Ptree::Snoc(exp, new Leaf(tk));
03236             if(lex->GetToken(tk) != ']')
03237                 return FALSE;
03238 
03239             exp = Ptree::Snoc(exp, new Leaf(tk));
03240         }
03241 
03242         if(!rCastExpr(obj))
03243             return FALSE;
03244 
03245         exp = Ptree::Snoc(exp, obj);
03246         return TRUE;
03247     }
03248     else if(t == NEW){
03249         Ptree *atype;
03250         if(head == nil)
03251             exp = new PtreeNewExpr(new LeafReserved(tk), nil);
03252         else
03253             exp = new PtreeNewExpr(head, Ptree::List(new LeafReserved(tk)));
03254 
03255         if(!rAllocateType(atype))
03256             return FALSE;
03257 
03258         exp = Ptree::Nconc(exp, atype);
03259         return TRUE;
03260     }
03261     else
03262         return FALSE;
03263 }
03264 
03265 /*
03266   userdef.keyword
03267   : [UserKeyword | UserKeyword5] {'(' function.arguments ')'}
03268 */
03269 bool Parser::rUserdefKeyword(Ptree*& ukey)
03270 {
03271     Token tk;
03272 
03273     int t = lex->GetToken(tk);
03274     if(t != UserKeyword && t != UserKeyword5)
03275         return FALSE;
03276 
03277     if(lex->LookAhead(0) != '(')
03278         ukey = new PtreeUserdefKeyword(new Leaf(tk), nil);
03279     else{
03280         Ptree* args;
03281         Token op, cp;
03282         lex->GetToken(op);
03283         if(!rFunctionArguments(args))
03284             return FALSE;
03285 
03286         if(lex->GetToken(cp) != ')')
03287             return FALSE;
03288 
03289         ukey = new PtreeUserdefKeyword(new Leaf(tk),
03290                         Ptree::List(new Leaf(op), args, new Leaf(cp)));
03291     }
03292 
03293     return TRUE;
03294 }
03295 
03296 /*
03297   allocate.type
03298   : {'(' function.arguments ')'} type.specifier new.declarator
03299     {allocate.initializer}
03300   | {'(' function.arguments ')'} '(' type.name ')' {allocate.initializer}
03301 */
03302 bool Parser::rAllocateType(Ptree*& atype)
03303 {
03304     Token op, cp;
03305     Ptree *tname, *init, *exp;
03306 
03307     if(lex->LookAhead(0) != '(')
03308         atype = Ptree::List(nil);
03309     else{
03310         lex->GetToken(op);
03311 
03312         char* pos = lex->Save();
03313         if(rTypeName(tname))
03314             if(lex->GetToken(cp) == ')')
03315                 if(lex->LookAhead(0) != '('){
03316                     atype = Ptree::List(nil, Ptree::List(new Leaf(op), tname,
03317                                                          new Leaf(cp)));
03318                     if(!isTypeSpecifier())
03319                         return TRUE;
03320                 }
03321                 else if(rAllocateInitializer(init)){
03322                     atype = Ptree::List(nil,
03323                                         Ptree::List(new Leaf(op), tname,
03324                                                     new Leaf(cp)),
03325                                         init);
03326                     // the next token cannot be '('
03327                     if(lex->LookAhead(0) != '(')
03328                         return TRUE;
03329                 }
03330 
03331         // if we reach here, we have to process '(' function.arguments ')'.
03332         lex->Restore(pos);
03333         if(!rFunctionArguments(exp))
03334             return FALSE;
03335 
03336         if(lex->GetToken(cp) != ')')
03337             return FALSE;
03338 
03339         atype = Ptree::List(Ptree::List(new Leaf(op), exp, new Leaf(cp)));
03340     }
03341 
03342     if(lex->LookAhead(0) == '('){
03343         lex->GetToken(op);
03344         if(!rTypeName(tname))
03345             return FALSE;
03346 
03347         if(lex->GetToken(cp) != ')')
03348             return FALSE;
03349 
03350         atype = Ptree::Snoc(atype, Ptree::List(new Leaf(op), tname,
03351                                                new Leaf(cp)));
03352     }
03353     else{
03354         Ptree* decl;
03355         Encoding type_encode;
03356         if(!rTypeSpecifier(tname, FALSE, type_encode))
03357             return FALSE;
03358 
03359         if(!rNewDeclarator(decl, type_encode))
03360             return FALSE;
03361 
03362         atype = Ptree::Snoc(atype, Ptree::List(tname, decl));
03363     }
03364 
03365     if(lex->LookAhead(0) == '('){
03366         if(!rAllocateInitializer(init))
03367             return FALSE;
03368 
03369         atype = Ptree::Snoc(atype, init);
03370     }
03371 
03372     return TRUE;
03373 }
03374 
03375 /*
03376   new.declarator
03377   : empty
03378   | ptr.operator
03379   | {ptr.operator} ('[' comma.expression ']')+
03380 */
03381 bool Parser::rNewDeclarator(Ptree*& decl, Encoding& encode)
03382 {
03383     decl = nil;
03384     if(lex->LookAhead(0) != '[')
03385         if(!optPtrOperator(decl, encode))
03386             return FALSE;
03387 
03388     while(lex->LookAhead(0) == '['){
03389         Token ob, cb;
03390         Ptree* exp;
03391         lex->GetToken(ob);
03392         if(!rCommaExpression(exp))
03393             return FALSE;
03394 
03395         if(lex->GetToken(cb) != ']')
03396             return FALSE;
03397 
03398         encode.Array();
03399         decl = Ptree::Nconc(decl, Ptree::List(new Leaf(ob), exp,
03400                                               new Leaf(cb)));
03401     }
03402 
03403     if(decl == nil)
03404         decl = new PtreeDeclarator(encode);
03405     else
03406         decl = new PtreeDeclarator(decl, encode);
03407 
03408     return TRUE;
03409 }
03410 
03411 /*
03412   allocate.initializer
03413   : '(' {initialize.expr (',' initialize.expr)* } ')'
03414 */
03415 bool Parser::rAllocateInitializer(Ptree*& init)
03416 {
03417     Token op, cp;
03418 
03419     if(lex->GetToken(op) != '(')
03420         return FALSE;
03421 
03422     if(lex->LookAhead(0) == ')'){
03423         lex->GetToken(cp);
03424         init = Ptree::List(new Leaf(op), nil, new Leaf(cp));
03425         return TRUE;
03426     }
03427 
03428     init = nil;
03429     for(;;){
03430         Ptree* exp;
03431         if(!rInitializeExpr(exp))
03432             return FALSE;
03433 
03434         init = Ptree::Snoc(init, exp);
03435         if(lex->LookAhead(0) != ',')
03436             break;
03437         else{
03438             Token tk;
03439             lex->GetToken(tk);
03440             init = Ptree::Snoc(init, new Leaf(tk));
03441         }
03442     }
03443 
03444     lex->GetToken(cp);
03445     init = Ptree::List(new Leaf(op), init, new Leaf(cp));
03446     return TRUE;
03447 }
03448 
03449 /*
03450   postfix.exp
03451   : primary.exp
03452   | postfix.expr '[' comma.expression ']'
03453   | postfix.expr '(' function.arguments ')'
03454   | postfix.expr '.' var.name
03455   | postfix.expr ArrowOp var.name
03456   | postfix.expr IncOp
03457   | openc++.postfix.expr
03458 
03459   openc++.postfix.expr
03460   : postfix.expr '.' userdef.statement
03461   | postfix.expr ArrowOp userdef.statement
03462 
03463   Note: function-style casts are accepted as function calls.
03464 */
03465 bool Parser::rPostfixExpr(Ptree*& exp)
03466 {
03467     Ptree* e;
03468     Token cp, op;
03469     int t, t2;
03470 
03471     if(!rPrimaryExpr(exp))
03472         return FALSE;
03473 
03474     for(;;){
03475         switch(lex->LookAhead(0)){
03476         case '[' :
03477             lex->GetToken(op);
03478             if(!rCommaExpression(e))
03479                 return FALSE;
03480 
03481             if(lex->GetToken(cp) != ']')
03482                 return FALSE;
03483 
03484             exp = new PtreeArrayExpr(exp, Ptree::List(new Leaf(op),
03485                                                       e, new Leaf(cp)));
03486             break;
03487         case '(' :
03488             lex->GetToken(op);
03489             if(!rFunctionArguments(e))
03490                 return FALSE;
03491 
03492             if(lex->GetToken(cp) != ')')
03493                 return FALSE;
03494 
03495             exp = new PtreeFuncallExpr(exp, Ptree::List(new Leaf(op),
03496                                                         e, new Leaf(cp)));
03497             break;
03498         case IncOp :
03499             lex->GetToken(op);
03500             exp = new PtreePostfixExpr(exp, Ptree::List(new Leaf(op)));
03501             break;
03502         case '.' :
03503         case ArrowOp :
03504             t2 = lex->GetToken(op);
03505             t = lex->LookAhead(0);
03506             if(t == UserKeyword || t == UserKeyword2 || t == UserKeyword3){
03507                 if(!rUserdefStatement(e))
03508                     return FALSE;
03509 
03510                 exp = new PtreeUserStatementExpr(exp,
03511                                                  Ptree::Cons(new Leaf(op), e));
03512                 break;
03513             }
03514             else{
03515                 if(!rVarName(e))
03516                     return FALSE;
03517 
03518                 if(t2 == '.')
03519                     exp = new PtreeDotMemberExpr(exp,
03520                                                  Ptree::List(new Leaf(op), e));
03521                 else
03522                     exp = new PtreeArrowMemberExpr(exp,
03523                                                 Ptree::List(new Leaf(op), e));
03524                 break;
03525             }
03526         default :
03527             return TRUE;
03528         }
03529     }
03530 }
03531 
03532 /*
03533   primary.exp
03534   : Constant
03535   | CharConst
03536   | StringL
03537   | THIS
03538   | var.name
03539   | '(' comma.expression ')'
03540   | integral.or.class.spec '(' function.arguments ')'
03541   | openc++.primary.exp
03542 
03543   openc++.primary.exp
03544   : var.name '::' userdef.statement
03545 */
03546 bool Parser::rPrimaryExpr(Ptree*& exp)
03547 {
03548     Token tk, tk2;
03549     Ptree* exp2;
03550     Encoding cast_type_encode;
03551 
03552     switch(lex->LookAhead(0)){
03553     case Constant : case CharConst : case StringL :
03554         lex->GetToken(tk);
03555         exp = new Leaf(tk);
03556         return TRUE;
03557     case THIS :
03558         lex->GetToken(tk);
03559         exp = new LeafThis(tk);
03560         return TRUE;
03561     case '(' :
03562         lex->GetToken(tk);
03563         if(!rCommaExpression(exp2))
03564             return FALSE;
03565 
03566         if(lex->GetToken(tk2) != ')')
03567             return FALSE;
03568 
03569         exp = new PtreeParenExpr(new Leaf(tk),
03570                                  Ptree::List(exp2, new Leaf(tk2)));
03571         return TRUE;
03572     default :
03573         if(!optIntegralTypeOrClassSpec(exp, cast_type_encode))
03574             return FALSE;
03575 
03576         if(exp != nil){         // if integral.or.class.spec
03577             if(lex->GetToken(tk) != '(')
03578                 return FALSE;
03579 
03580             if(!rFunctionArguments(exp2))
03581                 return FALSE;
03582 
03583             if(lex->GetToken(tk2) != ')')
03584                 return FALSE;
03585 
03586             exp = new PtreeFstyleCastExpr(cast_type_encode, exp,
03587                                           Ptree::List(new Leaf(tk), exp2,
03588                                                       new Leaf(tk2)));
03589             return TRUE;
03590         }
03591         else{
03592             if(!rVarName(exp))
03593                 return FALSE;
03594 
03595             if(lex->LookAhead(0) == Scope){
03596                 lex->GetToken(tk);
03597                 if(!rUserdefStatement(exp2))
03598                     return FALSE;
03599 
03600                 exp = new PtreeStaticUserStatementExpr(exp,
03601                                         Ptree::Cons(new Leaf(tk), exp2));
03602             }
03603 
03604             return TRUE;
03605         }
03606     }
03607 }
03608 
03609 /*
03610   userdef.statement
03611   : UserKeyword '(' function.arguments ')' compound.statement
03612   | UserKeyword2 '(' arg.decl.list ')' compound.statement
03613   | UserKeyword3 '(' expr.statement {comma.expression} ';'
03614                         {comma.expression} ')' compound.statement
03615 */
03616 bool Parser::rUserdefStatement(Ptree*& st)
03617 {
03618     Token tk, tk2, tk3, tk4;
03619     Ptree *keyword, *exp, *body, *exp2, *exp3;
03620     Encoding dummy_encode;
03621 
03622     int t = lex->GetToken(tk);
03623     if(lex->GetToken(tk2) != '(')
03624         return FALSE;
03625 
03626     switch(t){
03627     case UserKeyword :
03628         keyword = new LeafReserved(tk);
03629         if(!rFunctionArguments(exp))
03630             return FALSE;
03631         goto rest;
03632     case UserKeyword2 :
03633         keyword = new LeafUserKeyword2(tk);
03634         if(!rArgDeclList(exp, dummy_encode))
03635             return FALSE;
03636     rest:
03637         if(lex->GetToken(tk3) != ')')
03638             return FALSE;
03639 
03640         if(!rCompoundStatement(body))
03641             return FALSE;
03642 
03643         st = Ptree::List(keyword, new Leaf(tk2), exp, new Leaf(tk3),
03644                          body);
03645         return TRUE;
03646     case UserKeyword3 :
03647         if(!rExprStatement(exp))
03648             return FALSE;
03649 
03650         if(lex->LookAhead(0) == ';')
03651             exp2 = nil;
03652         else
03653             if(!rCommaExpression(exp2))
03654                 return FALSE;
03655 
03656         if(lex->GetToken(tk3) != ';')
03657             return FALSE;
03658 
03659         if(lex->LookAhead(0) == ')')
03660             exp3 = nil;
03661         else
03662             if(!rCommaExpression(exp3))
03663                 return FALSE;
03664 
03665         if(lex->GetToken(tk4) != ')')
03666             return FALSE;
03667 
03668         if(!rCompoundStatement(body))
03669             return FALSE;
03670 
03671         st = Ptree::List(new Leaf(tk), new Leaf(tk2), exp, exp2,
03672                          new Leaf(tk3), exp3, new Leaf(tk4), body);
03673         return TRUE;
03674     default :
03675         return FALSE;
03676     }
03677 }
03678 
03679 /*
03680   var.name : {'::'} name2 ('::' name2)*
03681 
03682   name2
03683   : Identifier {template.args}
03684   | '~' Identifier
03685   | OPERATOR operator.name
03686 
03687   if var.name ends with a template type, the next token must be '('
03688 */
03689 bool Parser::rVarName(Ptree*& name)
03690 {
03691     Encoding encode;
03692 
03693     if(rVarNameCore(name, encode)){
03694         if(!name->IsLeaf())
03695             name = new PtreeName(name, encode);
03696 
03697         return TRUE;
03698     }
03699     else
03700         return FALSE;
03701 }
03702 
03703 bool Parser::rVarNameCore(Ptree*& name, Encoding& encode)
03704 {
03705     Token tk;
03706     int length = 0;
03707 
03708     if(lex->LookAhead(0) == Scope){
03709         lex->GetToken(tk);
03710         name = Ptree::List(new Leaf(tk));
03711         encode.GlobalScope();
03712         ++length;
03713     }
03714     else
03715         name = nil;
03716 
03717     for(;;){
03718         int t = lex->GetToken(tk);
03719         if(t == Identifier){
03720             Ptree* n = new LeafName(tk);
03721             if(isTemplateArgs()){
03722                 Ptree* args;
03723                 Encoding args_encode;
03724                 if(!rTemplateArgs(args, args_encode))
03725                     return FALSE;
03726 
03727                 encode.Template(n, args_encode);
03728                 ++length;
03729                 n = Ptree::List(n, args);
03730             }
03731             else{
03732                 encode.SimpleName(n);
03733                 ++length;
03734             }
03735 
03736             if(moreVarName()){
03737                 lex->GetToken(tk);
03738                 name = Ptree::Nconc(name, Ptree::List(n, new Leaf(tk)));
03739             }
03740             else{
03741                 if(name == nil)
03742                     name = n;
03743                 else
03744                     name = Ptree::Snoc(name, n);
03745 
03746                 if(length > 1)
03747                     encode.Qualified(length);
03748 
03749                 return TRUE;
03750             }
03751         }
03752         else if(t == '~'){
03753             Token tk2;
03754             if(lex->LookAhead(0) != Identifier)
03755                 return FALSE;
03756 
03757             lex->GetToken(tk2);
03758             Ptree* class_name = new Leaf(tk2);
03759             Ptree* dt = Ptree::List(new Leaf(tk), class_name);
03760             if(name == nil)
03761                 name = dt;
03762             else
03763                 name = Ptree::Snoc(name, dt);
03764 
03765             encode.Destructor(class_name);
03766             if(length > 0)
03767                 encode.Qualified(length + 1);
03768 
03769             return TRUE;
03770         }
03771         else if(t == OPERATOR){
03772             Ptree* op;
03773             if(!rOperatorName(op, encode))
03774                 return FALSE;
03775 
03776             Ptree* opf = Ptree::List(new LeafReserved(tk), op);
03777             if(name == nil)
03778                 name = opf;
03779             else
03780                 name = Ptree::Snoc(name, opf);
03781 
03782             if(length > 0)
03783                 encode.Qualified(length + 1);
03784 
03785             return TRUE;
03786         }
03787         else
03788             return FALSE;
03789     }
03790 }
03791 
03792 bool Parser::moreVarName()
03793 {
03794     if(lex->LookAhead(0) == Scope){
03795         int t = lex->LookAhead(1);
03796         if(t == Identifier || t == '~' || t == OPERATOR)
03797             return TRUE;
03798     }
03799 
03800     return FALSE;
03801 }
03802 
03803 /*
03804   template.args : '<' any* '>'
03805 
03806   template.args must be followed by '(' or '::'
03807 */
03808 bool Parser::isTemplateArgs()
03809 {
03810     int i = 0;
03811     int t = lex->LookAhead(i++);
03812     if(t == '<'){
03813         int n = 1;
03814         while(n > 0){
03815             int u = lex->LookAhead(i++);
03816             if(u == '<')
03817                 ++n;
03818             else if(u == '>')
03819                 --n;
03820             else if(u == '('){
03821                 int m = 1;
03822                 while(m > 0){
03823                     int v = lex->LookAhead(i++);
03824                     if(v == '(')
03825                         ++m;
03826                     else if(v == ')')
03827                         --m;
03828                     else if(v == '\0' || v == ';' || v == '}')
03829                         return FALSE;
03830                 }
03831             }
03832             else if(u == '\0' || u == ';' || u == '}')
03833                 return FALSE;
03834         }
03835 
03836         t = lex->LookAhead(i);
03837         return bool(t == Scope || t == '(');
03838     }
03839 
03840     return FALSE;
03841 }
03842 
03843 /*
03844   function.body  : compound.statement
03845 */
03846 bool Parser::rFunctionBody(Ptree*& body)
03847 {
03848     return rCompoundStatement(body);
03849 }
03850 
03851 /*
03852   compound.statement
03853   : '{' (statement)* '}'
03854 */
03855 bool Parser::rCompoundStatement(Ptree*& body)
03856 {
03857     Token ob, cb;
03858 
03859     if(lex->GetToken(ob) != '{')
03860         return FALSE;
03861 
03862     Ptree* sts = nil;
03863     while(lex->LookAhead(0) != '}'){
03864         Ptree* st;
03865         if(!rStatement(st)){
03866             if(!SyntaxError())
03867                 return FALSE;   // too many errors
03868 
03869             SkipTo('}');
03870             lex->GetToken(cb);
03871             body = Ptree::List(new Leaf(ob), nil, new Leaf(cb));
03872             return TRUE;        // error recovery
03873         }
03874 
03875         lex->GetComments();
03876         sts = Ptree::Snoc(sts, st);
03877     }
03878 
03879     if(lex->GetToken(cb) != '}')
03880         return FALSE;
03881 
03882     body = new PtreeBlock(new Leaf(ob), sts, new Leaf(cb));
03883     return TRUE;
03884 }
03885 
03886 /*
03887   statement
03888   : compound.statement
03889   | typedef
03890   | if.statement
03891   | switch.statement
03892   | while.statement
03893   | do.statement
03894   | for.statement
03895   | try.statement
03896   | BREAK ';'
03897   | CONTINUE ';'
03898   | RETURN { comma.expression } ';'
03899   | GOTO Identifier ';'
03900   | CASE expression ':' statement
03901   | DEFAULT ':' statement
03902   | Identifier ':' statement
03903   | expr.statement
03904 */
03905 bool Parser::rStatement(Ptree*& st)
03906 {
03907     Token tk1, tk2, tk3;
03908     Ptree *st2, *exp;
03909     int k;
03910 
03911     switch(k = lex->LookAhead(0)){
03912     case '{' :
03913         return rCompoundStatement(st);
03914     case TYPEDEF :
03915         return rTypedef(st);
03916     case IF :
03917         return rIfStatement(st);
03918     case SWITCH :
03919         return rSwitchStatement(st);
03920     case WHILE :
03921         return rWhileStatement(st);
03922     case DO :
03923         return rDoStatement(st);
03924     case FOR :
03925         return rForStatement(st);
03926     case TRY :
03927         return rTryStatement(st);
03928     case BREAK :
03929     case CONTINUE :
03930         lex->GetToken(tk1);
03931         if(lex->GetToken(tk2) != ';')
03932             return FALSE;
03933 
03934         if(k == BREAK)
03935             st = new PtreeBreakStatement(new LeafReserved(tk1),
03936                                          Ptree::List(new Leaf(tk2)));
03937         else
03938             st = new PtreeContinueStatement(new LeafReserved(tk1),
03939                                             Ptree::List(new Leaf(tk2)));
03940         return TRUE;
03941     case RETURN :
03942         lex->GetToken(tk1);
03943         if(lex->LookAhead(0) == ';'){
03944             lex->GetToken(tk2);
03945             st = new PtreeReturnStatement(new LeafReserved(tk1),
03946                                           Ptree::List(new Leaf(tk2)));
03947             return TRUE;
03948         }
03949         else{
03950             if(!rCommaExpression(exp))
03951                 return FALSE;
03952 
03953             if(lex->GetToken(tk2) != ';')
03954                 return FALSE;
03955 
03956             st = new PtreeReturnStatement(new LeafReserved(tk1),
03957                                           Ptree::List(exp, new Leaf(tk2)));
03958             return TRUE;
03959         }
03960     case GOTO :
03961         lex->GetToken(tk1);
03962         if(lex->GetToken(tk2) != Identifier)
03963             return FALSE;
03964 
03965         if(lex->GetToken(tk3) != ';')
03966             return FALSE;
03967 
03968         st = new PtreeGotoStatement(new LeafReserved(tk1),
03969                                     Ptree::List(new Leaf(tk2), new Leaf(tk3)));
03970         return TRUE;
03971     case CASE :
03972         lex->GetToken(tk1);
03973         if(!rExpression(exp))
03974             return FALSE;
03975 
03976         if(lex->GetToken(tk2) != ':')
03977             return FALSE;
03978 
03979         if(!rStatement(st2))
03980             return FALSE;
03981 
03982         st = new PtreeCaseStatement(new LeafReserved(tk1),
03983                                     Ptree::List(exp, new Leaf(tk2), st2));
03984         return TRUE;
03985     case DEFAULT :
03986         lex->GetToken(tk1);
03987         if(lex->GetToken(tk2) != ':')
03988             return FALSE;
03989 
03990         if(!rStatement(st2))
03991             return FALSE;
03992 
03993         st = new PtreeDefaultStatement(new LeafReserved(tk1),
03994                                        Ptree::List(new Leaf(tk2), st2));
03995         return TRUE;
03996     case Identifier :
03997         if(lex->LookAhead(1) == ':'){   // label statement
03998             lex->GetToken(tk1);
03999             lex->GetToken(tk2);
04000             if(!rStatement(st2))
04001                 return FALSE;
04002 
04003             st = new PtreeLabelStatement(new Leaf(tk1),
04004                                          Ptree::List(new Leaf(tk2), st2));
04005             return TRUE;
04006         }
04007         // don't break here!
04008     default :
04009         return rExprStatement(st);
04010     }
04011 }
04012 
04013 /*
04014   if.statement
04015   : IF '(' comma.expression ')' statement { ELSE statement }
04016 */
04017 bool Parser::rIfStatement(Ptree*& st)
04018 {
04019     Token tk1, tk2, tk3, tk4;
04020     Ptree *exp, *then, *otherwise;
04021 
04022     if(lex->GetToken(tk1) != IF)
04023         return FALSE;
04024 
04025     if(lex->GetToken(tk2) != '(')
04026         return FALSE;
04027 
04028     if(!rCommaExpression(exp))
04029         return FALSE;
04030 
04031     if(lex->GetToken(tk3) != ')')
04032         return FALSE;
04033 
04034     if(!rStatement(then))
04035         return FALSE;
04036 
04037     st = new PtreeIfStatement(new LeafReserved(tk1),
04038                               Ptree::List(new Leaf(tk2), exp, new Leaf(tk3),
04039                                           then));
04040     if(lex->LookAhead(0) == ELSE){
04041         lex->GetToken(tk4);
04042         if(!rStatement(otherwise))
04043             return FALSE;
04044 
04045         st = Ptree::Nconc(st, Ptree::List(new Leaf(tk4), otherwise));
04046     }
04047 
04048     return TRUE;
04049 }
04050 
04051 /*
04052   switch.statement
04053   : SWITCH '(' comma.expression ')' statement
04054 */
04055 bool Parser::rSwitchStatement(Ptree*& st)
04056 {
04057     Token tk1, tk2, tk3;
04058     Ptree *exp, *body;
04059 
04060     if(lex->GetToken(tk1) != SWITCH)
04061         return FALSE;
04062 
04063     if(lex->GetToken(tk2) != '(')
04064         return FALSE;
04065 
04066     if(!rCommaExpression(exp))
04067         return FALSE;
04068 
04069     if(lex->GetToken(tk3) != ')')
04070         return FALSE;
04071 
04072     if(!rStatement(body))
04073         return FALSE;
04074 
04075     st = new PtreeSwitchStatement(new LeafReserved(tk1),
04076                                   Ptree::List(new Leaf(tk2), exp,
04077                                               new Leaf(tk3), body));
04078     return TRUE;
04079 }
04080 
04081 /*
04082   while.statement
04083   : WHILE '(' comma.expression ')' statement
04084 */
04085 bool Parser::rWhileStatement(Ptree*& st)
04086 {
04087     Token tk1, tk2, tk3;
04088     Ptree *exp, *body;
04089 
04090     if(lex->GetToken(tk1) != WHILE)
04091         return FALSE;
04092 
04093     if(lex->GetToken(tk2) != '(')
04094         return FALSE;
04095 
04096     if(!rCommaExpression(exp))
04097         return FALSE;
04098 
04099     if(lex->GetToken(tk3) != ')')
04100         return FALSE;
04101 
04102     if(!rStatement(body))
04103         return FALSE;
04104 
04105     st = new PtreeWhileStatement(new LeafReserved(tk1),
04106                                  Ptree::List(new Leaf(tk2), exp,
04107                                               new Leaf(tk3), body));
04108     return TRUE;
04109 }
04110 
04111 /*
04112   do.statement
04113   : DO statement WHILE '(' comma.expression ')' ';'
04114 */
04115 bool Parser::rDoStatement(Ptree*& st)
04116 {
04117     Token tk0, tk1, tk2, tk3, tk4;
04118     Ptree *exp, *body;
04119 
04120     if(lex->GetToken(tk0) != DO)
04121         return FALSE;
04122 
04123     if(!rStatement(body))
04124         return FALSE;
04125 
04126     if(lex->GetToken(tk1) != WHILE)
04127         return FALSE;
04128 
04129     if(lex->GetToken(tk2) != '(')
04130         return FALSE;
04131 
04132     if(!rCommaExpression(exp))
04133         return FALSE;
04134 
04135     if(lex->GetToken(tk3) != ')')
04136         return FALSE;
04137 
04138     if(lex->GetToken(tk4) != ';')
04139         return FALSE;
04140 
04141     st = new PtreeDoStatement(new LeafReserved(tk0),
04142                                  Ptree::List(body, new LeafReserved(tk1),
04143                                              new Leaf(tk2), exp,
04144                                              new Leaf(tk3), new Leaf(tk4)));
04145     return TRUE;
04146 }
04147 
04148 /*
04149   for.statement
04150   : FOR '(' expr.statement {comma.expression} ';' {comma.expression} ')'
04151     statement
04152 */
04153 bool Parser::rForStatement(Ptree*& st)
04154 {
04155     Token tk1, tk2, tk3, tk4;
04156     Ptree *exp1, *exp2, *exp3, *body;
04157 
04158     if(lex->GetToken(tk1) != FOR)
04159         return FALSE;
04160 
04161     if(lex->GetToken(tk2) != '(')
04162         return FALSE;
04163 
04164     if(!rExprStatement(exp1))
04165         return FALSE;
04166 
04167     if(lex->LookAhead(0) == ';')
04168         exp2 = nil;
04169     else
04170         if(!rCommaExpression(exp2))
04171             return FALSE;
04172 
04173     if(lex->GetToken(tk3) != ';')
04174         return FALSE;
04175 
04176     if(lex->LookAhead(0) == ')')
04177         exp3 = nil;
04178     else
04179         if(!rCommaExpression(exp3))
04180             return FALSE;
04181 
04182     if(lex->GetToken(tk4) != ')')
04183         return FALSE;
04184 
04185     if(!rStatement(body))
04186         return FALSE;
04187 
04188 
04189     st = new PtreeForStatement(new LeafReserved(tk1),
04190                                Ptree::List(new Leaf(tk2), exp1, exp2,
04191                                            new Leaf(tk3), exp3,
04192                                            new Leaf(tk4), body));
04193     return TRUE;
04194 }
04195 
04196 /*
04197   try.statement
04198   : TRY compound.statement (exception.handler)+ ';'
04199 
04200   exception.handler
04201   : CATCH '(' (arg.declaration | Ellipsis) ')' compound.statement
04202 */
04203 bool Parser::rTryStatement(Ptree*& st)
04204 {
04205     Token tk, op, cp;
04206     Ptree *body, *handler;
04207 
04208     if(lex->GetToken(tk) != TRY)
04209         return FALSE;
04210 
04211     if(!rCompoundStatement(body))
04212         return FALSE;
04213 
04214     st = new PtreeTryStatement(new LeafReserved(tk), Ptree::List(body));
04215 
04216     do{
04217         if(lex->GetToken(tk) != CATCH)
04218             return FALSE;
04219 
04220         if(lex->GetToken(op) != '(')
04221             return FALSE;
04222 
04223         if(lex->LookAhead(0) == Ellipsis){
04224             lex->GetToken(cp);
04225             handler = new Leaf(cp);
04226         }
04227         else{
04228             Encoding encode;
04229             if(!rArgDeclaration(handler, encode))
04230                 return FALSE;
04231         }
04232 
04233         if(lex->GetToken(cp) != ')')
04234             return FALSE;
04235 
04236         if(!rCompoundStatement(body))
04237             return FALSE;
04238 
04239         st = Ptree::Snoc(st, Ptree::List(new LeafReserved(tk),
04240                                          new Leaf(op), handler, new Leaf(cp),
04241                                          body));
04242     } while(lex->LookAhead(0) == CATCH);
04243     return TRUE;
04244 }
04245 
04246 /*
04247   expr.statement
04248   : ';'
04249   | declaration.statement
04250   | comma.expression ';'
04251   | openc++.postfix.expr
04252   | openc++.primary.exp
04253 */
04254 bool Parser::rExprStatement(Ptree*& st)
04255 {
04256     Token tk;
04257 
04258     if(lex->LookAhead(0) == ';'){
04259         lex->GetToken(tk);
04260         st = new PtreeExprStatement(nil, Ptree::List(new Leaf(tk)));
04261         return TRUE;
04262     }
04263     else{
04264         char* pos = lex->Save();
04265         if(rDeclarationStatement(st))
04266             return TRUE;
04267         else{
04268             Ptree* exp;
04269             lex->Restore(pos);
04270             if(!rCommaExpression(exp))
04271                 return FALSE;
04272 
04273             if(exp->IsA(ntUserStatementExpr, ntStaticUserStatementExpr)){
04274                 st = exp;
04275                 return TRUE;
04276             }
04277 
04278             if(lex->GetToken(tk) != ';')
04279                 return FALSE;
04280 
04281             st = new PtreeExprStatement(exp, Ptree::List(new Leaf(tk)));
04282             return TRUE;
04283         }
04284     }
04285 }
04286 
04287 /*
04288   declaration.statement
04289   : decl.head integral.or.class.spec {cv.qualify} {declarators} ';'
04290   | decl.head name {cv.qualify} declarators ';'
04291   | const.declaration
04292 
04293   decl.head
04294   : {storage.spec} {cv.qualify}
04295 
04296   const.declaration
04297   : cv.qualify {'*'} Identifier '=' expression {',' declarators} ';'
04298 
04299   Note: if you modify this function, take a look at rDeclaration(), too.
04300 */
04301 bool Parser::rDeclarationStatement(Ptree*& statement)
04302 {
04303     Ptree *storage_s, *cv_q, *integral;
04304     Encoding type_encode;
04305 
04306     if(!optStorageSpec(storage_s)
04307        || !optCvQualify(cv_q)
04308        || !optIntegralTypeOrClassSpec(integral, type_encode))
04309         return FALSE;
04310 
04311     Ptree* head = nil;
04312     if(storage_s != nil)
04313         head = Ptree::Snoc(head, storage_s);
04314 
04315     if(integral != nil)
04316         return rIntegralDeclStatement(statement, type_encode, integral,
04317                                       cv_q, head);
04318     else{
04319         type_encode.Clear();
04320         int t = lex->LookAhead(0);
04321         if(cv_q != nil && ((t == Identifier && lex->LookAhead(1) == '=')
04322                            || t == '*'))
04323             return rConstDeclaration(statement, type_encode, head, cv_q);
04324         else
04325             return rOtherDeclStatement(statement, type_encode, cv_q, head);
04326     }
04327 }
04328 
04329 /*
04330   integral.decl.statement
04331   : decl.head integral.or.class.spec {cv.qualify} {declarators} ';'
04332 */
04333 bool Parser::rIntegralDeclStatement(Ptree*& statement, Encoding& type_encode,
04334                                     Ptree* integral, Ptree* cv_q, Ptree* head)
04335 {
04336     Ptree *cv_q2, *decl;
04337     Token tk;
04338 
04339     if(!optCvQualify(cv_q2))
04340         return FALSE;
04341 
04342     if(cv_q != nil)
04343         if(cv_q2 == nil)
04344             integral = Ptree::Snoc(cv_q, integral);
04345         else
04346             integral = Ptree::Nconc(cv_q, Ptree::Cons(integral, cv_q2));
04347     else if(cv_q2 != nil)
04348         integral = Ptree::Cons(integral, cv_q2);
04349 
04350     type_encode.CvQualify(cv_q, cv_q2);
04351     if(lex->LookAhead(0) == ';'){
04352         lex->GetToken(tk);
04353         statement = new PtreeDeclaration(head, Ptree::List(integral,
04354                                                            new Leaf(tk)));
04355         return TRUE;
04356     }
04357     else{
04358         if(!rDeclarators(decl, type_encode, FALSE, TRUE))
04359             return FALSE;
04360 
04361         if(lex->GetToken(tk) != ';')
04362             return FALSE;
04363             
04364         statement = new PtreeDeclaration(head, Ptree::List(integral, decl,
04365                                                            new Leaf(tk)));
04366         return TRUE;
04367     }
04368 }
04369 
04370 /*
04371    other.decl.statement
04372    :decl.head name {cv.qualify} declarators ';'
04373 */
04374 bool Parser::rOtherDeclStatement(Ptree*& statement, Encoding& type_encode,
04375                                  Ptree* cv_q, Ptree* head)
04376 {
04377     Ptree *type_name, *cv_q2, *decl;
04378     Token tk;
04379 
04380     if(!rName(type_name, type_encode))
04381         return FALSE;
04382 
04383     if(!optCvQualify(cv_q2))
04384         return FALSE;
04385 
04386     if(cv_q != nil)
04387         if(cv_q2 == nil)
04388             type_name = Ptree::Snoc(cv_q, type_name);
04389         else
04390             type_name = Ptree::Nconc(cv_q, Ptree::Cons(type_name, cv_q2));
04391     else if(cv_q2 != nil)
04392         type_name = Ptree::Cons(type_name, cv_q2);
04393 
04394     type_encode.CvQualify(cv_q, cv_q2);
04395     if(!rDeclarators(decl, type_encode, FALSE, TRUE))
04396         return FALSE;
04397 
04398     if(lex->GetToken(tk) != ';')
04399         return FALSE;
04400 
04401     statement = new PtreeDeclaration(head, Ptree::List(type_name, decl,
04402                                                        new Leaf(tk)));
04403     return TRUE;
04404 }
04405 
04406 bool Parser::MaybeTypeNameOrClassTemplate(Token&)
04407 {
04408     return TRUE;
04409 }
04410 
04411 void Parser::SkipTo(int token)
04412 {
04413     Token tk;
04414 
04415     for(;;){
04416         int t = lex->LookAhead(0);
04417         if(t == token || t == '\0')
04418             break;
04419         else
04420             lex->GetToken(tk);
04421     }
04422 }
04423 
04424 #ifdef TEST
04425 
04426 #include "buffer.h"
04427 #include "walker.h"
04428 
04429 main()
04430 {
04431     ProgramFromStdin    prog;
04432     Lex                 lex(&prog);
04433     Parser              parse(&lex);
04434     Walker              w(&parse);
04435     Ptree*              def;
04436 
04437     while(parse.rProgram(def)){
04438         def->Display2(cout);
04439         w.Translate(def);
04440     }
04441 
04442     cerr << parse.NumOfErrors() << " errors\n";
04443 }
04444 #endif

Generated on Mon Feb 10 17:32:54 2003 for VFiasco Semantics Compiler by doxygen1.2.15