00001 #include <boost/spirit/core.hpp>
00002 #include <boost/spirit/actor/push_back_actor.hpp>
00003
00004 #include "ast.h"
00005 #include "ifprintf.h"
00006
00007 using namespace std;
00008 using namespace boost::spirit;
00009 using namespace AST;
00013 vector<Node*> stack_node;
00014 vector<Node*> stack_wrapped_node;
00015 vector<List*> stack_list_nodes;
00016 string constant_type, constant_value;
00017 vector<AttributeProxy*> stack_attribute_proxy;
00018 vector<Node*> stack_attribute_value;
00019
00021 void pop_stack_node(){
00022 stack_node.pop_back();
00023 }
00024 void pop_stack_wrapped_nodes(){
00025 stack_wrapped_node.pop_back();
00026 }
00027 void pop_stack_list_nodes(){
00028 stack_list_nodes.pop_back();
00029 }
00030 void pop_stack_attribute_proxy(){
00031 delete stack_attribute_proxy.back();
00032 stack_attribute_proxy.pop_back();
00033 }
00034 void pop_stack_attribute_value(){
00035 stack_attribute_value.pop_back();
00036 }
00038 #define create_create_node_func(CLASSNAME) \
00039 struct Creator_##CLASSNAME {\
00040 static Node* create() { return new CLASSNAME(); }\
00041 };\
00042 create_node_funcs[#CLASSNAME] = Creator_##CLASSNAME::create;
00043
00044 typedef Node* (*create_node_func)(void);
00045 static map<string, create_node_func> create_create_node_funcs(){
00046 printf("create_create_node_funcs\n");
00047 map<string, create_node_func> create_node_funcs;
00048 create_create_node_func(Program);
00049 create_create_node_func(If);
00050 create_create_node_func(Op_Binary);
00051 create_create_node_func(Identifier);
00052 create_create_node_func(Constant);
00053 create_create_node_func(FunctionCall);
00054 return create_node_funcs;
00055 }
00056 static map<string, create_node_func> create_node_funcs = create_create_node_funcs();
00057
00059 void start_node(char const* start, char const* end){
00060 string str(start, end);
00061 printf("start_node:%s\n", str.c_str());
00062 create_node_func func = create_node_funcs[str];
00063 assert(func && "undefined function for some type");
00064 Node* n = func();
00065 assert(n && "func failed");
00066 stack_node.push_back(n);
00067 }
00069 void end_node(char const* start, char const* end){
00070 string str(start, end);
00071 printf("end_node:%s\n", str.c_str());
00072 Node* n = stack_node.back();
00073 stack_wrapped_node.push_back(n);
00074 pop_stack_node();
00075 }
00076
00078 void start_attribute(char const* start, char const* end){
00079 string str(start, end);
00080
00081 AttributeProxy* attrib = new AttributeProxy(stack_node.back(), str);
00082 stack_attribute_proxy.push_back(attrib);
00083 }
00085 void end_attribute(char const* start, char const* end){
00086 string str(start, end);
00087 *(stack_attribute_proxy.back()) = stack_attribute_value.back();
00088 pop_stack_attribute_proxy();
00089 pop_stack_attribute_value();
00090 }
00091
00092 void do_value_string(char const* start, char const* end){
00093 string str(start, end);
00094 Leaf* leaf = new Leaf(str);
00095 stack_attribute_value.push_back(leaf);
00096 }
00097 void do_value_id(char const* start, char const* end){
00098 string str(start, end);
00099 Identifier* identifier = new Identifier();
00100 identifier->handle = str;
00101 stack_attribute_value.push_back(identifier);
00102 }
00103 void do_const_type(char const* start, char const* end){
00104 string str(start, end);
00105 constant_value = str;
00106 }
00107 void do_const_value(char const* start, char const* end){
00108 string str(start, end);
00109 constant_value = str;
00110 }
00111 void do_value_const(char const* start, char const* end){
00112 string str(start, end);
00113 Constant* constant = new Constant();
00114 constant->type = constant_type;
00115 constant->value = constant_value;
00116 stack_attribute_value.push_back(constant);
00117 }
00118 void start_list(char const* start, char const* end){
00119 printf("start_list\n");
00120 stack_list_nodes.push_back(new List());
00121 }
00122 void do_list_node(char const* start, char const* end){
00123 printf("list.push_back(%s)\n", stack_attribute_value.back()->get_name());
00124 stack_list_nodes.back()->addChild(stack_attribute_value.back());
00125 pop_stack_attribute_value();
00126 }
00127 void end_list(char const* start, char const* end){
00128 printf("end_list\n");
00129 stack_attribute_value.push_back(stack_list_nodes.back());
00130 pop_stack_list_nodes();
00131 }
00132 void do_wrapped_node(const char* start, const char* end){
00133
00134 stack_attribute_value.push_back(stack_wrapped_node.back());
00135 pop_stack_wrapped_nodes();
00136 }
00140 struct ASTreeGrammar : public grammar<ASTreeGrammar>
00141 {
00142 ASTreeGrammar(){}
00143
00144 template <typename ScannerT>
00145 struct definition
00146 {
00147 definition(ASTreeGrammar const& self)
00148 {
00149 node =
00150 (str[&start_node] >> +(attributePair))[&end_node]
00151 ;
00152
00153 attributePair =
00154 str[&start_attribute] >> attributeValue[&end_attribute]
00155 ;
00156
00157 attributeValue =
00158 value_node
00159 | value_id
00160 | value_const
00161 | value_list
00162 | value_string
00163 ;
00164
00165 value_node =
00166 ("{" >> node >> "}")[&do_wrapped_node]
00167 ;
00168
00169 value_list =
00170 str_p("[")[&start_list] >> *(value_node[&do_list_node]) >> str_p("]")[&end_list]
00171 ;
00172
00173 value_string =
00174 lexeme_d[(+(~space_p))][&do_value_string]
00175 ;
00176
00177 value_id =
00178 str_p("id") >> ':' >> str[&do_value_id]
00179 ;
00180
00181 value_const =
00182 (str_p("const") >> ':' >> str[&do_const_type] >> ':' >> str[&do_const_value])[&do_value_const]
00183 ;
00184
00185 str =
00186 (lexeme_d[(+(alnum_p | ch_p('_')))])
00187 ;
00188
00189 BOOST_SPIRIT_DEBUG_NODE(node);
00190 BOOST_SPIRIT_DEBUG_NODE(name_node);
00191 BOOST_SPIRIT_DEBUG_NODE(attributePair);
00192 BOOST_SPIRIT_DEBUG_NODE(name_attribute);
00193 BOOST_SPIRIT_DEBUG_NODE(attributeValue);
00194 BOOST_SPIRIT_DEBUG_NODE(value_node);
00195 BOOST_SPIRIT_DEBUG_NODE(value_list);
00196 BOOST_SPIRIT_DEBUG_NODE(value_string);
00197 BOOST_SPIRIT_DEBUG_NODE(value_id);
00198 BOOST_SPIRIT_DEBUG_NODE(value_const);
00199 }
00200
00201 rule<ScannerT> node, name_node, attributePair, name_attribute, attributeValue, value_node, value_list, value_string, value_id, value_const, str;
00202 rule<ScannerT> const& start() const { return node; }
00203 };
00204 };
00210 Node* AST::fromASTFile(FILE* f){
00211 printf("fromASTFile(%p)\n", f);
00212 string str;
00213 char s[1024];
00214 vector<string> v;
00215 while (fgets(s, 1024, f)) {
00216 if (s[0] == '\0')
00217 break;
00218 str += s;
00219 }
00220 ASTreeGrammar grammar;
00221
00222 bool b = parse(str.c_str(), grammar, space_p).full;
00223 printf(b ? "ParsingSuccesful\n" : "Parsing Failed\n");
00224 Node* root = stack_wrapped_node.back();
00225 return root;
00226 }