--- /dev/null
+Overview
+-------------------------------------------------------------------------------
+This module provides a collection of C++ classes for implementing parsers in
+C and C++. Among the classes provided are a homogenous abstract syntax tree
+and an tree visitor.
--- /dev/null
+#include "ast.h"
+#include <sstream>
+#include <string.h>
+
+AST::AST(ASTNodeType type)
+{
+ node_type = type;
+ node_text = NULL;
+ node_children = new list<AST*>();
+}
+
+AST::~AST()
+{
+ list<AST*>::iterator it = node_children->begin();
+ for(; it != node_children->end(); it++)
+ {
+ delete *(it);
+ }
+ delete node_children;
+ delete node_text;
+}
+
+AST::AST(ASTNodeType type, char* text)
+{
+ node_type = type;
+ node_text = new string(text);
+ node_children = new list<AST*>();
+}
+
+AST::AST(ASTNodeType type, int child_count, ...)
+{
+ va_list arg_list;
+ int i = 0;
+ node_type = type;
+ node_text = NULL;
+ node_children = new list<AST*>();
+ va_start (arg_list, child_count);
+ for (i = 0; i < child_count ; i++)
+ {
+ node_children->push_back( (AST*)va_arg(arg_list, AST*) );
+ }
+ va_end(arg_list);
+}
+
+ASTNodeType AST::type()
+{
+ return node_type;
+}
+
+list<AST*>* AST::children()
+{
+ return node_children;
+}
+
+string AST::text()
+{
+ ostringstream oss;
+ if(node_text != NULL)
+ {
+ oss << node_text->c_str();
+ }
+ return oss.str();
+}
+
+void AST::addChild(AST* node)
+{
+ node_children->push_back(node);
+}
+
--- /dev/null
+#ifndef AST_H
+#define AST_H
+
+#include <stdarg.h>
+#include <list>
+#include <string>
+
+using namespace std;
+
+typedef unsigned int ASTNodeType;
+
+class AST {
+ protected:
+ ASTNodeType node_type;
+ string* node_text;
+ list<AST*>* node_children;
+ public:
+ AST(ASTNodeType type);
+ ~AST();
+ AST(ASTNodeType type, char* text);
+ AST(ASTNodeType type, int child_count, ...);
+ ASTNodeType type();
+ string text();
+ list<AST*>* children();
+ void addChild(AST* node);
+};
+
+#endif
--- /dev/null
+/******************************************************************************
+ * Copyright (C) 2001 Michael D. Lowis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+/******************************************************************************
+ * Includes and Prototypes
+ *****************************************************************************/
+#include <stdio.h>
+#include "parser.h"
+
+using namespace std;
+
+#ifdef PURE_PARSER
+typedef void* yyscan_t;
+extern int yyparse(ParseContext_T* context);
+extern int yylex_init(yyscan_t* ptr_yy_globals);
+extern void yyset_in (FILE* in_str , yyscan_t yyscanner);
+#else
+#endif
+
+/******************************************************************************
+ * Public Functions
+ *****************************************************************************/
+Parser::~Parser()
+{
+ delete factory;
+}
+
+void Parser::parseInput(FILE* in_file)
+{
+ if ( in_file != NULL )
+ {
+ #ifdef PURE_PARSER
+ ParseContext_T context = { NULL, this};
+ yylex_init( &(context.lexinfo) );
+ yyset_in( in_file, context.lexinfo );
+ yyparse( &context );
+ #else
+ #endif
+ }
+}
+
+void Parser::parseFile(string* in_file)
+{
+ FILE* input_file = fopen( in_file->c_str() ,"r");
+ parseInput( input_file );
+ delete in_file;
+}
+
+void Parser::processAST(AST* root)
+{
+ Visitor* translator = factory->createVisitor(root);
+ translator->visit();
+ cout << translator->str();
+ delete translator;
+}
+
--- /dev/null
+/******************************************************************************
+ * Copyright (C) 2001 Michael D. Lowis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *****************************************************************************/
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <string>
+#include "ast.h"
+#include "visitor.h"
+
+using namespace std;
+
+class Parser {
+ protected:
+ VisitorFactory* factory;
+ private:
+ public:
+ Parser(VisitorFactory* trans_fact) : factory(trans_fact) {}
+ ~Parser();
+ void parseFile(string* in_file);
+ void parseInput(FILE* in_file);
+ void processAST(AST* root);
+};
+
+#ifdef PURE_PARSER
+typedef struct
+{
+ void* lexinfo;
+ Parser* parser;
+} ParseContext_T;
+#endif
+
+#endif
--- /dev/null
+#include "visitor.h"
+#include <list>
+
+using namespace std;
+
+void Visitor::visit(AST* cur, int depth)
+{
+ list<AST*>* children;
+ list<AST*>::iterator it;
+
+ // If we are just starting then use the global tree
+ if(cur == NULL) cur = ast;
+
+ // Execute or pre-walk actions
+ if(depth == 0) beforeVisit( cur, depth );
+
+ // Setup our locals
+ children = cur->children();
+ it = children->begin();
+
+ // Visit the tree
+ beforeChildren(cur,depth);
+ depth++;
+ for(; it != children->end(); it++)
+ {
+ beforeChild( *it, depth );
+ visit( *it, depth );
+ afterChild( *it, depth );
+ }
+ afterChildren(cur,depth);
+
+ // Execute our post-walk actions
+ if(depth == 1) afterVisit( cur, depth );
+}
+
--- /dev/null
+#ifndef TRANSLATOR_H
+#define TRANSLATOR_H
+
+#include "ast.h"
+#include <string>
+#include <iostream>
+
+class Visitor {
+ protected:
+ AST* ast;
+ public:
+ Visitor(AST* tree) : ast(tree) {};
+ ~Visitor() { delete ast; }
+ void visit(AST* cur = NULL, int depth = 0);
+ virtual string str() = 0;
+ private:
+ virtual void beforeVisit(AST* cur, int depth) = 0;
+ virtual void afterVisit(AST* cur, int depth) = 0;
+ virtual void beforeChildren(AST* cur, int depth) = 0;
+ virtual void afterChildren(AST* cur, int depth) = 0;
+ virtual void beforeChild(AST* cur, int depth) = 0;
+ virtual void afterChild(AST* cur, int depth) = 0;
+};
+
+class VisitorFactory {
+ public:
+ virtual Visitor* createVisitor(AST* root) = 0;
+};
+
+#endif