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