00001
00002
00003 #ifndef ptree_program_visitor_h
00004 #define ptree_program_visitor_h
00005
00006 #include "ptree_visitor.h"
00007 #include "downcast.h"
00008
00009
00010
00011
00012
00013
00014
00015
00016 template <typename Returntype>
00017 class Ptree_program_visitor : virtual public Ptree_visitor<Returntype>
00018 {
00019 typedef Ptree_visitor<Returntype> Super;
00020
00021 public:
00022 Ptree_program_visitor(Source* s);
00023
00024 virtual Returntype visit_function(Ptree* storagespec, Ptree* returntype, PtreeDeclarator* decl, PtreeBlock* block);
00025
00026 virtual Returntype visit_type_declaration(Ptree* storagespec, Ptree* type);
00027
00028 virtual Returntype visit_name_declaration(Ptree* storagespec, Ptree* type, Ptree* decllist);
00029
00030 private:
00031
00032
00033
00034
00035
00036 virtual Returntype visit_declaration(PtreeDeclaration *p);
00037 };
00038
00039
00040
00041
00042
00043
00044
00045
00046 template <typename Returntype> Ptree_program_visitor<Returntype>::Ptree_program_visitor(Source* s)
00047 : Ptree_visitor<Returntype> (s)
00048 {
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 template <typename Returntype> Returntype
00059 Ptree_program_visitor<Returntype>::visit_declaration(PtreeDeclaration *p)
00060 {
00061 Ptree* storagespec = p->First();
00062 Ptree* typespec = p->Second();
00063
00064
00065 PtreeDeclarator* decl = dynamic_cast<PtreeDeclarator*> (p->Third());
00066
00067 if (decl)
00068 return visit_function (storagespec,
00069 typespec,
00070 decl,
00071 downcast<PtreeBlock*> (p->Nth(3)));
00072
00073
00074
00075 if (p->Third()->IsLeaf())
00076 {
00077 assert (* p->Third()->ToString() == ';');
00078 return visit_type_declaration (storagespec, typespec);
00079 }
00080
00081
00082 return visit_name_declaration(storagespec, typespec, p->Third());
00083 }
00084
00085
00086
00087 template <typename Returntype> Returntype
00088 Ptree_program_visitor<Returntype>::visit_function(Ptree* storagespec,
00089 Ptree* returntype,
00090 PtreeDeclarator* decl,
00091 PtreeBlock* block)
00092 {
00093 visit(storagespec);
00094 visit(returntype);
00095 visit(decl);
00096 return visit(block);
00097 }
00098
00099
00100
00101 template <typename Returntype> Returntype
00102 Ptree_program_visitor<Returntype>::visit_type_declaration(Ptree* storagespec, Ptree* type)
00103 {
00104 visit(storagespec);
00105 return visit(type);
00106 }
00107
00108
00109
00110 template <typename Returntype> Returntype
00111 Ptree_program_visitor<Returntype>::visit_name_declaration(Ptree* storagespec,
00112 Ptree* type,
00113 Ptree* decllist)
00114 {
00115 visit(storagespec);
00116 visit(type);
00117 return visit(decllist);
00118 }
00119
00120 #endif // ptree_program_visitor_h