Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nbingham1 committed Dec 5, 2024
0 parents commit 1c56710
Show file tree
Hide file tree
Showing 11 changed files with 1,239 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.o
*.d
*.a
*.so
test_*
674 changes: 674 additions & 0 deletions COPYRIGHT

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
NAME = parse_cog
DEPEND = parse_expression parse_ucs parse common

SRCDIR = $(NAME)
TESTDIR = tests
GTEST := ../../googletest
GTEST_I := -I$(GTEST)/googletest/include -I.
GTEST_L := -L$(GTEST)/build/lib -L.

CXXFLAGS = -std=c++17 -O2 -g -Wall -fmessage-length=0 $(DEPEND:%=-I../%) -I.
LDFLAGS =

SOURCES := $(shell mkdir -p $(SRCDIR); find $(SRCDIR) -name '*.cpp')
OBJECTS := $(SOURCES:%.cpp=build/%.o)
DEPS := $(shell mkdir -p build/$(SRCDIR); find build/$(SRCDIR) -name '*.d')
TARGET = lib$(NAME).a

TESTS := $(shell mkdir -p $(TESTDIR); find $(TESTDIR) -name '*.cpp')
TEST_OBJECTS := $(TESTS:%.cpp=build/%.o) build/$(TESTDIR)/gtest_main.o
TEST_DEPS := $(shell mkdir -p build/$(TESTDIR); find build/$(TESTDIR) -name '*.d')
TEST_TARGET = test

ifeq ($(OS),Windows_NT)
CXXFLAGS += -D WIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CXXFLAGS += -D AMD64
else
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CXXFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CXXFLAGS += -D IA32
endif
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CXXFLAGS += -D LINUX
endif
ifeq ($(UNAME_S),Darwin)
CXXFLAGS += -D OSX -mmacos-version-min=12.0
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CXXFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CXXFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CXXFLAGS += -D ARM
endif
endif


all: lib

lib: $(TARGET)

tests: lib $(TEST_TARGET)

$(TARGET): $(OBJECTS)
ar rvs $(TARGET) $(OBJECTS)

