[submodule "deps/cork"]
path = deps/cork
url = git://github.com/mikedlowis/cork.git
+[submodule "deps/parse-utils"]
+ path = deps/parse-utils
+ url = git://github.com/mikedlowis/parse-utils.git
--- /dev/null
+Subproject commit e2ccce38d3d7a0f77a0834b87912a679bcb4ed47
require 'tools/rake_utils/source/binary.rb'
require 'tools/rake_utils/source/tests.rb'
+# Keep track of the project root
PROJECT_ROOT = File.expand_path(File.dirname(__FILE__))
+
+# Add library build folders to the clobber list
CLOBBER.include('./deps/cork/build/static')
CLOBBER.include('./deps/cork/build/shared')
+CLOBBER.include('./deps/parse-utils/build/static')
+CLOBBER.include('./deps/parse-utils/build/shared')
#------------------------------------------------------------------------------
# Configuration Objects
:name => 'dlang',
:output_dir => 'build/parser',
:compiler_options => [ '-c', '-Wall', '-Werror', '-o' ],
- :static_libs => [ './deps/cork/build/static/bin/libcork.a' ],
+ :static_libs => [
+ './deps/cork/build/static/bin/libcork.a',
+ './deps/parse-utils/build/static/bin/libparse-utils.a',
+ ],
:source_files => [ 'source/**/*.c*' ],
:include_dirs => [
'source/**/',
- 'deps/cork/source/**/'
+ 'deps/cork/source/**/',
+ 'deps/parse-utils/source/**/'
],
})
DLangParser.setup_default_rake_tasks()
-
# Configuration for the unit tests
UnitTest = Tests.new({
:test_files => [ 'tests/source/**.h' ],
UnitTest.setup_default_rake_tasks()
desc 'Build and link all artifacts'
-task :release => [ :cork, DLangParser.name() ]
+task :release => [ :cork, :parse_utils, DLangParser.name() ]
+desc 'Build the cork memory leak detector'
task :cork do
Dir.chdir('./deps/cork')
sh 'rake release'
Dir.chdir(PROJECT_ROOT)
end
+
+desc 'Build the parse-utils library'
+task :parse_utils do
+ Dir.chdir('./deps/parse-utils')
+ sh 'rake release'
+ Dir.chdir(PROJECT_ROOT)
+end
+++ /dev/null
-#include <sstream>
-#include "exception.h"
-
-Exception::Exception(int line, int column) throw() : std::exception(), ex_line(line), ex_column(column)
-{
-}
-
-const char* Exception::what() const throw()
-{
- std::ostringstream oss;
- oss << "(ln " << ex_line << ", col " << ex_column << "): ";
- oss << ((Exception*)this)->message() << std::endl;
- return oss.str().c_str();
-}
-
-void Exception::setMessage(std::string msg) throw()
-{
- ex_msg = msg;
-}
-
-std::string& Exception::message(void) throw()
-{
- return ex_msg;
-}
-
+++ /dev/null
-#ifndef EXCEPTION_H
-#define EXCEPTION_H
-
-#include <exception>
-#include <string>
-
-class Exception : public std::exception
-{
- protected:
- int ex_line;
- int ex_column;
- std::string ex_msg;
- public:
- Exception(int line, int column) throw();
- virtual ~Exception() throw() {};
- virtual const char* what() const throw();
- void setMessage(std::string msg) throw();
- std::string& message(void) throw();
-};
-
-#endif
+++ /dev/null
-#include <exception>
-#include "ilexer.h"
-#include "exception.h"
-#include "cork.h"
-
-using namespace std;
-
-ILexer::ILexer() : line(-1), column(-1)
-{
-}
-
-ILexer::~ILexer()
-{
-}
-
-void ILexer::setInput(char* in)
-{
- line = 1;
- column = 0;
- input = _new istringstream( string( in ) );
- consume();
-}
-
-void ILexer::setInput(string& in)
-{
- line = 1;
- column = 0;
- input = _new istringstream( in );
- consume();
-}
-
-void ILexer::setInput(istream* in)
-{
- line = 1;
- column = 0;
- input = in;
- consume();
-}
-
-bool ILexer::eof(void)
-{
- return ((input == NULL) || (input->eof()));
-}
-
-void ILexer::consume(void)
-{
- if(input->eof())
- {
- current = EOF;
- }
- else
- {
- current = input->get();
- if(current == '\n')
- {
- line++;
- column = 0;
- }
- else
- {
- column++;
- }
- }
-}
-
-void ILexer::match(char x) {
- if ( current == x)
- {
- consume();
- }
- else
- {
- ostringstream oss;
- oss << "Unexpected character. Expected " << x << ", received " << current << ".";
- Exception ex(line,column);
- ex.setMessage(oss.str());
- throw ex;
- }
-}
-
-
+++ /dev/null
-#ifndef LEXER_H
-#define LEXER_H
-
-#include <iostream>
-#include <sstream>
-#include <cstdio>
-#include "token.h"
-
-class ILexer
-{
- protected:
- int line;
- int column;
- char current;
- std::istream* input;
-
- public:
- ILexer();
- virtual ~ILexer();
-
- void setInput(char* in);
- void setInput(std::string& in);
- void setInput(std::istream* in);
-
- void consume(void);
- void match(char x);
- bool eof(void);
-
- virtual Token next(void) = 0;
-};
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include "token.h"
-
-Token::Token() : tok_type(EOF), tok_text(""), tok_line(-1), tok_col(-1)
-{
-}
-
-Token::Token(TokenType_T ttype, std::string ttext, int line, int col) : tok_type(ttype), tok_text(ttext), tok_line(line), tok_col(col)
-{
-}
-
-Token::Token(TokenType_T ttype, int line, int col) : tok_type(ttype), tok_line(line), tok_col(col)
-{
-}
-
-void Token::type(TokenType_T typ)
-{
- tok_type = typ;
-}
-
-TokenType_T Token::type()
-{
- return tok_type;
-}
-
-void Token::text(std::string txt)
-{
- tok_text = txt;
-}
-
-std::string Token::text()
-{
- return tok_text;
-}
-
-void Token::line(int ln)
-{
- tok_line = ln;
-}
-
-int Token::line()
-{
- return tok_line;
-}
-
-void Token::column(int col)
-{
- tok_col = col;
-}
-
-int Token::column()
-{
- return tok_col;
-}
-
+++ /dev/null
-#ifndef TOKEN_H
-#define TOKEN_H
-
-#include <string>
-
-typedef int TokenType_T;
-
-class Token
-{
- private:
- TokenType_T tok_type;
- std::string tok_text;
- int tok_line;
- int tok_col;
- public:
- Token();
- Token(TokenType_T ttype, int line, int col);
- Token(TokenType_T ttype, std::string ttext, int line, int col);
-
- void type(TokenType_T typ);
- TokenType_T type();
-
- void text(std::string txt);
- std::string text();
-
- void line(int ln);
- int line();
-
- void column(int col);
- int column();
-};
-
-#endif
+++ /dev/null
-#include "ast.h"
-#include <sstream>
-#include <string.h>
-#include <iostream>
-#include "cork.h"
-
-AST::AST(ASTNodeType type)
-{
- node_type = type;
- node_text = "";
- node_children = _new list<AST*>();
-}
-
-AST::AST(ASTNodeType type, const char* text)
-{
- node_type = type;
- node_text = string(text);
- node_children = _new list<AST*>();
-}
-
-AST::AST(ASTNodeType type, std::string text)
-{
- node_type = type;
- node_text = 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 = "";
- 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);
-}
-
-AST::~AST()
-{
- list<AST*>::iterator it = node_children->begin();
- for(; it != node_children->end(); it++)
- {
- delete *(it);
- }
- delete node_children;
-}
-
-AST& AST::operator = (AST& rhs)
-{
- list<AST*>::iterator it = rhs.children()->begin();
- node_type = rhs.type();
- node_text = rhs.text();
- node_children->clear();
-
- for(; it != rhs.children()->end(); it++)
- {
- node_children->push_back( (*it)->clone() );
- }
-
- return *this;
-}
-
-ASTNodeType AST::type(void)
-{
- return node_type;
-}
-
-list<AST*>* AST::children(void)
-{
- return node_children;
-}
-
-string AST::text(void)
-{
- return node_text;
-}
-
-void AST::addChild(AST* node)
-{
- node_children->push_back(node);
-}
-
-AST* AST::clone(void)
-{
- AST* new_clone = _new AST( node_type, node_text );
- list<AST*>::iterator it = node_children->begin();
- for(; it != node_children->end(); it++)
- {
- new_clone->addChild( (*it)->clone() );
- }
- return new_clone;
-}
-
+++ /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(ASTNodeType type, const char* text);
- AST(ASTNodeType type, string text);
- AST(ASTNodeType type, int child_count, ...);
- virtual ~AST();
-
- AST& operator = (AST& rhs);
-
- ASTNodeType type(void);
- string text(void);
- list<AST*>* children(void);
- void addChild(AST* node);
- AST* clone(void);
-};
-
-#endif
+++ /dev/null
-#include "btparser.h"
-#include "exception.h"
-
-BTParser::BTParser(ILexer* lxer) : lexer(lxer), current(0)
-{
-}
-
-BTParser::~BTParser()
-{
- if(lexer != NULL)
- {
- delete lexer;
- // Input stream was deleted with the lexer so null it out
- IParser::setInput((istream*)NULL);
- }
-}
-
-void BTParser::setInput(char* in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
-}
-
-void BTParser::setInput(string& in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
-}
-
-void BTParser::setInput(istream* in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
-}
-
-void BTParser::consume(void)
-{
- current++;
- if((current == lookahead.size()) && !isSpeculating())
- {
- current = 0;
- lookahead.clear();
- }
- sync(1);
-}
-
-void BTParser::sync(unsigned int i)
-{
- unsigned int next_index = current + i - 1;
- unsigned int max_index = (lookahead.size() == 0) ? 0 : (lookahead.size() - 1);
- if( next_index >= max_index )
- {
- fill( next_index - max_index);
- }
-}
-
-void BTParser::fill(unsigned int n)
-{
- unsigned int i = 0;
- for (i = 0; i <= n; i++)
- {
- lookahead.push_back( lexer->next() );
- }
-}
-
-void BTParser::match(TokenType_T type)
-{
- if( lookaheadType(1) == type )
- {
- consume();
- }
- else
- {
- Token& tok = lookaheadToken(1);
- ostringstream oss;
- oss << "Expected token type. Expected " << type << ", received " << tok.type() << ".";
- Exception ex( tok.line(), tok.column() );
- ex.setMessage(oss.str());
- }
-}
-
-Token& BTParser::lookaheadToken(unsigned int i)
-{
- sync(i);
- return lookahead.at( current + i - 1 );
-}
-
-TokenType_T BTParser::lookaheadType(unsigned int i)
-{
- return lookaheadToken(i).type();
-}
-
-unsigned int BTParser::mark(void)
-{
- markers.push_back(current);
- return current;
-}
-
-void BTParser::release(void)
-{
- unsigned int marker = markers.back();
- markers.pop_back();
- seek(marker);
-}
-
-void BTParser::seek(unsigned int index)
-{
- current = index;
-}
-
-bool BTParser::isSpeculating(void)
-{
- return (markers.size() > 0);
-}
-
+++ /dev/null
-#ifndef BT_PARSER_H
-#define BT_PARSER_H
-
-#include <exception>
-#include <vector>
-#include "iparser.h"
-#include "ilexer.h"
-#include "ast.h"
-
-class BTParser : public IParser
-{
- private:
- ILexer* lexer;
- unsigned int current;
- std::vector<unsigned int> markers;
- std::vector<Token> lookahead;
- public:
- BTParser(ILexer* lxer);
- ~BTParser();
-
- void setInput(char* in);
- void setInput(string& in);
- void setInput(istream* in);
-
- void consume(void);
- void sync(unsigned int i);
- void fill(unsigned int n);
- void match(TokenType_T type);
- Token& lookaheadToken(unsigned int i);
- TokenType_T lookaheadType(unsigned int i);
- unsigned int mark(void);
- void release(void);
- void seek(unsigned int index);
- bool isSpeculating(void);
-
- virtual AST* parse(void) = 0;
-};
-
-#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 "iparser.h"
-#include "cork.h"
-
-using namespace std;
-
-/******************************************************************************
- * Public Functions
- *****************************************************************************/
-IParser::IParser() : input(NULL)
-{
-}
-
-IParser::~IParser()
-{
-}
-
-void IParser::setInput(char* in)
-{
- input = _new istringstream( string( in ) );
-}
-
-void IParser::setInput(string& in)
-{
- input = _new istringstream( in );
-}
-
-void IParser::setInput(istream* in)
-{
- input = in;
-}
-
-
+++ /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 <sstream>
-#include "ast.h"
-#include "ivisitor.h"
-
-using namespace std;
-
-class IParser {
- private:
- istream* input;
- public:
- IParser();
- virtual ~IParser();
- virtual AST* parse() = 0;
-
- void setInput(char* in);
- void setInput(string& in);
- void setInput(istream* in);
-};
-
-#endif
+++ /dev/null
-#include "llkparser.h"
-#include "exception.h"
-#include "cork.h"
-
-LLKParser::LLKParser(int k_val, ILexer* lxer) : k(k_val), next(0), lexer(lxer)
-{
- if ( lexer != NULL )
- {
- lookahead = new Token[k];
- }
- else
- {
- throw std::exception();
- }
-}
-
-LLKParser::~LLKParser()
-{
- if(lexer != NULL)
- {
- delete lexer;
- // Input stream was deleted with th elexer so null it out
- IParser::setInput((istream*)NULL);
- }
- if (lookahead != NULL)
- {
- delete[] lookahead;
- }
-}
-
-void LLKParser::setInput(char* in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
- for (int i = 0; i < k; i++)
- {
- consume();
- }
-}
-
-void LLKParser::setInput(string& in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
- for (int i = 0; i < k; i++)
- {
- consume();
- }
-}
-
-void LLKParser::setInput(istream* in)
-{
- IParser::setInput(in);
- lexer->setInput(in);
- for (int i = 0; i < k; i++)
- {
- consume();
- }
-}
-
-void LLKParser::consume(void)
-{
- if ( lookahead != NULL )
- {
- lookahead[next] = lexer->next();
- next = (next + 1) % k;
- }
-}
-
-void LLKParser::match(TokenType_T type)
-{
- if( lookaheadType(1) == type )
- {
- consume();
- }
- else
- {
- throw std::exception();
- }
-}
-
-Token& LLKParser::lookaheadToken(int i)
-{
- Token& ret = lookahead[(next + i - 1) % k];
- return ret;
-}
-
-TokenType_T LLKParser::lookaheadType(int i)
-{
- TokenType_T ret = EOF;
- if( lookahead != NULL )
- {
- ret = lookaheadToken(i).type();
- }
- return ret;
-}
-
+++ /dev/null
-#ifndef LLK_PARSER_H
-#define LLK_PARSER_H
-
-#include <exception>
-#include "iparser.h"
-#include "ilexer.h"
-#include "ast.h"
-
-class LLKParser : public IParser
-{
- private:
- int k;
- int next;
- ILexer* lexer;
- Token* lookahead;
- public:
- LLKParser(int k_val, ILexer* lxer);
- ~LLKParser();
-
- void setInput(char* in);
- void setInput(string& in);
- void setInput(istream* in);
-
- void consume(void);
- void match(TokenType_T type);
- Token& lookaheadToken(int i);
- TokenType_T lookaheadType(int i);
- virtual AST* parse(void) = 0;
-};
-
-#endif
+++ /dev/null
-#include "ivisitor.h"
-#include <list>
-
-using namespace std;
-
-void IVisitor::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 IVisitor {
- protected:
- AST* ast;
- public:
- IVisitor(AST* tree) : ast(tree) {};
- ~IVisitor() { delete ast; }
- void visit(AST* cur = NULL, int depth = 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 IVisitorFactory {
- public:
- virtual IVisitor* createIVisitor(AST* root) = 0;
-};
-
-#endif