]> git.mdlowis.com Git - archive/parse-utils.git/commitdiff
Initial commit
authorMike D. Lowis <mike@mdlowis.com>
Sun, 2 Oct 2011 04:46:46 +0000 (00:46 -0400)
committerMike D. Lowis <mike@mdlowis.com>
Sun, 2 Oct 2011 04:46:46 +0000 (00:46 -0400)
README.txt [new file with mode: 0644]
src/ast/ast.cpp [new file with mode: 0644]
src/ast/ast.h [new file with mode: 0644]
src/parser.cpp [new file with mode: 0644]
src/parser.h [new file with mode: 0644]
src/visitor/visitor.cpp [new file with mode: 0644]
src/visitor/visitor.h [new file with mode: 0644]

diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..2b07464
--- /dev/null
@@ -0,0 +1,5 @@
+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.
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
new file mode 100644 (file)
index 0000000..8683e97
--- /dev/null
@@ -0,0 +1,69 @@
+#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);
+}
+
diff --git a/src/ast/ast.h b/src/ast/ast.h
new file mode 100644 (file)
index 0000000..6877fdf
--- /dev/null
@@ -0,0 +1,28 @@
+#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
diff --git a/src/parser.cpp b/src/parser.cpp
new file mode 100644 (file)
index 0000000..84eb3f0
--- /dev/null
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *  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;
+}
+
diff --git a/src/parser.h b/src/parser.h
new file mode 100644 (file)
index 0000000..b2e146c
--- /dev/null
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *  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
diff --git a/src/visitor/visitor.cpp b/src/visitor/visitor.cpp
new file mode 100644 (file)
index 0000000..71c3ccf
--- /dev/null
@@ -0,0 +1,35 @@
+#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 );
+}
+
diff --git a/src/visitor/visitor.h b/src/visitor/visitor.h
new file mode 100644 (file)
index 0000000..61fdde0
--- /dev/null
@@ -0,0 +1,30 @@
+#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