build/$(SRCDIR)/%.o: $(SRCDIR)/%.cpp
@mkdir -p $(dir $@)
@$(CXX) $(CXXFLAGS) $(LDFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -MT $@ -c $<
$(CXX) $(CXXFLAGS) $(LDFLAGS) -c -o $@ $<

$(TEST_TARGET): $(TEST_OBJECTS)
$(CXX) $(CXXFLAGS) $(GTEST_L) $^ -pthread -l$(NAME) -lgtest -o $(TEST_TARGET)

build/$(TESTDIR)/%.o: $(TESTDIR)/%.cpp
@mkdir -p $(dir $@)
@$(CXX) $(CXXFLAGS) $(GTEST_I) -MM -MF $(patsubst %.o,%.d,$@) -MT $@ -c $<
$(CXX) $(CXXFLAGS) $(GTEST_I) $< -c -o $@

build/$(TESTDIR)/gtest_main.o: $(GTEST)/googletest/src/gtest_main.cc
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(GTEST_I) $< -c -o $@

include $(DEPS) $(TEST_DEPS)

clean:
rm -rf build $(TARGET) $(TEST_TARGET)
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# parse_cog

This library provides a parser for COG.

## License

Licensed by Broccoli, LLC under GNU GPL v3.

Written by Ned Bingham.
Copyright © 2024 Broccoli, LLC.

Loom 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.

Loom 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.

A copy of the GNU General Public License may be found in COPYRIGHT.
Otherwise, see <https://www.gnu.org/licenses/>.

45 changes: 45 additions & 0 deletions parse_cog/branch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "branch.h"

#include "composition.h"
#include "control.h"

namespace parse_cog {

branch::branch()
{

}

branch::branch(composition sub)
{
this->sub = std::shared_ptr<composition>(new composition(sub));
}

branch::branch(control ctrl)
{
this->ctrl = std::shared_ptr<control>(new control(ctrl));
}

branch::branch(assignment assign)
{
this->assign = assign;
}

branch::~branch()
{

}

string branch::to_string(int level, string tab) const
{
if (sub and sub->valid) {
return sub->to_string(level, tab);
} else if (ctrl and ctrl->valid) {
return ctrl->to_string(tab);
} else if (assign.valid) {
return assign.to_string(tab);
}
return "skip";
}

}
31 changes: 31 additions & 0 deletions parse_cog/branch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <parse/parse.h>
#include <parse/syntax.h>
#include <parse_expression/assignment.h>

#include <memory>

namespace parse_cog
{
using parse_expression::assignment;

struct composition;
struct control;

struct branch
{
branch();
branch(composition sub);
branch(control ctrl);
branch(assignment assign);
~branch();

std::shared_ptr<composition> sub;
std::shared_ptr<control> ctrl;
assignment assign;

string to_string(int level, string tab) const;
};

}
159 changes: 159 additions & 0 deletions parse_cog/composition.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#include "composition.h"

#include <parse/default/symbol.h>
#include <parse/default/number.h>
#include <parse/default/white_space.h>
#include <parse/default/new_line.h>

#include "branch.h"
#include "control.h"

namespace parse_cog
{

composition::composition()
{
debug_name = "composition";
level = 0;
}

composition::composition(tokenizer &tokens, int level, void *data)
{
debug_name = "composition";
this->level = level;
parse(tokens, data);
}

composition::~composition()
{
}

void composition::parse(tokenizer &tokens, void *data)
{
tokens.syntax_start(this);

bool first = true;
do {
if (first) {
first = false;
} else {
tokens.next();
}

tokens.increment(false);
if (level == 0) {
tokens.expect(";");
tokens.expect<parse::new_line>();
} else if (level == 1) {
tokens.expect("or");
} else if (level == 2) {
tokens.expect("xor");
} else if (level == 3) {
tokens.expect("and");
}

tokens.increment(true);
if (level < 3) {
tokens.expect<composition>();
} else {
tokens.expect<control>();
tokens.expect<assignment>();
tokens.expect("{");
tokens.expect("skip");
}

if (tokens.decrement(__FILE__, __LINE__, data)) {
if (tokens.found<composition>()) {
branches.push_back(branch(composition(tokens, level+1, data)));
} else if (tokens.found<control>()) {
branches.push_back(branch(control(tokens, data)));
} else if (tokens.found<assignment>()) {
branches.push_back(branch(assignment(tokens, data)));
} else if (tokens.found("skip")) {
tokens.next();
} else if (tokens.found("{")) {
tokens.next();

tokens.increment(true);
tokens.expect("}");

tokens.increment(true);
tokens.expect<composition>();

if (tokens.decrement(__FILE__, __LINE__, data)) {
branches.push_back(branch(composition(tokens, 0, data)));
}

if (tokens.decrement(__FILE__, __LINE__, data)) {
tokens.next();
}
}
}
} while (tokens.decrement(__FILE__, __LINE__, data));

tokens.syntax_end(this);
}

bool composition::is_next(tokenizer &tokens, int i, void *data)
{
return tokens.is_next("skip")
or tokens.is_next("{", i)
or control::is_next(tokens, i, data)
or assignment::is_next(tokens, i, data);
}

void composition::register_syntax(tokenizer &tokens)
{
if (!tokens.syntax_registered<composition>())
{
tokens.register_syntax<composition>();
tokens.register_token<parse::symbol>();
tokens.register_token<parse::white_space>(false);
tokens.register_token<parse::new_line>(true);
control::register_syntax(tokens);
assignment::register_syntax(tokens);
}
}

string composition::to_string(string tab) const
{
return to_string(-1, tab);
}

string composition::to_string(int prev_level, string tab) const
{
if (!valid || branches.empty())
return "skip";

string result = "";
if (prev_level > level)
result += "{";

for (auto branch = branches.begin(); branch != branches.end(); branch++) {
if (branch != branches.begin()) {
if (level == 0) {
result += "\n";
} else if (level == 1) {
result += "or";
} else if (level == 2) {
result += "xor";
} else if (level == 3) {
result += "and";
}
}

result += branch->to_string(level, tab);
}

if (prev_level > level)
result += "}";

return result;
}

parse::syntax *composition::clone() const
{
return new composition(*this);
}

}
30 changes: 30 additions & 0 deletions parse_cog/composition.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <parse/parse.h>
#include <parse/syntax.h>

#include "branch.h"

namespace parse_cog
{

struct composition : parse::syntax
{
composition();
composition(tokenizer &tokens, int level = 0, void *data = NULL);
~composition();

vector<parse_cog::branch> branches;
int level;

void parse(tokenizer &tokens, void *data = NULL);
static bool is_next(tokenizer &tokens, int i = 1, void *data = NULL);
static void register_syntax(tokenizer &tokens);

string to_string(string tab = "") const;
string to_string(int prev_level, string tab = "") const;
parse::syntax *clone() const;
};

}

Loading

0 comments on commit 1c56710

Please sign in to comment.