From 18d2886d74a77a953353448de3f3a790009a527b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Mon, 3 Feb 2014 20:13:41 +0100 Subject: [PATCH] Sync with master --- .gitignore | 15 +- acat/makefile | 20 ++ acat/src/acat.cpp | 97 +++--- aconvert.automaton/makefile | 20 ++ aconvert.automaton/src/AutomatonParser.cpp | 75 +++++ aconvert.automaton/src/AutomatonParser.h | 18 ++ aconvert.automaton/src/AutomatonPrinter.cpp | 60 ++++ aconvert.automaton/src/AutomatonPrinter.h | 17 ++ aconvert.automaton/src/aconvert.automaton.cpp | 93 ++++++ aconvert.dot/.cproject | 132 +++++++++ aconvert.dot/.project | 27 ++ aconvert.dot/makefile | 20 ++ .../src/DotConverter.cpp | 36 +-- aconvert.dot/src/DotConverter.h | 31 ++ aconvert.dot/src/aconvert.dot.cpp | 43 +++ aconvert.gastex/.cproject | 133 +++++++++ aconvert.gastex/.project | 27 ++ aconvert.gastex/makefile | 20 ++ aconvert.gastex/src/GasTexConverter.cpp | 202 +++++++++++++ aconvert.gastex/src/GasTexConverter.h | 33 +++ aconvert.gastex/src/aconvert.gastex.cpp | 44 +++ aconvert.grammar/.cproject | 127 ++++++++ aconvert.grammar/.project | 27 ++ aconvert.grammar/makefile | 20 ++ aconvert.grammar/src/GrammarPrinter.cpp | 47 +++ aconvert.grammar/src/GrammarPrinter.h | 21 ++ aconvert.grammar/src/aconvert.grammar.cpp | 34 +++ aconvert.regexp/makefile | 20 ++ aconvert.regexp/src/RegExpLexer.cpp | 60 ++++ aconvert.regexp/src/RegExpLexer.h | 35 +++ aconvert.regexp/src/RegExpParser.cpp | 109 +++++++ aconvert.regexp/src/RegExpParser.h | 40 +++ aconvert.regexp/src/RegExpPrinter.cpp | 86 ++++++ aconvert.regexp/src/RegExpPrinter.h | 28 ++ aconvert.regexp/src/aconvert.regexp.cpp | 90 ++++++ aconvert/makefile | 20 ++ aconvert/src/DotConverter.h | 28 -- aconvert/src/aconvert.cpp | 112 ++++--- adeterminize.fsm/makefile | 20 ++ adeterminize.vpa/src/VPADeterminizer.cpp | 226 ++++++++++++++ adeterminize.vpa/src/VPADeterminizer.h | 28 ++ adeterminize.vpa/src/adeterminize.vpa.cpp | 34 +++ adeterminize.vpa2/src/VPADeterminizer2.cpp | 225 ++++++++++++++ adeterminize.vpa2/src/VPADeterminizer2.h | 28 ++ adeterminize.vpa2/src/adeterminize.vpa2.cpp | 34 +++ adeterminize.vpa3/src/VPADeterminizer3.cpp | 277 ++++++++++++++++++ adeterminize.vpa3/src/VPADeterminizer3.h | 34 +++ adeterminize.vpa3/src/adeterminize.vpa3.cpp | 34 +++ adeterminize/makefile | 20 ++ adeterminize/src/DeterminizationUtils.cpp | 1 + adeterminize/src/VPADeterminizationStructs.h | 77 +++++ adeterminize/src/VPADeterminizationUtils.cpp | 162 ++++++++++ adeterminize/src/VPADeterminizationUtils.h | 38 +++ adiff.automaton/makefile | 20 ++ adiff.automaton/src/AutomatonDiff.cpp | 131 +++++++++ adiff.automaton/src/AutomatonDiff.h | 27 ++ adiff.automaton/src/adiff.automaton.cpp | 43 +++ adiff.grammar/makefile | 20 ++ adiff.grammar/src/GrammarDiff.cpp | 94 ++++++ adiff.grammar/src/GrammarDiff.h | 27 ++ adiff.grammar/src/adiff.grammar.cpp | 43 +++ adiff/makefile | 20 ++ adiff/src/adiff.cpp | 70 +++++ aepsilon/makefile | 20 ++ aepsilon/src/EpsilonClosure.cpp | 14 +- aepsilon/src/EpsilonClosure.h | 4 +- aepsilon/src/EpsilonRemover.cpp | 39 ++- alib/makefile | 19 +- alib/src/AutomatonFactory.cpp | 10 + alib/src/AutomatonFactory.h | 14 +- alib/src/GrammarFactory.cpp | 12 + alib/src/GrammarFactory.h | 15 +- alib/src/RegExpFactory.cpp | 18 +- alib/src/RegExpFactory.h | 22 ++ alib/src/alphabet/Epsilon.cpp | 34 +++ alib/src/alphabet/Epsilon.h | 32 ++ alib/src/regexp/RegExpEmpty.cpp | 20 ++ alib/src/regexp/RegExpEmpty.h | 31 ++ alib/src/regexp/RegExpEpsilon.cpp | 20 ++ alib/src/regexp/RegExpEpsilon.h | 33 +++ alib/src/regexp/RegExpParser.cpp | 49 ++-- alib/src/regexp/RegExpParser.h | 6 +- alib/src/regexp/RegExpPrinter.cpp | 23 +- alib/src/regexp/RegExpPrinter.h | 4 + alib/src/std/istream.cpp | 27 ++ alib/src/std/istream.h | 4 + aminimize/makefile | 20 ++ aminimize/src/Minimize.cpp | 122 ++++++++ aminimize/src/Minimize.h | 19 ++ aminimize/src/aminimize.cpp | 61 ++++ atrim/src/TrimNFA.cpp | 25 +- atrim/src/TrimNFA.h | 2 +- examples/NFSM1.DET.xml | 60 ++++ examples/VPA1.xml | 67 +++++ examples/VPA2.xml | 71 +++++ examples/automaton/DFA.txt | 19 ++ examples/automaton/NFA.txt | 32 ++ examples/regexp/regexp4.xml | 24 ++ makefile | 49 ++++ 99 files changed, 4612 insertions(+), 229 deletions(-) create mode 100644 acat/makefile create mode 100644 aconvert.automaton/makefile create mode 100644 aconvert.automaton/src/AutomatonParser.cpp create mode 100644 aconvert.automaton/src/AutomatonParser.h create mode 100644 aconvert.automaton/src/AutomatonPrinter.cpp create mode 100644 aconvert.automaton/src/AutomatonPrinter.h create mode 100644 aconvert.automaton/src/aconvert.automaton.cpp create mode 100644 aconvert.dot/.cproject create mode 100644 aconvert.dot/.project create mode 100644 aconvert.dot/makefile rename {aconvert => aconvert.dot}/src/DotConverter.cpp (82%) create mode 100644 aconvert.dot/src/DotConverter.h create mode 100644 aconvert.dot/src/aconvert.dot.cpp create mode 100644 aconvert.gastex/.cproject create mode 100644 aconvert.gastex/.project create mode 100644 aconvert.gastex/makefile create mode 100644 aconvert.gastex/src/GasTexConverter.cpp create mode 100644 aconvert.gastex/src/GasTexConverter.h create mode 100644 aconvert.gastex/src/aconvert.gastex.cpp create mode 100644 aconvert.grammar/.cproject create mode 100644 aconvert.grammar/.project create mode 100644 aconvert.grammar/makefile create mode 100644 aconvert.grammar/src/GrammarPrinter.cpp create mode 100644 aconvert.grammar/src/GrammarPrinter.h create mode 100644 aconvert.grammar/src/aconvert.grammar.cpp create mode 100644 aconvert.regexp/makefile create mode 100644 aconvert.regexp/src/RegExpLexer.cpp create mode 100644 aconvert.regexp/src/RegExpLexer.h create mode 100644 aconvert.regexp/src/RegExpParser.cpp create mode 100644 aconvert.regexp/src/RegExpParser.h create mode 100644 aconvert.regexp/src/RegExpPrinter.cpp create mode 100644 aconvert.regexp/src/RegExpPrinter.h create mode 100644 aconvert.regexp/src/aconvert.regexp.cpp create mode 100644 aconvert/makefile delete mode 100644 aconvert/src/DotConverter.h create mode 100644 adeterminize.fsm/makefile create mode 100644 adeterminize.vpa/src/VPADeterminizer.cpp create mode 100644 adeterminize.vpa/src/VPADeterminizer.h create mode 100644 adeterminize.vpa/src/adeterminize.vpa.cpp create mode 100644 adeterminize.vpa2/src/VPADeterminizer2.cpp create mode 100644 adeterminize.vpa2/src/VPADeterminizer2.h create mode 100644 adeterminize.vpa2/src/adeterminize.vpa2.cpp create mode 100644 adeterminize.vpa3/src/VPADeterminizer3.cpp create mode 100644 adeterminize.vpa3/src/VPADeterminizer3.h create mode 100644 adeterminize.vpa3/src/adeterminize.vpa3.cpp create mode 100644 adeterminize/makefile create mode 100644 adeterminize/src/VPADeterminizationStructs.h create mode 100644 adeterminize/src/VPADeterminizationUtils.cpp create mode 100644 adeterminize/src/VPADeterminizationUtils.h create mode 100644 adiff.automaton/makefile create mode 100644 adiff.automaton/src/AutomatonDiff.cpp create mode 100644 adiff.automaton/src/AutomatonDiff.h create mode 100644 adiff.automaton/src/adiff.automaton.cpp create mode 100644 adiff.grammar/makefile create mode 100644 adiff.grammar/src/GrammarDiff.cpp create mode 100644 adiff.grammar/src/GrammarDiff.h create mode 100644 adiff.grammar/src/adiff.grammar.cpp create mode 100644 adiff/makefile create mode 100644 adiff/src/adiff.cpp create mode 100644 aepsilon/makefile create mode 100644 alib/src/alphabet/Epsilon.cpp create mode 100644 alib/src/alphabet/Epsilon.h create mode 100644 alib/src/regexp/RegExpEmpty.cpp create mode 100644 alib/src/regexp/RegExpEmpty.h create mode 100644 alib/src/regexp/RegExpEpsilon.cpp create mode 100644 alib/src/regexp/RegExpEpsilon.h create mode 100644 alib/src/std/istream.cpp create mode 100644 alib/src/std/istream.h create mode 100644 aminimize/makefile create mode 100644 aminimize/src/Minimize.cpp create mode 100644 aminimize/src/Minimize.h create mode 100644 aminimize/src/aminimize.cpp create mode 100644 examples/NFSM1.DET.xml create mode 100644 examples/VPA1.xml create mode 100644 examples/VPA2.xml create mode 100644 examples/automaton/DFA.txt create mode 100644 examples/automaton/NFA.txt create mode 100644 examples/regexp/regexp4.xml create mode 100644 makefile diff --git a/.gitignore b/.gitignore index 764a08db2b..9fb9db37f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,9 @@ # Eclipse workspace data .metadata/ **/Debug +**/Debug* **/Release - - -# Doxygen -Doxyfile -doc/ +**/Release* # Compiled Object files *.slo @@ -25,3 +22,11 @@ doc/ # vim backup and swap files *~ *.swp + +# Doxygen documentation +Doxyfile +documentation/* + +bin/* +**/bin +**/obj diff --git a/acat/makefile b/acat/makefile new file mode 100644 index 0000000000..6ade75d926 --- /dev/null +++ b/acat/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=acat +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/acat/src/acat.cpp b/acat/src/acat.cpp index f1ab25b513..e2b2cac849 100644 --- a/acat/src/acat.cpp +++ b/acat/src/acat.cpp @@ -6,22 +6,21 @@ #include <iostream> #include <string> #include <set> - +#include <cstdlib> +#include <unistd.h> +#include <exception> #include "AutomatonFactory.h" #include "GrammarFactory.h" #include "AlibException.h" - #include "regexp/RegExpParser.h" - #include "automaton/AutomatonParser.h" #include "grammar/GrammarParser.h" -#include "grammar/RightRegularGrammar.h" - #include "sax/SaxInterface.h" - #include "sax/ParserException.h" -#include <exception> + +#define VERSION "0.0.1" +#define USAGE "Usage: catPDA [-c] [input]"; using namespace std; using namespace automaton; @@ -34,69 +33,61 @@ void getAutomaton(list<Token>& tokens, bool complexTypes) { UnknownAutomaton automaton = AutomatonParser::parse(tokens); if(complexTypes) { - Automaton* concreateAutomaton = AutomatonFactory::buildAutomaton(automaton); - concreateAutomaton->toXML(cout); + Automaton* concreteAutomaton = AutomatonFactory::buildAutomaton(automaton); + cout << *concreteAutomaton; } else { - automaton.toXML(cout); + cout << automaton; } } void getGrammar(list<Token>& tokens) { UnknownGrammar grammar = GrammarParser::parse(tokens); - grammar.toXML(cout); + cout << grammar; } void getRegExp(list<Token>& tokens) { RegExp regexp = RegExpParser::parse(tokens); - regexp.toXML(cout); + cout << regexp; } int main(int argc, char** argv) { - - int fileParameterIndex = -1; - bool complexTypes = false; - - try { - if (argc > 1) { - for (int i = 1; i < argc; i++) { - if (string("-h").compare(argv[i]) == 0) { - cout << "Automaton parsing.\nUsage: catPDA [automaton.xml]\n"; - return -1; - } else if (string("-c").compare(argv[i]) == 0) { - complexTypes = true; - } else { - if(fileParameterIndex == -1) { - fileParameterIndex = i; - } else { - throw AlibException("Only one file can be passed as parameter - " + string(argv[i]) + " " + string(argv[fileParameterIndex])); - } - } - } - } - - list<Token> tokens; - - if(fileParameterIndex != -1) { - SaxInterface::parseFile(argv[fileParameterIndex],tokens); - } else { - string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); - SaxInterface::parseMemory(input, tokens); + if(argc == 2 && string(argv[1])=="-v" ) { + cout << argv[0] << " version " << VERSION << "\n"; + cout << USAGE; + cout << endl; + return EXIT_SUCCESS; } - if (tokens.front().getData() == "automaton") { - getAutomaton(tokens, complexTypes); - } else if (tokens.front().getData() == "grammar") { - getGrammar(tokens); - } else if (tokens.front().getData() == "regexp") { - getRegExp(tokens); - } else { - throw AlibException("Expected root tag automaton, grammar or regexp. Read: " + tokens.front().getData()); + bool concrete = false; + + int i=getopt(argc, argv, "t:"); + while(i!=-1) { + switch(i){ + case 'c': + concrete = true; + break; + default: + optind--; + break; } + i=getopt(argc, argv, "t:"); + } - } catch (AlibException& e) { - cout << e.what() << endl; - return -1; + list<Token> tokens; + if(optind == argc) { + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + SaxInterface::parseMemory(input, tokens); + } else { + SaxInterface::parseFile(argv[optind],tokens); } - cout.flush(); + if (tokens.front().getData() == "automaton") { + getAutomaton(tokens, concrete); + } else if (tokens.front().getData() == "grammar") { + getGrammar(tokens); + } else if (tokens.front().getData() == "regexp") { + getRegExp(tokens); + } else { + throw AlibException( "Expected root tag automaton, grammar or regexp. Read: " + tokens.front().getData()); + } } diff --git a/aconvert.automaton/makefile b/aconvert.automaton/makefile new file mode 100644 index 0000000000..eca1f70d08 --- /dev/null +++ b/aconvert.automaton/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert.automaton +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert.automaton/src/AutomatonParser.cpp b/aconvert.automaton/src/AutomatonParser.cpp new file mode 100644 index 0000000000..c672bcbae8 --- /dev/null +++ b/aconvert.automaton/src/AutomatonParser.cpp @@ -0,0 +1,75 @@ +#include "AutomatonParser.h" +#include "std/istream.h" +#include <string> +#include <sstream> +#include <vector> +#include <algorithm> + +#include "alphabet/Symbol.h" + +AutomatonParser::AutomatonParser(std::istream& in) : m_In(in) { + +} + +automaton::FSM AutomatonParser::parse() { + automaton::FSM res = automaton::FSM(); + std::string headerLine; + std::getline(m_In, headerLine); + + std::stringstream header(headerLine); + if(!(header >> "NFA") && !(header.clear(), header >> "DFA")) { + throw ParseError(); + } + + std::string alpha; + std::vector<alphabet::Symbol> symbols; + while(header >> alpha) { + if(alpha != "\\eps") { + res.addInputSymbol(alphabet::Symbol(alpha)); + symbols.push_back(alphabet::Symbol(alpha)); + } else { + symbols.push_back(alphabet::Symbol("")); + } + } + + std::string line; + while(std::getline(m_In, line)) { + bool initial = false; + bool final = false; + + std::stringstream linestream(line); + + if(linestream >> ">") initial = true; + else linestream.clear(); + if(linestream >> "<") final = true; + else linestream.clear(); + + std::string from; + linestream >> from; + + if(res.getStates().find(from) == res.getStates().end()) res.addState(from); + if(initial) res.addInitialState(from); + if(final) res.addFinalState(from); + + std::vector<alphabet::Symbol>::const_iterator iter = symbols.begin(); + std::string to; + while(linestream >> to) { + if(iter == symbols.end()) throw ParseError(); + if(to != "-") { + + std::replace(to.begin(), to.end(), '|', ' '); + std::stringstream states(to); + std::string state; + while(states >> state) { + if(res.getStates().find(state) == res.getStates().end()) res.addState(state); + + res.addTransition(from, *iter, state); + } + + } + iter++; + } + } + + return res; +} \ No newline at end of file diff --git a/aconvert.automaton/src/AutomatonParser.h b/aconvert.automaton/src/AutomatonParser.h new file mode 100644 index 0000000000..599ae24513 --- /dev/null +++ b/aconvert.automaton/src/AutomatonParser.h @@ -0,0 +1,18 @@ +#ifndef __AUTOMATON_PARSER__ +#define __AUTOMATON_PARSER__ + +#include "automaton/FSM/FSM.h" + +class ParseError { + +}; + +class AutomatonParser { + std::istream& m_In; +public: + AutomatonParser(std::istream&); + automaton::FSM parse(); + +}; + +#endif \ No newline at end of file diff --git a/aconvert.automaton/src/AutomatonPrinter.cpp b/aconvert.automaton/src/AutomatonPrinter.cpp new file mode 100644 index 0000000000..a63c7f8673 --- /dev/null +++ b/aconvert.automaton/src/AutomatonPrinter.cpp @@ -0,0 +1,60 @@ +#include "AutomatonPrinter.h" + +AutomatonPrinter::AutomatonPrinter(std::ostream& out) : m_Out(out) { + +} + +void AutomatonPrinter::printStateSymbolTo(automaton::FSM& automaton, automaton::State from, alphabet::Symbol input) { + bool sign = false; + for(auto iterTransitions = automaton.getTransitions().begin(); iterTransitions != automaton.getTransitions().end(); iterTransitions++) { + if(iterTransitions->getFrom() == from && iterTransitions->getInput() == input) { + m_Out << (sign ? "|" : " ") << iterTransitions->getTo().getName(); + sign = true; + } + } + if(!sign) { + m_Out << " -"; + } +} + +void AutomatonPrinter::print(automaton::FSM& automaton) { + + if(automaton.isDeterministic()) { + m_Out << "DFA"; + } else { + m_Out << "NFA"; + } + + for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { + m_Out << " " << iterSymbol->getSymbol(); + } + + bool isEpsilonFreeSign = automaton.isEpsilonFree(); + if(!isEpsilonFreeSign) { + m_Out << " \\eps"; + } + + m_Out << std::endl; + + for(auto iterState = automaton.getStates().begin(); iterState != automaton.getStates().end(); iterState++) { + if(automaton.getInitialStates().find(*iterState) != automaton.getInitialStates().end()) { + m_Out << ">"; + } + if(automaton.getFinalStates().find(*iterState) != automaton.getFinalStates().end()) { + m_Out << "<"; + } + m_Out << iterState->getName(); + + for(auto iterSymbol = automaton.getInputAlphabet().begin(); iterSymbol != automaton.getInputAlphabet().end(); iterSymbol++) { + printStateSymbolTo(automaton, *iterState, *iterSymbol); + } + + if(!isEpsilonFreeSign) { + printStateSymbolTo(automaton, *iterState, alphabet::Symbol("")); + } + + m_Out << std::endl; + } + +} + diff --git a/aconvert.automaton/src/AutomatonPrinter.h b/aconvert.automaton/src/AutomatonPrinter.h new file mode 100644 index 0000000000..7f41357fec --- /dev/null +++ b/aconvert.automaton/src/AutomatonPrinter.h @@ -0,0 +1,17 @@ +#ifndef AUTOMATON_PRINTER_H_ +#define AUTOMATON_PRINTER_H_ + +#include <iostream> +#include "automaton/FSM/FSM.h" + +class AutomatonPrinter { + std::ostream& m_Out; + + void printStateSymbolTo(automaton::FSM& automaton, automaton::State from, alphabet::Symbol input); + +public: + AutomatonPrinter(std::ostream& out); + void print(automaton::FSM& automaton); +}; + +#endif /* AUTOMATON_PRINTER_H_ */ \ No newline at end of file diff --git a/aconvert.automaton/src/aconvert.automaton.cpp b/aconvert.automaton/src/aconvert.automaton.cpp new file mode 100644 index 0000000000..2b23de63b6 --- /dev/null +++ b/aconvert.automaton/src/aconvert.automaton.cpp @@ -0,0 +1,93 @@ +#include <iostream> +#include <fstream> +#include "AutomatonParser.h" +#include "AutomatonPrinter.h" + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> + +#include "automaton/FSM/FSM.h" +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" + +#define FROM 1 +#define TO 2 + +int fromAutomaton(std::istream& in, std::ostream& out) { + AutomatonParser parser(in); + + automaton::FSM result = parser.parse(); + + out << result; + + return 0; +} + +int toAutomaton(std::istream& in, std::ostream& out) { + + try { + + automaton::UnknownAutomaton automaton = automaton::AutomatonFactory::fromStream(in); + if(!automaton::AutomatonFactory::isFSM(automaton)) { + std::cerr << "Automaton minimize require deterministic finite automaton\n" << std::endl; + return 1; + } + automaton::FSM fsm = automaton::AutomatonFactory::buildFSM(automaton); + AutomatonPrinter printer = AutomatonPrinter(out); + printer.print(fsm); + + } catch (alib::AlibException& e) { + std::cerr << e.getCause() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, char* argv[]) { + + int fromTo = 0; + int c; + + while (1) { + static struct option long_options[] = { + {"from", no_argument, &fromTo, FROM}, + {"to", no_argument, &fromTo, TO}, + {0, 0, 0, 0} + }; + + int option_index = 0; + + c = getopt_long (argc, argv, "", long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: + break; + default: + optind--; + goto more; + } + } +more: + + std::istream* in = &std::cin; + if(optind != argc) in = new std::ifstream(argv[optind]); + + int res; + if(fromTo == FROM) { + res = fromAutomaton(*in, std::cout); + } else if(fromTo == TO) { + res = toAutomaton(*in, std::cout); + } else { + std::cerr << "error" << std::endl; + res = 1; + } + + if(c != -1) delete in; + return res; +} \ No newline at end of file diff --git a/aconvert.dot/.cproject b/aconvert.dot/.cproject new file mode 100644 index 0000000000..5f2482f118 --- /dev/null +++ b/aconvert.dot/.cproject @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.2062139078"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.2062139078" moduleId="org.eclipse.cdt.core.settings" name="Debug"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.2062139078" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.2062139078." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.286118695" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1348655222" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> + <builder buildPath="${workspace_loc:/aconvert.dot}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1555080851" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1494017337" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1656524610" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.402104271" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2003624661" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.include.paths.1598023120" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/src}""/> + <listOptionValue builtIn="false" value="libxml2"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1186367151" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1391892587" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1217626349" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.debug.option.debugging.level.1068602887" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1408764124" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1590802746" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1702518767" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> + <option id="gnu.cpp.link.option.paths.943614567" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/Debug}""/> + </option> + <option id="gnu.cpp.link.option.libs.1697970918" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> + <listOptionValue builtIn="false" value="xml2"/> + <listOptionValue builtIn="false" value="alib"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.773644316" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1515665326" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1254233161" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.886617893"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.886617893" moduleId="org.eclipse.cdt.core.settings" name="Release"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.886617893" name="Release" parent="cdt.managedbuild.config.gnu.exe.release"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.886617893." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.248721683" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1017471885" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> + <builder buildPath="${workspace_loc:/aconvert.dot}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1459381062" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1194836311" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.197021504" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.28725979" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.release.option.debugging.level.295390021" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.795391706" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.210646947" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release"> + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1131876208" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.release.option.debugging.level.12516513" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.94733664" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.131352154" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1485756614" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1625090592" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1409214020" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1118520950" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="aconvert.dot.cdt.managedbuild.target.gnu.exe.1503114349" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.886617893;cdt.managedbuild.config.gnu.exe.release.886617893.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.197021504;cdt.managedbuild.tool.gnu.cpp.compiler.input.795391706"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.886617893;cdt.managedbuild.config.gnu.exe.release.886617893.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.210646947;cdt.managedbuild.tool.gnu.c.compiler.input.94733664"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.2062139078;cdt.managedbuild.config.gnu.exe.debug.2062139078.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1656524610;cdt.managedbuild.tool.gnu.cpp.compiler.input.1186367151"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.2062139078;cdt.managedbuild.config.gnu.exe.debug.2062139078.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1391892587;cdt.managedbuild.tool.gnu.c.compiler.input.1408764124"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> + <storageModule moduleId="refreshScope"/> +</cproject> diff --git a/aconvert.dot/.project b/aconvert.dot/.project new file mode 100644 index 0000000000..7de074779e --- /dev/null +++ b/aconvert.dot/.project @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>aconvert.dot</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.core.ccnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/aconvert.dot/makefile b/aconvert.dot/makefile new file mode 100644 index 0000000000..7fc4f89013 --- /dev/null +++ b/aconvert.dot/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert.dot +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert/src/DotConverter.cpp b/aconvert.dot/src/DotConverter.cpp similarity index 82% rename from aconvert/src/DotConverter.cpp rename to aconvert.dot/src/DotConverter.cpp index d5bf21a5d4..baeb3a21d3 100644 --- a/aconvert/src/DotConverter.cpp +++ b/aconvert.dot/src/DotConverter.cpp @@ -2,7 +2,7 @@ * DotConverter.cpp * * Created on: Apr 1, 2013 - * Author: martin + * Author: Martin Zak */ #include "DotConverter.h" @@ -20,7 +20,7 @@ using namespace std; using namespace automaton; -void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) { +void DotConverter::convert(const Automaton& a, ostream& out) { out << "digraph automaton {\n"; out << "rankdir=LR;\n"; int cnt = 1; @@ -55,7 +55,7 @@ void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) { transitions(fsm, states, out); out << "}"; return; - } catch (const std::bad_cast& e) { + } catch (const bad_cast& e) { } try { @@ -63,7 +63,7 @@ void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) { transitions(pda, states, out); out << "}"; return; - } catch (const std::bad_cast& e) { + } catch (const bad_cast& e) { } try { @@ -71,19 +71,19 @@ void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) { transitions(tm, states, out); out << "}"; return; - } catch (const std::bad_cast& e) { + } catch (const bad_cast& e) { } } -void DotConverter::transitions(const automaton::FSM& fsm, const std::map<automaton::State, int>& states, - std::ostream& out) { +void DotConverter::transitions(const FSM& fsm, const map<State, int>& states, + ostream& out) { map<pair<int, int>, string> transitions; - const set<automaton::TransitionFSM>& t = fsm.getTransitions(); + const set<TransitionFSM>& t = fsm.getTransitions(); //put transitions from automaton to "transitions" - set<automaton::TransitionFSM>::const_iterator it = t.begin(); + set<TransitionFSM>::const_iterator it = t.begin(); while (it != t.end()) { string symbol; if (it->getInput().getSymbol().compare("") == 0) { @@ -112,13 +112,13 @@ void DotConverter::transitions(const automaton::FSM& fsm, const std::map<automat it2++; } } -void DotConverter::transitions(const automaton::PDA& pda, const std::map<automaton::State, int>& states, - std::ostream& out) { +void DotConverter::transitions(const PDA& pda, const map<State, int>& states, + ostream& out) { map<pair<int, int>, string> transitions; - const set<automaton::TransitionPDA>& t = pda.getTransitions(); + const set<TransitionPDA>& t = pda.getTransitions(); //put transitions from automaton to "transitions" - set<automaton::TransitionPDA>::const_iterator it = t.begin(); + set<TransitionPDA>::const_iterator it = t.begin(); while (it != t.end()) { string symbol; @@ -175,13 +175,13 @@ void DotConverter::transitions(const automaton::PDA& pda, const std::map<automat } } -void DotConverter::transitions(const automaton::TM& tm, const std::map<automaton::State, int>& states, - std::ostream& out) { +void DotConverter::transitions(const TM& tm, const map<State, int>& states, + ostream& out) { map<pair<int, int>, string> transitions; - const set<automaton::TransitionTM>& t = tm.getTransitions(); + const set<TransitionTM>& t = tm.getTransitions(); //put transitions from automaton to "transitions" - set<automaton::TransitionTM>::const_iterator it = t.begin(); + set<TransitionTM>::const_iterator it = t.begin(); while (it != t.end()) { string symbol; @@ -190,7 +190,7 @@ void DotConverter::transitions(const automaton::TM& tm, const std::map<automaton symbol += "/"; symbol += it->getOutput().getSymbol(); symbol += " "; - symbol += (std::string[] ) { "←", "→", "×" } [it->getShift()]; + symbol += (string[] ) { "←", "→", "×" } [it->getShift()]; //Insert into map pair<int, int> key(states.find(it->getFrom())->second, states.find(it->getTo())->second); diff --git a/aconvert.dot/src/DotConverter.h b/aconvert.dot/src/DotConverter.h new file mode 100644 index 0000000000..a7794d9137 --- /dev/null +++ b/aconvert.dot/src/DotConverter.h @@ -0,0 +1,31 @@ +/* + * DotConverter.h + * + * Created on: Apr 1, 2013 + * Author: Martin Zak + */ + +#ifndef DOTCONVERTER_H_ +#define DOTCONVERTER_H_ + +#include<ostream> + +#include <automaton/FSM/FSM.h> +#include <automaton/PDA/PDA.h> +#include <automaton/TM/TM.h> +#include <map> +#include <utility> + +using namespace std; +using namespace automaton; + +class DotConverter { +protected: + static void transitions(const FSM& fsm, const map<State, int>& states, ostream& out); + static void transitions(const PDA& pda, const map<State, int>& states, ostream& out); + static void transitions(const TM& tm, const map<State, int>& states, ostream& out); +public: + static void convert(const Automaton& a, ostream& out); +}; + +#endif /* DOTCONVERTER_H_ */ diff --git a/aconvert.dot/src/aconvert.dot.cpp b/aconvert.dot/src/aconvert.dot.cpp new file mode 100644 index 0000000000..bae9afd3d1 --- /dev/null +++ b/aconvert.dot/src/aconvert.dot.cpp @@ -0,0 +1,43 @@ +//============================================================================ +// Name : aconvert.dot.cpp +// Author : Martin Zak +//============================================================================ + +#include <iostream> +#include "automaton/AutomatonParser.h" +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "sax/SaxInterface.h" + +#include "DotConverter.h" + +#define VERSION "0.0.1" +#define USAGE "aconvert.dot [inputfile]" + +using namespace std; +using namespace automaton; +using namespace sax; +using namespace alib; + +int main(int argc, char** argv) { + list<Token> tokens; + + if (argc > 1) { + if (string(argv[1]) == "-v") { + cout << USAGE; + cout << endl; + return EXIT_SUCCESS; + } + SaxInterface::parseFile(argv[1], tokens); + + } else { + string input(istreambuf_iterator<char>(cin), + (istreambuf_iterator<char>())); + SaxInterface::parseMemory(input, tokens); + } + + UnknownAutomaton unknownAutomaton = AutomatonParser::parse(tokens); + Automaton* automaton = AutomatonFactory::buildAutomaton(unknownAutomaton); + DotConverter::convert(*automaton, cout); +} diff --git a/aconvert.gastex/.cproject b/aconvert.gastex/.cproject new file mode 100644 index 0000000000..5b1557e6d6 --- /dev/null +++ b/aconvert.gastex/.cproject @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.2062139078"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.2062139078" moduleId="org.eclipse.cdt.core.settings" name="Debug"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.2062139078" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.2062139078." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.286118695" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1348655222" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> + <builder buildPath="${workspace_loc:/aconvert.dot}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1555080851" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1494017337" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1656524610" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.402104271" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2003624661" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.include.paths.1598023120" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/src}""/> + <listOptionValue builtIn="false" value="libxml2"/> + </option> + <option id="gnu.cpp.compiler.option.other.other.514433026" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -std=c++11" valueType="string"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1186367151" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1391892587" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1217626349" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.debug.option.debugging.level.1068602887" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1408764124" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1590802746" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1702518767" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> + <option id="gnu.cpp.link.option.paths.943614567" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/Debug}""/> + </option> + <option id="gnu.cpp.link.option.libs.1697970918" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> + <listOptionValue builtIn="false" value="xml2"/> + <listOptionValue builtIn="false" value="alib"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.773644316" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1515665326" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1254233161" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.886617893"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.886617893" moduleId="org.eclipse.cdt.core.settings" name="Release"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.886617893" name="Release" parent="cdt.managedbuild.config.gnu.exe.release"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.886617893." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.248721683" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1017471885" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> + <builder buildPath="${workspace_loc:/aconvert.dot}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1459381062" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1194836311" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.197021504" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.28725979" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.release.option.debugging.level.295390021" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.795391706" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.210646947" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release"> + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1131876208" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.release.option.debugging.level.12516513" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.94733664" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.131352154" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1485756614" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1625090592" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1409214020" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1118520950" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="aconvert.dot.cdt.managedbuild.target.gnu.exe.1503114349" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.886617893;cdt.managedbuild.config.gnu.exe.release.886617893.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.197021504;cdt.managedbuild.tool.gnu.cpp.compiler.input.795391706"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.886617893;cdt.managedbuild.config.gnu.exe.release.886617893.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.210646947;cdt.managedbuild.tool.gnu.c.compiler.input.94733664"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.2062139078;cdt.managedbuild.config.gnu.exe.debug.2062139078.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1656524610;cdt.managedbuild.tool.gnu.cpp.compiler.input.1186367151"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.2062139078;cdt.managedbuild.config.gnu.exe.debug.2062139078.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1391892587;cdt.managedbuild.tool.gnu.c.compiler.input.1408764124"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> + <storageModule moduleId="refreshScope"/> +</cproject> diff --git a/aconvert.gastex/.project b/aconvert.gastex/.project new file mode 100644 index 0000000000..90bcd4bd65 --- /dev/null +++ b/aconvert.gastex/.project @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>aconvert.gastex</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.core.ccnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/aconvert.gastex/makefile b/aconvert.gastex/makefile new file mode 100644 index 0000000000..e9e21a20b5 --- /dev/null +++ b/aconvert.gastex/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert.gastex +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert.gastex/src/GasTexConverter.cpp b/aconvert.gastex/src/GasTexConverter.cpp new file mode 100644 index 0000000000..c84af4fec2 --- /dev/null +++ b/aconvert.gastex/src/GasTexConverter.cpp @@ -0,0 +1,202 @@ +/* + * GasTexConverter.cpp + * + * Created on: Jan 1, 2014 + * Author: Martin Zak + */ + +#include "GasTexConverter.h" + +#include <set> +#include <map> +#include <typeinfo> +#include "AlibException.h" + +using namespace std; + +void GasTexConverter::convert(const Automaton& a, ostream& out) { + out << "\\begin{center}\n"; + out << "\\begin{picture}(,)(,)\n"; + + for (auto& state : a.getStates()) { + bool initial = false; + bool final = false; + + if(a.getInitialStates().find(state) != a.getInitialStates().end()){ + initial = true; + } + if(a.getFinalStates().find(state) != a.getFinalStates().end()){ + final = true; + } + + if(initial || final) { + out << "\\node[Nmarks="; + if(initial){ + out << "i"; + } + if(final){ + out << "r"; + } + out<<"]("; + } else { + out <<"\\node("; + } + + out << state.getName(); + out << ")(,){"; + out << state.getName(); + out << "}\n"; + } + + try { + const FSM& fsm = dynamic_cast<const FSM&>(a); + transitions(fsm, out); + out << "\\end{center}\n"; + out << "\\end{picture}\n"; + return; + } catch (const bad_cast& e) { + } + + try { + const PDA& pda = dynamic_cast<const PDA&>(a); + transitions(pda, out); + out << "\\end{center}\n"; + out << "\\end{picture}\n"; + return; + } catch (const bad_cast& e) { + } + + try { + const TM& tm = dynamic_cast<const TM&>(a); + transitions(tm, out); + out << "\\end{center}\n"; + out << "\\end{picture}\n"; + return; + } catch (const bad_cast& e) { + } + + throw new alib::AlibException("Unknown automaton type!"); +} + + +string GasTexConverter::getStackSymbols(const list<Symbol>& stackSymbols) { + if (stackSymbols.size() == 0) { + return "$\\varepsilon$"; + } + + string symbols = ""; + int i=0; + for (auto& popSymbol : stackSymbols) { + if(i++ !=0) { + symbols +=" "; + } + symbols += popSymbol.getSymbol(); + } + return symbols; +} + +string GasTexConverter::checkEpsilon(const string& inputSymbol) { + if (inputSymbol.compare("") == 0) { + return "$\\varepsilon$"; + } else { + return inputSymbol; + } +} + +void GasTexConverter::printTransitionMap( + const map<pair<string, string>, string> transitionMap, ostream& out) { + for (auto& transition : transitionMap) { + string from = transition.first.first; + string to = transition.first.second; + string symbols = transition.second; + + if (from == to) { + out << "\\drawloop("; + out << from; + out << "){"; + out << symbols; + out << "}\n"; + + } else { + out << "\\drawedge("; + out << from; + out << ","; + out << to; + out << "){"; + out << symbols; + out << "}\n"; + } + } +} + +void GasTexConverter::transitions(const FSM& fsm, ostream& out) { + map<pair<string, string>, string> transitionMap; + for (auto& transition : fsm.getTransitions()) { + pair<string, string> key(transition.getFrom().getName(), transition.getTo().getName()); + auto mapIterator = transitionMap.find(key); + + string symbol = checkEpsilon(transition.getInput().getSymbol()); + + if (mapIterator == transitionMap.end()) { + transitionMap.insert( + pair<pair<string, string>, string>(key, symbol)); + } else { + mapIterator->second += "," + symbol; + } + } + printTransitionMap(transitionMap, out); +} + +void GasTexConverter::transitions(const PDA& pda, ostream& out) { + map<pair<string, string>, string> transitionMap; + + for (auto& transition : pda.getTransitions()) { + + pair<string, string> key(transition.getFrom().getName(), transition.getTo().getName()); + auto mapIterator = transitionMap.find(key); + + string symbol = checkEpsilon(transition.getInput().getSymbol()); + + symbol += ","; + + + symbol += getStackSymbols(transition.getPop()); + symbol += "/"; + symbol += getStackSymbols(transition.getPush()); + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(pair<pair<string, string>, string>(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + + printTransitionMap(transitionMap, out); + +} + +void GasTexConverter::transitions(const TM& tm, ostream& out) { + map<pair<string, string>, string> transitionMap; + + for (auto& transition : tm.getTransitions()) { + + pair<string, string> key(transition.getFrom().getName(), transition.getTo().getName()); + auto mapIterator = transitionMap.find(key); + + string symbol = checkEpsilon(transition.getInput().getSymbol()); + symbol += "/"; + symbol += checkEpsilon(transition.getOutput().getSymbol()); + symbol += ","; + symbol += (std::string[] ) { "$\\leftarrow$", "$\\rightarrow$", "$\\times$" } [transition.getShift()]; + + if (mapIterator == transitionMap.end()) { + transitionMap.insert(pair<pair<string, string>, string>(key, symbol)); + } else { + mapIterator->second += "; " + symbol; + } + } + + printTransitionMap(transitionMap, out); + +} + diff --git a/aconvert.gastex/src/GasTexConverter.h b/aconvert.gastex/src/GasTexConverter.h new file mode 100644 index 0000000000..b2cf1505a9 --- /dev/null +++ b/aconvert.gastex/src/GasTexConverter.h @@ -0,0 +1,33 @@ +/* + * GasTexConverter.h + * + * Created on: Jan 1, 2014 + * Author: Martin Zak + */ + +#ifndef GASTEXCONVERTER_H_ +#define GASTEXCONVERTER_H_ + +#include<ostream> +#include<map> +#include<utility> +#include"automaton/FSM/FSM.h" +#include"automaton/PDA/PDA.h" +#include"automaton/TM/TM.h" + +using namespace std; +using namespace automaton; + +class GasTexConverter { +private: + static void printTransitionMap( const map<pair<string, string>, string> transitionMap, ostream& out); + static string checkEpsilon(const string& inputSymbol); + static string getStackSymbols(const list<Symbol>& stackSymbols); + static void transitions(const FSM& fsm, ostream& out); + static void transitions(const PDA& pda, ostream& out); + static void transitions(const TM& tm, ostream& out); +public: + static void convert(const Automaton& a, ostream& out); +}; + +#endif /* GASTEXCONVERTER_H_ */ diff --git a/aconvert.gastex/src/aconvert.gastex.cpp b/aconvert.gastex/src/aconvert.gastex.cpp new file mode 100644 index 0000000000..3b9e52cdc0 --- /dev/null +++ b/aconvert.gastex/src/aconvert.gastex.cpp @@ -0,0 +1,44 @@ +//============================================================================ +// Name : aconvert.gastex.cpp +// Author : Martin Zak +//============================================================================ + +#include <iostream> +#include "automaton/AutomatonParser.h" +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "sax/SaxInterface.h" + +#include "GasTexConverter.h" + +#define VERSION "0.0.1" +#define USAGE "aconvert.gastex [inputfile]" + +using namespace std; +using namespace automaton; +using namespace sax; +using namespace alib; + +int main(int argc, char** argv) { + list<Token> tokens; + + if (argc > 1) { + if (string(argv[1]) == "-v") { + cout << USAGE; + cout << endl; + return EXIT_SUCCESS; + } + SaxInterface::parseFile(argv[1], tokens); + + } else { + string input(istreambuf_iterator<char>(cin), + (istreambuf_iterator<char>())); + SaxInterface::parseMemory(input, tokens); + } + + UnknownAutomaton unknownAutomaton = AutomatonParser::parse(tokens); + Automaton* automaton = AutomatonFactory::buildAutomaton(unknownAutomaton); + GasTexConverter::convert(*automaton, cout); + +} diff --git a/aconvert.grammar/.cproject b/aconvert.grammar/.cproject new file mode 100644 index 0000000000..c0b3d1801b --- /dev/null +++ b/aconvert.grammar/.cproject @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.64430919"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.64430919" moduleId="org.eclipse.cdt.core.settings" name="Debug"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.64430919" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.64430919." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1712690034" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.2101392019" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> + <builder buildPath="${workspace_loc:/aconvert.grammar}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1650545282" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1348825825" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1557767569" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1661291497" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1066675648" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.include.paths.228919629" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/src}""/> + <listOptionValue builtIn="false" value="/usr/include/libxml2"/> + </option> + <option id="gnu.cpp.compiler.option.other.other.31259776" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -std=c++11" valueType="string"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2079250197" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1620121719" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.437834220" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.debug.option.debugging.level.473346356" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1575412399" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.734179437" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1067778812" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> + <option id="gnu.cpp.link.option.libs.627858262" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> + <listOptionValue builtIn="false" value="alib"/> + </option> + <option id="gnu.cpp.link.option.paths.591596312" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/lib}""/> + <listOptionValue builtIn="false" value=""/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1424246647" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1611777659" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.376143327" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1121361280"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1121361280" moduleId="org.eclipse.cdt.core.settings" name="Release"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1121361280" name="Release" parent="cdt.managedbuild.config.gnu.exe.release"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.1121361280." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.970006224" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.45274759" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> + <builder buildPath="${workspace_loc:/aconvert.grammar}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.263112285" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.2117461476" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.478659920" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.1407098437" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> + <option id="gnu.cpp.compiler.exe.release.option.debugging.level.1198215692" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1899627218" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.941020788" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release"> + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1475736321" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.release.option.debugging.level.496505839" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.97518528" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.2003585585" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1240264067" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.381637236" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1129175057" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.353790346" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="aconvert.grammar.cdt.managedbuild.target.gnu.exe.1030518788" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1121361280;cdt.managedbuild.config.gnu.exe.release.1121361280.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.478659920;cdt.managedbuild.tool.gnu.cpp.compiler.input.1899627218"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.64430919;cdt.managedbuild.config.gnu.exe.debug.64430919.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1620121719;cdt.managedbuild.tool.gnu.c.compiler.input.1575412399"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.64430919;cdt.managedbuild.config.gnu.exe.debug.64430919.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1557767569;cdt.managedbuild.tool.gnu.cpp.compiler.input.2079250197"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1121361280;cdt.managedbuild.config.gnu.exe.release.1121361280.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.941020788;cdt.managedbuild.tool.gnu.c.compiler.input.97518528"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> + <storageModule moduleId="refreshScope"/> +</cproject> diff --git a/aconvert.grammar/.project b/aconvert.grammar/.project new file mode 100644 index 0000000000..3276fdeabb --- /dev/null +++ b/aconvert.grammar/.project @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>aconvert.grammar</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.core.ccnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/aconvert.grammar/makefile b/aconvert.grammar/makefile new file mode 100644 index 0000000000..80d67da8a0 --- /dev/null +++ b/aconvert.grammar/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert.grammar +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -I/usr/include/libxml2 +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert.grammar/src/GrammarPrinter.cpp b/aconvert.grammar/src/GrammarPrinter.cpp new file mode 100644 index 0000000000..3bfc672e3f --- /dev/null +++ b/aconvert.grammar/src/GrammarPrinter.cpp @@ -0,0 +1,47 @@ +#include "GrammarPrinter.h" + +using namespace std; +using namespace grammar; + +GrammarPrinter::GrammarPrinter( std::ostream& out ) : m_Out( out ) +{ + +} + +void GrammarPrinter::print( const grammar::Grammar & grammar ) +{ + // group by left side + map< list<Symbol>, set<Rule> > group; + for( const auto & r : grammar.getRules( ) ) + { + if( group.find( r.getLeftSide( ) ) != group.end( ) ) + group[ r.getLeftSide( ) ].insert( r ); + else + group.insert( std::pair< list<Symbol>, set<Rule> >( r.getLeftSide( ), set<Rule>( ) = { r } ) ); + } + + m_Out << "G = (N,T,P,S)" << endl; + + auto last = grammar.getNonTerminalSymbols( ).end( ); + last --; + m_Out << "N = {"; + for( auto it = grammar.getNonTerminalSymbols( ).begin( ) ; it != grammar.getNonTerminalSymbols( ).end( ) ; it++ ) + m_Out << it->getSymbol( ) << ( it != last ? ", " : "" ); + m_Out << "}" << endl; + + last = grammar.getTerminalSymbols( ).end( ); + last --; + m_Out << "T = {"; + for( auto it = grammar.getTerminalSymbols( ).begin( ) ; it != grammar.getTerminalSymbols( ).end( ) ; it++ ) + m_Out << it->getSymbol( ) << ( it != last ? ", " : "" ); + m_Out << "}" << endl; + + m_Out << "P = {" << endl; + for( const auto & g : group ) + for( const auto & r : g.second ) + m_Out << "\t" << r.toString( ) << endl; + m_Out << "}" << endl; + + m_Out << "S = " << grammar.getStartSymbol( ).getSymbol( ) << endl; +} + diff --git a/aconvert.grammar/src/GrammarPrinter.h b/aconvert.grammar/src/GrammarPrinter.h new file mode 100644 index 0000000000..725456c98e --- /dev/null +++ b/aconvert.grammar/src/GrammarPrinter.h @@ -0,0 +1,21 @@ +#ifndef GRAMMAR_PRINTER_H_ +#define GRAMMAR_PRINTER_H_ + +#include <iostream> +#include "grammar/Grammar.h" +#include "grammar/Rule.h" + +#include <map> +#include <list> +#include <set> + +class GrammarPrinter +{ + std::ostream& m_Out; + +public: + GrammarPrinter( std::ostream& out ); + void print( const grammar::Grammar & grammar ); +}; + +#endif /* GRAMMAR_PRINTER_H_ */ diff --git a/aconvert.grammar/src/aconvert.grammar.cpp b/aconvert.grammar/src/aconvert.grammar.cpp new file mode 100644 index 0000000000..633f3d8591 --- /dev/null +++ b/aconvert.grammar/src/aconvert.grammar.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <cstdlib> + +#include <GrammarFactory.h> +#include <AlibException.h> +#include <sax/SaxInterface.h> + +#include "GrammarPrinter.h" + + +#define VERSION "0.0.1" +#define USAGE "aconvert.grammar [inputfile]" + +using namespace grammar; +using namespace sax; +using namespace alib; + +int main(int argc, char** argv) +{ + try + { + string input( istreambuf_iterator<char>( cin ), ( istreambuf_iterator<char>( ) ) ); + + UnknownGrammar g = GrammarFactory::fromString( input ); + + GrammarPrinter printer( cout ); + printer.print( g ); + } + catch( AlibException & e ) + { + cout << e.what( ) << endl; + return 0; + } +} diff --git a/aconvert.regexp/makefile b/aconvert.regexp/makefile new file mode 100644 index 0000000000..39f1798c2c --- /dev/null +++ b/aconvert.regexp/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert.regexp +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert.regexp/src/RegExpLexer.cpp b/aconvert.regexp/src/RegExpLexer.cpp new file mode 100644 index 0000000000..e9642555f2 --- /dev/null +++ b/aconvert.regexp/src/RegExpLexer.cpp @@ -0,0 +1,60 @@ +#include "RegExpLexer.h" + +RegExpLexer::RegExpLexer(std::istream& in) : m_In(in) { + this->next(); +} + +RegExpLexer& RegExpLexer::next() { + char character; + +L0: + character = m_In.get(); + if(m_In.eof()) { + m_Current.type = TEOF; + return *this; + } else if(character == ' ' || character == '\n' || character == '\t') { + goto L0; + } else if((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9')) { + m_Current.type = SYMBOL; + m_Current.value = character; + return *this; + } else if(character == '(') { + m_Current.type = LPAR; + return *this; + } else if(character == ')') { + m_Current.type = RPAR; + return *this; + } else if(character == '+') { + m_Current.type = PLUS; + return *this; + } else if(character == '*') { + m_Current.type = STAR; + return *this; + } else if(character == '\\') { + goto L1; + } else { + m_In.unget(); + m_Current.type = ERROR; + return *this; + } +L1: + character = m_In.get(); + if(m_In.eof()) { + m_Current.type = ERROR; + return *this; + } else if(character == 'e') { + m_Current.type = EPS; + return *this; + } else if(character == '0') { + m_Current.type = EMPTY; + return *this; + } else { + m_In.unget(); + m_Current.type = ERROR; + return *this; + } +} + +RegExpLexer::Token RegExpLexer::token() { + return m_Current; +} \ No newline at end of file diff --git a/aconvert.regexp/src/RegExpLexer.h b/aconvert.regexp/src/RegExpLexer.h new file mode 100644 index 0000000000..7a047708ae --- /dev/null +++ b/aconvert.regexp/src/RegExpLexer.h @@ -0,0 +1,35 @@ +#ifndef __REG_EXP_LEXER__ +#define __REG_EXP_LEXER__ + +#include <string> +#include <iostream> + +class RegExpLexer { +public: + enum TokenType { + SYMBOL, + LPAR, + RPAR, + PLUS, + STAR, + EPS, + EMPTY, + TEOF, + ERROR + }; + + struct Token { + TokenType type; + std::string value; + }; +private: + std::istream& m_In; + Token m_Current; +public: + + RegExpLexer(std::istream&); + RegExpLexer& next(); + Token token(); +}; + +#endif \ No newline at end of file diff --git a/aconvert.regexp/src/RegExpParser.cpp b/aconvert.regexp/src/RegExpParser.cpp new file mode 100644 index 0000000000..cf070c07a5 --- /dev/null +++ b/aconvert.regexp/src/RegExpParser.cpp @@ -0,0 +1,109 @@ +#include "RegExpParser.h" + +RegExpParser::RegExpParser(RegExpLexer& lexer) : m_Lexer(lexer) { + +} + +regexp::RegExp* RegExpParser::parse() { + regexp::RegExpElement* element = this->Alternation(); + RegExpLexer::Token token = m_Lexer.token(); + if(token.type != RegExpLexer::TEOF) throw ParseError(); + return new regexp::RegExp(element); +} + +regexp::RegExpElement* RegExpParser::Alternation() { + return this->AlternationCont(this->Concatenation()); +} + +regexp::RegExpElement* RegExpParser::AlternationCont(regexp::RegExpElement* left) { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::PLUS) { + m_Lexer.next(); + regexp::Alternation* res = this->AlternationContCont(this->Concatenation()); + res->getElements().push_front(left); + return res; + } else { + return left; + } +} + +regexp::Alternation* RegExpParser::AlternationContCont(regexp::RegExpElement* left) { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::PLUS) { + m_Lexer.next(); + regexp::Alternation* res = this->AlternationContCont(this->Concatenation()); + res->getElements().push_front(left); + return res; + } else { + regexp::Alternation* res = new regexp::Alternation(); + res->getElements().push_front(left); + return res; + } +} + + +regexp::RegExpElement* RegExpParser::Concatenation() { + return this->ConcatenationCont(this->Factor()); +} + +regexp::RegExpElement* RegExpParser::ConcatenationCont(regexp::RegExpElement* left) { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::SYMBOL || token.type == RegExpLexer::LPAR || token.type == RegExpLexer::EPS || token.type == RegExpLexer::EMPTY) { + + regexp::Concatenation* res = this->ConcatenationContCont(this->Factor()); + res->getElements().push_front(left); + return res; + } else { + return left; + } +} + +regexp::Concatenation* RegExpParser::ConcatenationContCont(regexp::RegExpElement* left) { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::SYMBOL || token.type == RegExpLexer::LPAR || token.type == RegExpLexer::EPS || token.type == RegExpLexer::EMPTY) { + + regexp::Concatenation* res = this->ConcatenationContCont(this->Factor()); + res->getElements().push_front(left); + return res; + } else { + regexp::Concatenation* res = new regexp::Concatenation(); + res->getElements().push_front(left); + return res; + } +} + +regexp::RegExpElement* RegExpParser::Factor() { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::LPAR) { + m_Lexer.next(); + regexp::RegExpElement* base = this->Alternation(); + token = m_Lexer.token(); + if(token.type != RegExpLexer::RPAR) throw ParseError(); + m_Lexer.next(); + return this->Star(base); + } else if(token.type == RegExpLexer::EPS) { + m_Lexer.next(); + return this->Star(new regexp::RegExpEpsilon()); + } else if(token.type == RegExpLexer::EMPTY) { + m_Lexer.next(); + return this->Star(new regexp::RegExpEmpty()); + } else if(token.type == RegExpLexer::SYMBOL) { + std::string symbol = token.value; + m_Lexer.next(); + return this->Star(new regexp::RegExpSymbol(symbol)); + } else { + throw ParseError(); + } +} + +regexp::RegExpElement* RegExpParser::Star(regexp::RegExpElement* elem) { + RegExpLexer::Token token = m_Lexer.token(); + if(token.type == RegExpLexer::STAR) { + m_Lexer.next(); + regexp::Iteration* iter = new regexp::Iteration(); + iter->setElement(this->Star(elem)); + return iter; + } else { + return elem; + } +} diff --git a/aconvert.regexp/src/RegExpParser.h b/aconvert.regexp/src/RegExpParser.h new file mode 100644 index 0000000000..37e161181e --- /dev/null +++ b/aconvert.regexp/src/RegExpParser.h @@ -0,0 +1,40 @@ +#ifndef __REG_EXP_PARSER__ +#define __REG_EXP_PARSER__ + +#include "RegExpLexer.h" + +#include "regexp/RegExp.h" +#include "regexp/RegExpElement.h" + +#include "regexp/Alternation.h" +#include "regexp/Concatenation.h" +#include "regexp/Iteration.h" +#include "regexp/RegExpSymbol.h" +#include "regexp/RegExpEpsilon.h" +#include "regexp/RegExpEmpty.h" + +class ParseError { + +}; + +class RegExpParser { + RegExpLexer& m_Lexer; +public: + RegExpParser(RegExpLexer&); + regexp::RegExp* parse(); + +private: + regexp::RegExpElement* Alternation(); + regexp::RegExpElement* AlternationCont(regexp::RegExpElement* left); + regexp::Alternation* AlternationContCont(regexp::RegExpElement* left); + + regexp::RegExpElement* Concatenation(); + regexp::RegExpElement* ConcatenationCont(regexp::RegExpElement* left); + regexp::Concatenation* ConcatenationContCont(regexp::RegExpElement* left); + + regexp::RegExpElement* Factor(); + regexp::RegExpElement* Star(regexp::RegExpElement* elem); + +}; + +#endif \ No newline at end of file diff --git a/aconvert.regexp/src/RegExpPrinter.cpp b/aconvert.regexp/src/RegExpPrinter.cpp new file mode 100644 index 0000000000..2b1e7d3335 --- /dev/null +++ b/aconvert.regexp/src/RegExpPrinter.cpp @@ -0,0 +1,86 @@ +#include "RegExpPrinter.h" + +RegExpPrinter::RegExpPrinter(std::ostream& m_Out) : m_Out(m_Out) { + +} + +void RegExpPrinter::printElement(regexp::RegExpElement* element) { + regexp::Alternation* alternation = dynamic_cast<regexp::Alternation*>(element); + if (alternation) { + printAlternation(alternation); + return; + } + + regexp::Concatenation* concatenation = dynamic_cast<regexp::Concatenation*>(element); + if(concatenation) { + printConcatenation(concatenation); + return; + } + + regexp::Iteration* iteration = dynamic_cast<regexp::Iteration*>(element); + if (iteration) { + printIteration(iteration); + return; + } + + regexp::RegExpEpsilon* epsilon = dynamic_cast<regexp::RegExpEpsilon*>(element); + if (epsilon) { + printEpsilon(epsilon); + return; + } + + regexp::RegExpEmpty* empty = dynamic_cast<regexp::RegExpEmpty*>(element); + if (empty) { + printEmpty(empty); + return; + } + + regexp::RegExpSymbol* symbol = dynamic_cast<regexp::RegExpSymbol*>(element); + if (symbol) { + printSymbol(symbol); + return; + } +} + +void RegExpPrinter::printAlternation(regexp::Alternation* alternation) { + m_Out << "("; + bool first = true; + for (auto element : alternation->getElements()) { + if(first) { + first = false; + } else { + m_Out << "+"; + } + printElement(element); + } + m_Out << ")"; +} + +void RegExpPrinter::printConcatenation(regexp::Concatenation* concatenation) { + for (auto element : concatenation->getElements()) { + printElement(element); + } +} + +void RegExpPrinter::printIteration(regexp::Iteration* iteration) { + m_Out << "("; + printElement(iteration->getElement()); + m_Out << ")*"; +} + +void RegExpPrinter::printSymbol(regexp::RegExpSymbol* symbol) { + m_Out << symbol->getSymbol(); +} + +void RegExpPrinter::printEpsilon(regexp::RegExpEpsilon* symbol) { + m_Out << "\\e"; +} + +void RegExpPrinter::printEmpty(regexp::RegExpEmpty* symbol) { + m_Out << "\\0"; +} + +void RegExpPrinter::print(regexp::RegExp& regexp) { + printElement(regexp.getRegExp()); + m_Out << std::endl; +} \ No newline at end of file diff --git a/aconvert.regexp/src/RegExpPrinter.h b/aconvert.regexp/src/RegExpPrinter.h new file mode 100644 index 0000000000..124afe6dfc --- /dev/null +++ b/aconvert.regexp/src/RegExpPrinter.h @@ -0,0 +1,28 @@ +#ifndef REGEXP_PRINTER_H_ +#define REGEXP_PRINTER_H_ + +#include <iostream> +#include "regexp/RegExp.h" +#include "regexp/Alternation.h" +#include "regexp/Concatenation.h" +#include "regexp/Iteration.h" +#include "regexp/RegExpSymbol.h" +#include "regexp/RegExpEpsilon.h" +#include "regexp/RegExpEmpty.h" + +class RegExpPrinter { + std::ostream& m_Out; +public: + RegExpPrinter(std::ostream& out); + void printElement(regexp::RegExpElement* element); + void printAlternation(regexp::Alternation* alternation); + void printConcatenation(regexp::Concatenation* concatenation); + void printIteration(regexp::Iteration* iteration); + void printSymbol(regexp::RegExpSymbol* symbol); + void printEpsilon(regexp::RegExpEpsilon* symbol); + void printEmpty(regexp::RegExpEmpty* symbol); + + void print(regexp::RegExp& regexp); +}; + +#endif /*REGEXP_PRINTER_H_*/ \ No newline at end of file diff --git a/aconvert.regexp/src/aconvert.regexp.cpp b/aconvert.regexp/src/aconvert.regexp.cpp new file mode 100644 index 0000000000..417a1ff111 --- /dev/null +++ b/aconvert.regexp/src/aconvert.regexp.cpp @@ -0,0 +1,90 @@ +#include <iostream> +#include <fstream> +#include "RegExpLexer.h" +#include "RegExpParser.h" +#include "RegExpPrinter.h" + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> + +#include "regexp/RegExp.h" +#include "RegExpFactory.h" +#include "AlibException.h" + +#include "regexp/RegExp.h" + +#define FROM 1 +#define TO 2 + +int fromRegexp(std::istream& in, std::ostream& out) { + RegExpLexer lexer(in); + RegExpParser parser(lexer); + + regexp::RegExp* result = parser.parse(); + + out << *result; + + return 0; +} + +int toRegexp(std::istream& in, std::ostream& out) { + try { + + regexp::RegExp regexp = regexp::RegExpFactory::fromStream(in); + RegExpPrinter printer = RegExpPrinter(out); + printer.print(regexp); + + } catch (alib::AlibException& e) { + std::cerr << e.getCause() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, char* argv[]) { + + int fromTo = 0; + int c; + + while (1) { + static struct option long_options[] = { + {"from", no_argument, &fromTo, FROM}, + {"to", no_argument, &fromTo, TO}, + {0, 0, 0, 0} + }; + + int option_index = 0; + + c = getopt_long (argc, argv, "", long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 0: + break; + default: + optind--; + goto more; + } + } +more: + + std::istream* in = &std::cin; + if(optind != argc) in = new std::ifstream(argv[optind]); + + int res; + if(fromTo == FROM) { + res = fromRegexp(*in, std::cout); + } else if(fromTo == TO) { + res = toRegexp(*in, std::cout); + } else { + std::cerr << "error" << std::endl; + res = 1; + } + + if(c != -1) delete in; + return res; +} \ No newline at end of file diff --git a/aconvert/makefile b/aconvert/makefile new file mode 100644 index 0000000000..3a23168033 --- /dev/null +++ b/aconvert/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aconvert +CCFLAGS= -std=c++11 -O2 -c -Wall +LDFLAGS= + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aconvert/src/DotConverter.h b/aconvert/src/DotConverter.h deleted file mode 100644 index 63cebef764..0000000000 --- a/aconvert/src/DotConverter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * DotConverter.h - * - * Created on: Apr 1, 2013 - * Author: martin - */ - -#ifndef DOTCONVERTER_H_ -#define DOTCONVERTER_H_ - -#include<ostream> - -#include <automaton/FSM/FSM.h> -#include <automaton/PDA/PDA.h> -#include <automaton/TM/TM.h> -#include <map> -#include <utility> - -class DotConverter { -protected: - static void transitions(const automaton::FSM& fsm, const std::map<automaton::State, int>& states, std::ostream& out); - static void transitions(const automaton::PDA& pda, const std::map<automaton::State, int>& states, std::ostream& out); - static void transitions(const automaton::TM& tm, const std::map<automaton::State, int>& states, std::ostream& out); -public: - static void convert(const automaton::Automaton& a, std::ostream& out); -}; - -#endif /* DOTCONVERTER_H_ */ diff --git a/aconvert/src/aconvert.cpp b/aconvert/src/aconvert.cpp index c327c15123..501cbdd480 100644 --- a/aconvert/src/aconvert.cpp +++ b/aconvert/src/aconvert.cpp @@ -1,50 +1,70 @@ -//============================================================================ -// Name : aconvert.cpp -// Author : Martin Zak -// Version : -// Copyright : -// Description : -//============================================================================ - -#include <iostream> - -#include "automaton/AutomatonParser.h" -#include "automaton/UnknownAutomaton.h" -#include "AutomatonFactory.h" -#include "AlibException.h" -#include "sax/SaxInterface.h" - -#include "DotConverter.h" - -using namespace std; -using namespace automaton; -using namespace sax; -using namespace alib; - -int main(int argc, char** argv) { - list<Token> tokens; - try { - - if (argc > 1) { - if (string("-h").compare(argv[1]) == 0) { - cout - << "Automaton converting tool. Supports only dot format at the moment.\nUsage: aconvert [automaton.xml]\n"; - return -1; - } - - SaxInterface::parseFile(argv[1], tokens); - } else { - string input(istreambuf_iterator<char>(cin), - (istreambuf_iterator<char>())); - SaxInterface::parseMemory(input, tokens); - } +/* + * aconvert + * + * Usage: aconvert [-V] [-t outputtype] [output-options] input + * + * Authors: Martin Zak, Jan Travnicek + * + */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <err.h> +#include <stdlib.h> +#include <sys/stat.h> + +#define PROGNAME "./aconvert.%s" +#define VERSION "0.0.1" +#define USAGE "aconvert [-V] [-t outputtype] [output-options] input" + +int main(int argc, char *argv[]) { + if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))) { + char* program_name = argv[0]; + char* p = NULL; + if ((p = strrchr(program_name, '/')) != NULL) + program_name = p + 1; + + printf("%s (%s)\n", program_name, VERSION); + exit(EXIT_SUCCESS); + } + + char* difftype = NULL; + int i, verbose = 0; - UnknownAutomaton unknownAutomaton = AutomatonParser::parse(tokens); - Automaton* automaton = AutomatonFactory::buildAutomaton(unknownAutomaton); - DotConverter::convert(*automaton, cout); + while ((i = getopt(argc, argv, "Vt:")) != -1) + switch (i) { + case 'V': + verbose = 1; + break; + case 't': + difftype = optarg; + break; + default: + optind--; + goto more; + } +more: - } catch (AlibException& e) { - cout << e.what() << endl; - return 0; + if (optind == argc || difftype == NULL) { + fprintf(stderr, "Usage: %s\n", USAGE); + return EXIT_FAILURE; } + + if (verbose) + argv[--optind] = (char*) "-V"; + + char* program_name = (char*) malloc(sizeof(PROGNAME) - 3 + strlen(difftype) + 1); + sprintf(program_name, PROGNAME, difftype); + + argv[--optind] = program_name + 2; + + struct stat buffer; + if(stat (program_name, &buffer)) { + program_name += 2; + } + + execvp(program_name, argv + optind); + perror(program_name); + return EXIT_FAILURE; } diff --git a/adeterminize.fsm/makefile b/adeterminize.fsm/makefile new file mode 100644 index 0000000000..4567989565 --- /dev/null +++ b/adeterminize.fsm/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=adeterminize.fsm +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src -I../adeterminize/src +LDFLAGS= -L../alib/lib -L../adeterminize/lib -lxml2 -lalib -ladeterminize -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/adeterminize.vpa/src/VPADeterminizer.cpp b/adeterminize.vpa/src/VPADeterminizer.cpp new file mode 100644 index 0000000000..9cca7a2145 --- /dev/null +++ b/adeterminize.vpa/src/VPADeterminizer.cpp @@ -0,0 +1,226 @@ +#include "VPADeterminizer.h" + +namespace determinization { + + +PDA VPADeterminizer::determinize(PDA& nondeterministicVPA) { + PDA deterministicVPA; + map<string, StateData> states; + set<Symbol> internalSymbols; + set<Symbol> callSymbols; + set<Symbol> returnSymbols; + + DeterminizationUtils::copyInputAlphabet(nondeterministicVPA, deterministicVPA); + VPADeterminizationUtils::divideInputAlphabet(nondeterministicVPA, internalSymbols, callSymbols, returnSymbols); + vector<PartialStackData> partialStackAlphabet = VPADeterminizationUtils::buildStackAlphabet(nondeterministicVPA, + deterministicVPA, callSymbols); + + const SComponent& initialS = VPADeterminizationUtils::getSComponentWithStatesIdentity(nondeterministicVPA.getStates()); + const RComponent& initialR(nondeterministicVPA.getInitialStates()); + const State& initialState = VPADeterminizationUtils::getOrCreateState(initialS, initialR, states, deterministicVPA); + deterministicVPA.addInitialState(initialState); + + set<TransitionPDA> transitions = nondeterministicVPA.getTransitions(); + + while (true) { + StateData* unmarkedStateData = VPADeterminizationUtils::getUnmarkedState(states); + if (unmarkedStateData == NULL) { + break; + } + + // Internal symbols + for (set<Symbol>::iterator internalSymbol = internalSymbols.begin(); + internalSymbol != internalSymbols.end(); + internalSymbol++) { + SComponent sPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + RComponent rPrimed; + RComponent& r = unmarkedStateData->r; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + const TransitionPDA transition(fromState, *internalSymbol, toState); + deterministicVPA.addTransition(transition); + } + + // Call symbols + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); + callSymbol != callSymbols.end(); + callSymbol++) { + RComponent rPrimed; + RComponent& r = unmarkedStateData->r; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *callSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + SComponent& s = unmarkedStateData->s; + const SComponent& sPrimed = VPADeterminizationUtils::getSComponentWithStatesIdentity(nondeterministicVPA.getStates()); + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizationUtils::buildStackSymbolName(s, r, *callSymbol); + list<Symbol> pop; + list<Symbol> push(1, Symbol(stackSymbolName)); + const TransitionPDA transition(fromState, *callSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + + // Return symbols + for (set<Symbol>::iterator returnSymbol = returnSymbols.begin(); + returnSymbol != returnSymbols.end(); + returnSymbol++) { + SComponent& s = unmarkedStateData->s; + RComponent& r = unmarkedStateData->r; + + // Empty stack + list<Symbol> bottomOfStack(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + SComponent sPrimed; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + RComponent rPrimed; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + list<Symbol> pop(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + + // Otherwise + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + set<StatesPair> update; + for (set<StatesPair>::iterator sPair = s.statesPairs.begin(); + sPair != s.statesPairs.end(); + sPair++) { + const State& q1 = sPair->state1; + const State& q2 = sPair->state2; + if (r.states.find(q2) != r.states.end()) { + for (set<TransitionPDA>::iterator transitionPush = transitions.begin(); + transitionPush != transitions.end(); + transitionPush++) { + for (set<TransitionPDA>::iterator transitionPop = transitions.begin(); + transitionPop != transitions.end(); + transitionPop++) { + const State& q = transitionPush->getFrom(); + const State& qPrimed = transitionPop->getTo(); + if (transitionPush->getInput() == *callSymbol && transitionPush->getTo() == q1 && + transitionPop->getInput() == *returnSymbol && transitionPop->getFrom() == q2 && + transitionPush->getPush() == transitionPop->getPop()) { + update.insert(StatesPair(q, qPrimed)); + } + } + } + } + } + if (update.size() == 0) { + continue; + } + + for (vector<PartialStackData>::iterator partialStackSymbol = partialStackAlphabet.begin(); + partialStackSymbol != partialStackAlphabet.end(); + partialStackSymbol++) { + SComponent& sPrimed = partialStackSymbol->s; + RComponent& rPrimed = partialStackSymbol->r; + + RComponent rDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q = updateItem->state1; + const State& qPrimed = updateItem->state2; + if (rPrimed.states.find(q) != rPrimed.states.end()) { + rDoublePrimed.states.insert(qPrimed); + } + } + SComponent sDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q3 = updateItem->state1; + const State& qPrimed = updateItem->state2; + for (set<StatesPair>::iterator sPrimedPair = sPrimed.statesPairs.begin(); + sPrimedPair != sPrimed.statesPairs.end(); + sPrimedPair++) { + if (sPrimedPair->state2 == q3) { + const State& q = sPrimedPair->state1; + sDoublePrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, + states, deterministicVPA); + string stackSymbolName = VPADeterminizationUtils::buildStackSymbolName(sPrimed, rPrimed, *callSymbol); + list<Symbol> pop(1, Symbol(stackSymbolName)); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + } + } + } + + // Final states + for (map<string, StateData>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { + const StateData& stateData = stateIter->second; + if (DeterminizationUtils::containSomeFinalStateOfAutomaton(stateData.r.states, nondeterministicVPA)) { + deterministicVPA.addFinalState(stateData.state); + } + } + + return deterministicVPA; +} + +} /* namespace determinization */ diff --git a/adeterminize.vpa/src/VPADeterminizer.h b/adeterminize.vpa/src/VPADeterminizer.h new file mode 100644 index 0000000000..a208ce094e --- /dev/null +++ b/adeterminize.vpa/src/VPADeterminizer.h @@ -0,0 +1,28 @@ +#ifndef VPADETERMINIZER_H_ +#define VPADETERMINIZER_H_ + +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "alphabet/Symbol.h" +#include "DeterminizationUtils.h" +#include "VPADeterminizationUtils.h" +#include "VPADeterminizationStructs.h" + +using namespace std; +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class VPADeterminizer { +public: + static PDA determinize(PDA& automaton); +}; + +} /* namespace determinization */ +#endif /* VPADETERMINIZER_H_ */ \ No newline at end of file diff --git a/adeterminize.vpa/src/adeterminize.vpa.cpp b/adeterminize.vpa/src/adeterminize.vpa.cpp new file mode 100644 index 0000000000..fccb49688a --- /dev/null +++ b/adeterminize.vpa/src/adeterminize.vpa.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <set> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "VPADeterminizer.h" + + +using namespace std; +using namespace automaton; +using namespace determinization; +using namespace alib; + + +int main(int argc, char** argv) { + UnknownAutomaton automaton; + + try { + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + automaton = AutomatonFactory::fromString(input); + + Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton); + // TODO check that automaton is VPA + PDA deterministicVPA = VPADeterminizer::determinize(*((PDA*) knownAutomaton)); + deterministicVPA.toXML(cout); + + delete knownAutomaton; + + } catch (AlibException& e) { + cout << e.what() << endl; + return 0; + } +} \ No newline at end of file diff --git a/adeterminize.vpa2/src/VPADeterminizer2.cpp b/adeterminize.vpa2/src/VPADeterminizer2.cpp new file mode 100644 index 0000000000..a6df6c9b2a --- /dev/null +++ b/adeterminize.vpa2/src/VPADeterminizer2.cpp @@ -0,0 +1,225 @@ +#include "VPADeterminizer2.h" + +namespace determinization { + + +PDA VPADeterminizer2::determinize(PDA& nondeterministicVPA) { + PDA deterministicVPA; + map<string, StateData> states; + set<Symbol> internalSymbols; + set<Symbol> callSymbols; + set<Symbol> returnSymbols; + + DeterminizationUtils::copyInputAlphabet(nondeterministicVPA, deterministicVPA); + VPADeterminizationUtils::divideInputAlphabet(nondeterministicVPA, internalSymbols, callSymbols, returnSymbols); + vector<PartialStackData> partialStackAlphabet = VPADeterminizationUtils::buildStackAlphabet(nondeterministicVPA, + deterministicVPA, callSymbols); + + const SComponent& initialS = VPADeterminizationUtils::getSComponentWithStatesIdentity( + nondeterministicVPA.getInitialStates()); + const RComponent& initialR(nondeterministicVPA.getInitialStates()); + const State& initialState = VPADeterminizationUtils::getOrCreateState(initialS, initialR, states, deterministicVPA); + deterministicVPA.addInitialState(initialState); + + set<TransitionPDA> transitions = nondeterministicVPA.getTransitions(); + + while (true) { + StateData* unmarkedStateData = VPADeterminizationUtils::getUnmarkedState(states); + if (unmarkedStateData == NULL) { + break; + } + + // Internal symbols + for (set<Symbol>::iterator internalSymbol = internalSymbols.begin(); + internalSymbol != internalSymbols.end(); + internalSymbol++) { + SComponent sPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + RComponent rPrimed; + RComponent& r = unmarkedStateData->r; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + const TransitionPDA transition(fromState, *internalSymbol, toState); + deterministicVPA.addTransition(transition); + } + + // Call symbols + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); + callSymbol != callSymbols.end(); + callSymbol++) { + RComponent rPrimed; + RComponent& r = unmarkedStateData->r; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *callSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + SComponent& s = unmarkedStateData->s; + const SComponent& sPrimed = VPADeterminizationUtils::getSComponentWithStatesIdentity(rPrimed.states); + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizationUtils::buildStackSymbolName(s, r, *callSymbol); + list<Symbol> pop; + list<Symbol> push(1, Symbol(stackSymbolName)); + const TransitionPDA transition(fromState, *callSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + + // Return symbols + for (set<Symbol>::iterator returnSymbol = returnSymbols.begin(); + returnSymbol != returnSymbols.end(); + returnSymbol++) { + SComponent& s = unmarkedStateData->s; + RComponent& r = unmarkedStateData->r; + + // Empty stack + list<Symbol> bottomOfStack(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + SComponent sPrimed; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + RComponent rPrimed; + for (set<State>::iterator q = r.states.begin(); q != r.states.end(); q++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == *q && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sPrimed, rPrimed, states, deterministicVPA); + list<Symbol> pop(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + + // Otherwise + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + set<StatesPair> update; + for (set<StatesPair>::iterator sPair = s.statesPairs.begin(); + sPair != s.statesPairs.end(); + sPair++) { + const State& q1 = sPair->state1; + const State& q2 = sPair->state2; + for (set<TransitionPDA>::iterator transitionPush = transitions.begin(); + transitionPush != transitions.end(); + transitionPush++) { + for (set<TransitionPDA>::iterator transitionPop = transitions.begin(); + transitionPop != transitions.end(); + transitionPop++) { + const State& q = transitionPush->getFrom(); + const State& qPrimed = transitionPop->getTo(); + if (transitionPush->getInput() == *callSymbol && transitionPush->getTo() == q1 && + transitionPop->getInput() == *returnSymbol && transitionPop->getFrom() == q2 && + transitionPush->getPush() == transitionPop->getPop()) { + update.insert(StatesPair(q, qPrimed)); + } + } + } + } + if (update.size() == 0) { + continue; + } + + for (vector<PartialStackData>::iterator partialStackSymbol = partialStackAlphabet.begin(); + partialStackSymbol != partialStackAlphabet.end(); + partialStackSymbol++) { + SComponent& sPrimed = partialStackSymbol->s; + RComponent& rPrimed = partialStackSymbol->r; + + RComponent rDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q = updateItem->state1; + const State& qPrimed = updateItem->state2; + if (rPrimed.states.find(q) != rPrimed.states.end()) { + rDoublePrimed.states.insert(qPrimed); + } + } + SComponent sDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q3 = updateItem->state1; + const State& qPrimed = updateItem->state2; + for (set<StatesPair>::iterator sPrimedPair = sPrimed.statesPairs.begin(); + sPrimedPair != sPrimed.statesPairs.end(); + sPrimedPair++) { + if (sPrimedPair->state2 == q3) { + const State& q = sPrimedPair->state1; + sDoublePrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizationUtils::getOrCreateState(sDoublePrimed, rDoublePrimed, + states, deterministicVPA); + string stackSymbolName = VPADeterminizationUtils::buildStackSymbolName(sPrimed, rPrimed, *callSymbol); + list<Symbol> pop(1, Symbol(stackSymbolName)); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + } + } + } + + // Final states + for (map<string, StateData>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { + const StateData& stateData = stateIter->second; + if (DeterminizationUtils::containSomeFinalStateOfAutomaton(stateData.r.states, nondeterministicVPA)) { + deterministicVPA.addFinalState(stateData.state); + } + } + + return deterministicVPA; +} + +} /* namespace determinization */ diff --git a/adeterminize.vpa2/src/VPADeterminizer2.h b/adeterminize.vpa2/src/VPADeterminizer2.h new file mode 100644 index 0000000000..73fc867c67 --- /dev/null +++ b/adeterminize.vpa2/src/VPADeterminizer2.h @@ -0,0 +1,28 @@ +#ifndef VPADETERMINIZER2_H_ +#define VPADETERMINIZER2_H_ + +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "alphabet/Symbol.h" +#include "DeterminizationUtils.h" +#include "VPADeterminizationUtils.h" +#include "VPADeterminizationStructs.h" + +using namespace std; +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class VPADeterminizer2 { +public: + static PDA determinize(PDA& automaton); +}; + +} /* namespace determinization */ +#endif /* VPADETERMINIZER2_H_ */ \ No newline at end of file diff --git a/adeterminize.vpa2/src/adeterminize.vpa2.cpp b/adeterminize.vpa2/src/adeterminize.vpa2.cpp new file mode 100644 index 0000000000..fb31cc10b4 --- /dev/null +++ b/adeterminize.vpa2/src/adeterminize.vpa2.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <set> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "VPADeterminizer2.h" + + +using namespace std; +using namespace automaton; +using namespace determinization; +using namespace alib; + + +int main(int argc, char** argv) { + UnknownAutomaton automaton; + + try { + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + automaton = AutomatonFactory::fromString(input); + + Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton); + // TODO check that automaton is VPA + PDA deterministicVPA = VPADeterminizer2::determinize(*((PDA*) knownAutomaton)); + deterministicVPA.toXML(cout); + + delete knownAutomaton; + + } catch (AlibException& e) { + cout << e.what() << endl; + return 0; + } +} \ No newline at end of file diff --git a/adeterminize.vpa3/src/VPADeterminizer3.cpp b/adeterminize.vpa3/src/VPADeterminizer3.cpp new file mode 100644 index 0000000000..a4e0016072 --- /dev/null +++ b/adeterminize.vpa3/src/VPADeterminizer3.cpp @@ -0,0 +1,277 @@ +#include "VPADeterminizer3.h" + +namespace determinization { + + +string VPADeterminizer3::buildStateName(const SComponent& s) { + string name = "{"; + for (set<StatesPair>::const_iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + if (statesPair != s.statesPairs.begin()) { + name += ", "; + } + name += "('" + statesPair->state1.getName() + "', '" + statesPair->state2.getName() + "')"; + } + name += "}"; + return name; +} + + +string VPADeterminizer3::buildStackSymbolName(const SComponent& s, const Symbol& input) { + string name = "(" + buildStateName(s) + ")"; + name += ", " + input.getSymbol(); + return name; +} + + +const State& VPADeterminizer3::getOrCreateState(const SComponent& s, map<string, StateData>& states, + PDA& deterministicVPA) { + string stateName = buildStateName(s); + + map<string, StateData>::iterator statesIter = states.find(stateName); + if (statesIter != states.end()) { + return statesIter->second.state; + } + + State state(stateName); + StateData stateData(state, s); + StateData& insertedData = states.insert(pair<string, StateData>(stateName, stateData)).first->second; + deterministicVPA.addState(state); + return insertedData.state; +} + + +vector<SComponent> VPADeterminizer3::buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, + set<Symbol>& callSymbols) { + const set<State>& states = nondeterministicVPA.getStates(); + + // Generate all possible states pairs + vector<StatesPair> possibleStatesPairs; + for (set<State>::iterator state1 = states.begin(); state1 != states.end(); state1++) { + for (set<State>::iterator state2 = states.begin(); state2 != states.end(); state2++) { + possibleStatesPairs.push_back(StatesPair(*state1, *state2)); + } + } + + // Generate all possible s components = partial stack alphabet + vector<SComponent> partialStackAlphabet; + int possibleSSize = pow(2, possibleStatesPairs.size()); + for (int i = 0; i < possibleSSize; i++) { + set<StatesPair> statesPairsSet; + int mask = 1; + for (vector<StatesPair>::iterator statesPair = possibleStatesPairs.begin(); + statesPair != possibleStatesPairs.end(); + statesPair++) { + if ((i & mask) != 0) { + statesPairsSet.insert(*statesPair); + } + mask <<= 1; + } + partialStackAlphabet.push_back(SComponent(statesPairsSet)); + } + + // Generate whole stack alphabet + set<Symbol> alphabet = nondeterministicVPA.getInputAlphabet(); + for (vector<SComponent>::iterator s = partialStackAlphabet.begin(); s != partialStackAlphabet.end(); s++) { + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(*s, *callSymbol); + deterministicVPA.addStackSymbol(Symbol(stackSymbolName)); + } + } + + // Add bottom of stack symbol + deterministicVPA.addStackSymbol(VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + + return partialStackAlphabet; +} + + +PDA VPADeterminizer3::determinize(PDA& nondeterministicVPA) { + PDA deterministicVPA; + map<string, StateData> states; + set<Symbol> internalSymbols; + set<Symbol> callSymbols; + set<Symbol> returnSymbols; + + DeterminizationUtils::copyInputAlphabet(nondeterministicVPA, deterministicVPA); + VPADeterminizationUtils::divideInputAlphabet(nondeterministicVPA, internalSymbols, callSymbols, returnSymbols); + vector<SComponent> partialStackAlphabet = VPADeterminizer3::buildStackAlphabet(nondeterministicVPA, + deterministicVPA, callSymbols); + + const SComponent& initialS = VPADeterminizationUtils::getSComponentWithStatesIdentity( + nondeterministicVPA.getInitialStates()); + const State& initialState = VPADeterminizer3::getOrCreateState(initialS, states, deterministicVPA); + deterministicVPA.addInitialState(initialState); + + set<TransitionPDA> transitions = nondeterministicVPA.getTransitions(); + + while (true) { + StateData* unmarkedStateData = VPADeterminizationUtils::getUnmarkedState(states); + if (unmarkedStateData == NULL) { + break; + } + + // Internal symbols + for (set<Symbol>::iterator internalSymbol = internalSymbols.begin(); + internalSymbol != internalSymbols.end(); + internalSymbol++) { + SComponent sPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *internalSymbol) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + const TransitionPDA transition(fromState, *internalSymbol, toState); + deterministicVPA.addTransition(transition); + } + + // Call symbols + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); + callSymbol != callSymbols.end(); + callSymbol++) { + RComponent rPrimed; + SComponent& s = unmarkedStateData->s; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == q && transition->getInput() == *callSymbol) { + const State& qPrimed = transition->getTo(); + rPrimed.states.insert(qPrimed); + } + } + } + const SComponent& sPrimed = VPADeterminizationUtils::getSComponentWithStatesIdentity(rPrimed.states); + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(s, *callSymbol); + list<Symbol> pop; + list<Symbol> push(1, Symbol(stackSymbolName)); + const TransitionPDA transition(fromState, *callSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + + // Return symbols + for (set<Symbol>::iterator returnSymbol = returnSymbols.begin(); + returnSymbol != returnSymbols.end(); + returnSymbol++) { + SComponent& s = unmarkedStateData->s; + + // Empty stack + list<Symbol> bottomOfStack(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + SComponent sPrimed; + for (set<StatesPair>::iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + const State& q = statesPair->state1; + const State& qDoublePrimed = statesPair->state2; + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getFrom() == qDoublePrimed && transition->getInput() == *returnSymbol && + transition->getPop() == bottomOfStack) { + const State& qPrimed = transition->getTo(); + sPrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sPrimed, states, deterministicVPA); + list<Symbol> pop(1, VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + + // Otherwise + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + set<StatesPair> update; + for (set<StatesPair>::iterator sPair = s.statesPairs.begin(); + sPair != s.statesPairs.end(); + sPair++) { + const State& q1 = sPair->state1; + const State& q2 = sPair->state2; + for (set<TransitionPDA>::iterator transitionPush = transitions.begin(); + transitionPush != transitions.end(); + transitionPush++) { + for (set<TransitionPDA>::iterator transitionPop = transitions.begin(); + transitionPop != transitions.end(); + transitionPop++) { + const State& q = transitionPush->getFrom(); + const State& qPrimed = transitionPop->getTo(); + if (transitionPush->getInput() == *callSymbol && transitionPush->getTo() == q1 && + transitionPop->getInput() == *returnSymbol && transitionPop->getFrom() == q2 && + transitionPush->getPush() == transitionPop->getPop()) { + update.insert(StatesPair(q, qPrimed)); + } + } + } + } + if (update.size() == 0) { + continue; + } + + for (vector<SComponent>::iterator partialStackSymbol = partialStackAlphabet.begin(); + partialStackSymbol != partialStackAlphabet.end(); + partialStackSymbol++) { + SComponent& sPrimed = *partialStackSymbol; + SComponent sDoublePrimed; + for (set<StatesPair>::iterator updateItem = update.begin(); + updateItem != update.end(); + updateItem++) { + const State& q3 = updateItem->state1; + const State& qPrimed = updateItem->state2; + for (set<StatesPair>::iterator sPrimedPair = sPrimed.statesPairs.begin(); + sPrimedPair != sPrimed.statesPairs.end(); + sPrimedPair++) { + if (sPrimedPair->state2 == q3) { + const State& q = sPrimedPair->state1; + sDoublePrimed.statesPairs.insert(StatesPair(q, qPrimed)); + } + } + } + const State& fromState = unmarkedStateData->state; + const State& toState = VPADeterminizer3::getOrCreateState(sDoublePrimed, states, deterministicVPA); + string stackSymbolName = VPADeterminizer3::buildStackSymbolName(sPrimed, *callSymbol); + list<Symbol> pop(1, Symbol(stackSymbolName)); + list<Symbol> push; + const TransitionPDA transition(fromState, *returnSymbol, toState, pop, push); + deterministicVPA.addTransition(transition); + } + } + } + } + + // Final states + for (map<string, StateData>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { + const StateData& stateData = stateIter->second; + set<State> secondStates; + for (set<StatesPair>::iterator sPair = stateData.s.statesPairs.begin(); + sPair != stateData.s.statesPairs.end(); + sPair++) { + secondStates.insert(sPair->state2); + } + if (DeterminizationUtils::containSomeFinalStateOfAutomaton(secondStates, nondeterministicVPA)) { + deterministicVPA.addFinalState(stateData.state); + } + } + + return deterministicVPA; +} + +} /* namespace determinization */ diff --git a/adeterminize.vpa3/src/VPADeterminizer3.h b/adeterminize.vpa3/src/VPADeterminizer3.h new file mode 100644 index 0000000000..f1a252f5d1 --- /dev/null +++ b/adeterminize.vpa3/src/VPADeterminizer3.h @@ -0,0 +1,34 @@ +#ifndef VPADETERMINIZER2_H_ +#define VPADETERMINIZER2_H_ + +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "alphabet/Symbol.h" +#include "DeterminizationUtils.h" +#include "VPADeterminizationUtils.h" +#include "VPADeterminizationStructs.h" + +using namespace std; +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class VPADeterminizer3 { +protected: + static string buildStateName(const SComponent& s); + static string buildStackSymbolName(const SComponent& s, const Symbol& input); + static const State& getOrCreateState(const SComponent& s, map<string, StateData>& states, PDA& deterministicVPA); + static vector<SComponent> buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, set<Symbol>& callSymbols); + +public: + static PDA determinize(PDA& automaton); +}; + +} /* namespace determinization */ +#endif /* VPADETERMINIZER2_H_ */ \ No newline at end of file diff --git a/adeterminize.vpa3/src/adeterminize.vpa3.cpp b/adeterminize.vpa3/src/adeterminize.vpa3.cpp new file mode 100644 index 0000000000..364824b69a --- /dev/null +++ b/adeterminize.vpa3/src/adeterminize.vpa3.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <set> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "VPADeterminizer3.h" + + +using namespace std; +using namespace automaton; +using namespace determinization; +using namespace alib; + + +int main(int argc, char** argv) { + UnknownAutomaton automaton; + + try { + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + automaton = AutomatonFactory::fromString(input); + + Automaton* knownAutomaton = AutomatonFactory::buildAutomaton(automaton); + // TODO check that automaton is VPA + PDA deterministicVPA = VPADeterminizer3::determinize(*((PDA*) knownAutomaton)); + deterministicVPA.toXML(cout); + + delete knownAutomaton; + + } catch (AlibException& e) { + cout << e.what() << endl; + return 0; + } +} \ No newline at end of file diff --git a/adeterminize/makefile b/adeterminize/makefile new file mode 100644 index 0000000000..c18556666a --- /dev/null +++ b/adeterminize/makefile @@ -0,0 +1,20 @@ +CC=g++ +LIBRARY=libadeterminize.so +CCFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I../alib/src +LDFLAGS= -L../alib/lib -shared + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) lib/$(LIBRARY) + +lib/$(LIBRARY): $(OBJECTS) + mkdir -p lib + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d lib obj diff --git a/adeterminize/src/DeterminizationUtils.cpp b/adeterminize/src/DeterminizationUtils.cpp index 89060cf71e..bd6cda701c 100644 --- a/adeterminize/src/DeterminizationUtils.cpp +++ b/adeterminize/src/DeterminizationUtils.cpp @@ -14,6 +14,7 @@ string DeterminizationUtils::buildStateName(const set<State>& states) { return name; } + const State& DeterminizationUtils::getOrCreateState(const set<State>& originalStates, map<string, StateData>& states, Automaton& automaton) { string stateName = buildStateName(originalStates); diff --git a/adeterminize/src/VPADeterminizationStructs.h b/adeterminize/src/VPADeterminizationStructs.h new file mode 100644 index 0000000000..cdf196a15b --- /dev/null +++ b/adeterminize/src/VPADeterminizationStructs.h @@ -0,0 +1,77 @@ +#ifndef VPADETERKMINIZATIONSTRUCTS_H_ +#define VPADETERKMINIZATIONSTRUCTS_H_ + +#include <set> + +using namespace automaton; + +namespace determinization { + +struct StatesPair { + State state1; + State state2; + + StatesPair(const State& state1, const State& state2) + : state1(state1), + state2(state2) {} + + bool operator < (const StatesPair& other) const { + return state1 < other.state1 || state1 == other.state1 && state2 < other.state2; + } + + bool operator == (const StatesPair& other) const { + return state1 == other.state1 && state2 == other.state2; + } + + bool operator != (const StatesPair& other) const { + return state1 != other.state1 || state2 != other.state2; + } +}; + + +struct SComponent { + set<StatesPair> statesPairs; + SComponent() {} + SComponent(const set<StatesPair>& statesPairs) + : statesPairs(statesPairs) {} +}; + + +struct RComponent { + set<State> states; + RComponent() {} + RComponent(const set<State>& states) + : states(states) {} +}; + + +struct StateData { + State state; + SComponent s; + RComponent r; + bool isMarked; + + StateData(const State& state, const SComponent& s, const RComponent& r) + : s(s), + r(r), + state(state), + isMarked(false) {} + + StateData(const State& state, const SComponent& s) + : s(s), + state(state), + isMarked(false) {} +}; + + +struct PartialStackData { + SComponent s; + RComponent r; + + PartialStackData(const SComponent& s, const RComponent& r) + : s(s), + r(r) {} +}; + +} /* namespace determinization */ +#endif /* VPADETERKMINIZATIONSTRUCTS_H_ */ \ No newline at end of file diff --git a/adeterminize/src/VPADeterminizationUtils.cpp b/adeterminize/src/VPADeterminizationUtils.cpp new file mode 100644 index 0000000000..474cea571e --- /dev/null +++ b/adeterminize/src/VPADeterminizationUtils.cpp @@ -0,0 +1,162 @@ +#include "VPADeterminizationUtils.h" + +namespace determinization { + +const Symbol VPADeterminizationUtils::BOTTOM_OF_STACK_SYMBOL("⊥"); + + +string VPADeterminizationUtils::buildStateName(const SComponent& s, const RComponent& r) { + string name = "{"; + for (set<StatesPair>::const_iterator statesPair = s.statesPairs.begin(); + statesPair != s.statesPairs.end(); + statesPair++) { + if (statesPair != s.statesPairs.begin()) { + name += ", "; + } + name += "('" + statesPair->state1.getName() + "', '" + statesPair->state2.getName() + "')"; + } + name += "}, {"; + for (set<State>::const_iterator state = r.states.begin(); state != r.states.end(); state++) { + if (state != r.states.begin()) { + name += ", "; + } + name += "'" + state->getName() + "'"; + } + name += "}"; + return name; +} + + +const State& VPADeterminizationUtils::getOrCreateState(const SComponent& s, const RComponent& r, map<string, + StateData>& states, PDA& deterministicVPA) { + string stateName = buildStateName(s, r); + + map<string, StateData>::iterator statesIter = states.find(stateName); + if (statesIter != states.end()) { + return statesIter->second.state; + } + + State state(stateName); + StateData stateData(state, s, r); + StateData& insertedData = states.insert(pair<string, StateData>(stateName, stateData)).first->second; + deterministicVPA.addState(state); + return insertedData.state; +} + + +const SComponent VPADeterminizationUtils::getSComponentWithStatesIdentity(const set<State>& states) { + set<StatesPair> statesPairs; + for (set<State>::const_iterator state = states.begin(); state != states.end(); state++) { + statesPairs.insert(StatesPair(*state, *state)); + } + return SComponent(statesPairs); +} + + +void VPADeterminizationUtils::divideInputAlphabet(PDA& nondeterministicVPA, set<Symbol>& internalSymbols, + set<Symbol>& callSymbols, set<Symbol>& returnSymbols) { + const set<Symbol>& alphabet = nondeterministicVPA.getInputAlphabet(); + const set<TransitionPDA>& transitions = nondeterministicVPA.getTransitions(); + for (set<Symbol>::iterator input = alphabet.begin(); input != alphabet.end(); input++) { + for (set<TransitionPDA>::iterator transition = transitions.begin(); + transition != transitions.end(); + transition++) { + if (transition->getInput() == *input) { + if (transition->getPush().size() != 0) { + callSymbols.insert(*input); + } else if (transition->getPop().size() != 0) { + returnSymbols.insert(*input); + } else { + internalSymbols.insert(*input); + } + break; + } + } + } +} + + +string VPADeterminizationUtils::buildStackSymbolName(const SComponent& s, const RComponent& r, const Symbol& input) { + string name = "(" + buildStateName(s, r) + ")"; + name += ", " + input.getSymbol(); + return name; +} + + +vector<PartialStackData> VPADeterminizationUtils::buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, + set<Symbol>& callSymbols) { + vector<PartialStackData> partialStackAlphabet; + const set<State>& states = nondeterministicVPA.getStates(); + + // Generate all possible states pairs + vector<StatesPair> possibleStatesPairs; + for (set<State>::iterator state1 = states.begin(); state1 != states.end(); state1++) { + for (set<State>::iterator state2 = states.begin(); state2 != states.end(); state2++) { + possibleStatesPairs.push_back(StatesPair(*state1, *state2)); + } + } + + // Generate all possible s components + vector<SComponent> possibleS; + int possibleSSize = pow(2, possibleStatesPairs.size()); + for (int i = 0; i < possibleSSize; i++) { + set<StatesPair> statesPairsSet; + int mask = 1; + for (vector<StatesPair>::iterator statesPair = possibleStatesPairs.begin(); + statesPair != possibleStatesPairs.end(); + statesPair++) { + if ((i & mask) != 0) { + statesPairsSet.insert(*statesPair); + } + mask <<= 1; + } + possibleS.push_back(SComponent(statesPairsSet)); + } + + // Generate all possible r components + vector<RComponent> possibleR; + int possibleRSize = pow(2, states.size()); + for (int i = 0; i < possibleRSize; i++) { + set<State> statesSet; + int mask = 1; + for (set<State>::iterator state = states.begin(); state != states.end(); state++) { + if ((i & mask) != 0) { + statesSet.insert(*state); + } + mask <<= 1; + } + possibleR.push_back(RComponent(statesSet)); + } + + // Generate whole stack alphabet + set<Symbol> alphabet = nondeterministicVPA.getInputAlphabet(); + for (vector<SComponent>::iterator s = possibleS.begin(); s != possibleS.end(); s++) { + for (vector<RComponent>::iterator r = possibleR.begin(); r != possibleR.end(); r++) { + partialStackAlphabet.push_back(PartialStackData(*s, *r)); + for (set<Symbol>::iterator callSymbol = callSymbols.begin(); callSymbol != callSymbols.end(); callSymbol++) { + string stackSymbolName = buildStackSymbolName(*s, *r, *callSymbol); + deterministicVPA.addStackSymbol(Symbol(stackSymbolName)); + } + } + } + + // Add bottom of stack symbol + deterministicVPA.addStackSymbol(BOTTOM_OF_STACK_SYMBOL); + + return partialStackAlphabet; +} + + +StateData* VPADeterminizationUtils::getUnmarkedState(map<string, StateData>& states) { + StateData* unmarkedStateData = NULL; + for (map<string, StateData>::iterator stateIter = states.begin(); stateIter != states.end(); stateIter++) { + if (!stateIter->second.isMarked) { + unmarkedStateData = &stateIter->second; + unmarkedStateData->isMarked = true; + return unmarkedStateData; + } + } + return NULL; +} + +} /* namespace determinization */ diff --git a/adeterminize/src/VPADeterminizationUtils.h b/adeterminize/src/VPADeterminizationUtils.h new file mode 100644 index 0000000000..f24f318c26 --- /dev/null +++ b/adeterminize/src/VPADeterminizationUtils.h @@ -0,0 +1,38 @@ +#ifndef VPADETERKMINIZATIONUTILS_H_ +#define VPADETERKMINIZATIONUTILS_H_ + +#include <math.h> +#include <string> +#include <set> +#include <map> +#include <vector> + +#include "automaton/PDA/PDA.h" +#include "automaton/Transition.h" +#include "alphabet/Symbol.h" +#include "VPADeterminizationStructs.h" + +using namespace automaton; +using namespace alphabet; + +namespace determinization { + +class VPADeterminizationUtils { +public: + static const Symbol BOTTOM_OF_STACK_SYMBOL; + + static string buildStateName(const SComponent& s, const RComponent& r); + static const State& getOrCreateState(const SComponent& s, const RComponent& r, map<string, StateData>& states, + PDA& deterministicVPA); + static const SComponent getSComponentWithStatesIdentity(const set<State>& states); + static void divideInputAlphabet(PDA& nondeterministicVPA, set<Symbol>& internalSymbols, set<Symbol>& callSymbols, + set<Symbol>& returnSymbols); + static string buildStackSymbolName(const SComponent& s, const RComponent& r, const Symbol& input); + static vector<PartialStackData> buildStackAlphabet(PDA& nondeterministicVPA, PDA& deterministicVPA, + set<Symbol>& callSymbols); + static StateData* getUnmarkedState(map<string, StateData>& states); + +}; + +} /* namespace determinization */ +#endif /* VPADETERKMINIZATIONUTILS_H_ */ \ No newline at end of file diff --git a/adiff.automaton/makefile b/adiff.automaton/makefile new file mode 100644 index 0000000000..112e9e1dbe --- /dev/null +++ b/adiff.automaton/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=adiff.automaton +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/adiff.automaton/src/AutomatonDiff.cpp b/adiff.automaton/src/AutomatonDiff.cpp new file mode 100644 index 0000000000..12842cb19d --- /dev/null +++ b/adiff.automaton/src/AutomatonDiff.cpp @@ -0,0 +1,131 @@ +/* + * AutomatonDiff.cpp + * + * Created on: Apr 1, 2013 + * Author: martin + */ + +#include "AutomatonDiff.h" +#include "automaton/State.h" + +#include "automaton/Automaton.h" + +#include <set> +#include <map> +#include <list> +#include <utility> +#include <vector> +#include <typeinfo> +#include <iostream> +#include <algorithm> + +using namespace std; +using namespace automaton; + +bool AutomatonDiff::testDiff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b) { + return a.getBlankSymbol() == b.getBlankSymbol() && + a.getFinalStates() == b.getFinalStates() && + a.getInitialStates() == b.getInitialStates() && + a.getInputAlphabet() == b.getInputAlphabet() && + a.getStackAlphabet() == b.getStackAlphabet() && + a.getStartSymbols() == b.getStartSymbols() && + a.getStates() == b.getStates() && + a.getTapeAlphabet() == b.getTapeAlphabet() && + a.getTransitions() == b.getTransitions() ; +} + +template <class T> void AutomatonDiff::setDiff(const set<T> a, const set<T> b) { + set<T> aMinusB; + set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(aMinusB, aMinusB.begin())); + + set<T> bMinusA; + set_difference(b.begin(), b.end(), a.begin(), a.end(), std::inserter(bMinusA, bMinusA.begin())); + + for(typename set<T>::const_iterator iter = aMinusB.begin(); iter != aMinusB.end(); iter++) { + cout << "< " << *iter << endl; + } + cout << "---" << endl; + for(typename set<T>::const_iterator iter = bMinusA.begin(); iter != bMinusA.end(); iter++) { + cout << "> " << *iter << endl; + } +} + +template <class T> void AutomatonDiff::listDiff(const list<T> a, const list<T> b) { + list<T> aMinusB; + set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(aMinusB, aMinusB.begin())); + + list<T> bMinusA; + set_difference(b.begin(), b.end(), a.begin(), a.end(), std::inserter(bMinusA, bMinusA.begin())); + + for(typename list<T>::const_iterator iter = aMinusB.begin(); iter != aMinusB.end(); iter++) { + cout << "< " << *iter << endl; + } + cout << "---" << endl; + for(typename list<T>::const_iterator iter = bMinusA.begin(); iter != bMinusA.end(); iter++) { + cout << "> " << *iter << endl; + } +} + +void AutomatonDiff::printDiff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b) { + cout << "AutomataDiffer" << endl; + + if(a.getBlankSymbol() != b.getBlankSymbol()) { + cout << "Blank symbol" << endl; + + cout << "< " << a.getBlankSymbol() << endl; + cout << "---" << endl; + cout << "> " << b.getBlankSymbol() << endl; + } + + if(a.getFinalStates() != b.getFinalStates()){ + cout << "FinalStates" << endl; + + AutomatonDiff::setDiff(a.getFinalStates(), b.getFinalStates()); + } + + if(a.getInitialStates() != b.getInitialStates()){ + cout << "InitialStates" << endl; + + AutomatonDiff::setDiff(a.getInitialStates(), b.getInitialStates()); + } + + if(a.getInputAlphabet() != b.getInputAlphabet()) { + cout << "InputAlphabet" << endl; + + AutomatonDiff::setDiff(a.getInputAlphabet(), b.getInputAlphabet()); + } + + if(a.getStackAlphabet() != b.getStackAlphabet()) { + cout << "StackAlphabet" << endl; + + AutomatonDiff::setDiff(a.getStackAlphabet(), b.getStackAlphabet()); + } + + if(a.getStartSymbols() != b.getStartSymbols()) { + cout << "StartSymbols" << endl; + + AutomatonDiff::listDiff(a.getStartSymbols(), b.getStartSymbols()); + } + + if(a.getStates() != b.getStates()) { + cout << "States" << endl; + + AutomatonDiff::setDiff(a.getStates(), b.getStates()); + } + + if(a.getTapeAlphabet() != b.getTapeAlphabet()) { + cout << "TapeAlphabet" << endl; + + AutomatonDiff::setDiff(a.getTapeAlphabet(), b.getTapeAlphabet()); + } + + if(a.getTransitions() != b.getTransitions()) { + cout << "Transitions" << endl; + + AutomatonDiff::setDiff(a.getTransitions(), b.getTransitions()); + } +} + +void AutomatonDiff::diff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b) { + if(!AutomatonDiff::testDiff(a, b)) AutomatonDiff::printDiff(a, b); +} diff --git a/adiff.automaton/src/AutomatonDiff.h b/adiff.automaton/src/AutomatonDiff.h new file mode 100644 index 0000000000..9c06544d84 --- /dev/null +++ b/adiff.automaton/src/AutomatonDiff.h @@ -0,0 +1,27 @@ +/* + * AutomatonDiff.h + * + * Created on: Apr 1, 2013 + * Author: honza + */ + +#ifndef AUTOMATON_DIFF_H_ +#define AUTOMATON_DIFF_H_ + +#include <ostream> + +#include <automaton/UnknownAutomaton.h> +#include <map> +#include <utility> + +class AutomatonDiff { + static bool testDiff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b); + static void printDiff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b); + + template <class T> static void setDiff(const std::set<T> a, const std::set<T> b); + template <class T> static void listDiff(const std::list<T> a, const std::list<T> b); +public: + static void diff(const automaton::UnknownAutomaton& a, const automaton::UnknownAutomaton& b); +}; + +#endif /* AUTOMATON_DIFF_H_ */ diff --git a/adiff.automaton/src/adiff.automaton.cpp b/adiff.automaton/src/adiff.automaton.cpp new file mode 100644 index 0000000000..0c95000b35 --- /dev/null +++ b/adiff.automaton/src/adiff.automaton.cpp @@ -0,0 +1,43 @@ +//============================================================================ +// Name : adiff.cpp +// Author : Honza +// Version : +// Copyright : +// Description : +//============================================================================ + +#include <iostream> + +#include "automaton/UnknownAutomaton.h" +#include "AutomatonFactory.h" +#include "AlibException.h" + +using namespace std; +using namespace automaton; +using namespace alib; + +#include "AutomatonDiff.h" + +int main(int argc, char** argv) { + + UnknownAutomaton automaton1; + UnknownAutomaton automaton2; + + try { + + if (argc == 2 && string("-h").compare(argv[1]) == 0) { + cout << "Automaton diff.\nUsage: adiff automaton.xml automaton.xml\n"; + return -1; + } + + if (argc == 3) { + automaton1 = AutomatonFactory::fromFile(argv[1]); + automaton2 = AutomatonFactory::fromFile(argv[2]); + } + + AutomatonDiff::diff(automaton1, automaton2); + } catch (AlibException& e) { + cout << e.getCause() << endl; + return 0; + } +} diff --git a/adiff.grammar/makefile b/adiff.grammar/makefile new file mode 100644 index 0000000000..b850e6b828 --- /dev/null +++ b/adiff.grammar/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=adiff.grammar +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/adiff.grammar/src/GrammarDiff.cpp b/adiff.grammar/src/GrammarDiff.cpp new file mode 100644 index 0000000000..a1195dbe1d --- /dev/null +++ b/adiff.grammar/src/GrammarDiff.cpp @@ -0,0 +1,94 @@ +/* + * GrammarDiff.cpp + * + * Created on: Apr 1, 2013 + * Author: honza + */ + +#include "GrammarDiff.h" + +#include <set> +#include <map> +#include <list> +#include <utility> +#include <vector> +#include <typeinfo> +#include <iostream> +#include <algorithm> + +using namespace std; +using namespace grammar; + +bool GrammarDiff::testDiff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b) { + return a.getNonTerminalSymbols() == b.getNonTerminalSymbols() && + a.getRules() == b.getRules() && + a.getStartSymbol() == b.getStartSymbol() && + a.getTerminalSymbols() == b.getTerminalSymbols() ; +} + +template <class T> void GrammarDiff::setDiff(const set<T> a, const set<T> b) { + set<T> aMinusB; + set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(aMinusB, aMinusB.begin())); + + set<T> bMinusA; + set_difference(b.begin(), b.end(), a.begin(), a.end(), std::inserter(bMinusA, bMinusA.begin())); + + for(typename set<T>::const_iterator iter = aMinusB.begin(); iter != aMinusB.end(); iter++) { + cout << "< " << *iter << endl; + } + cout << "---" << endl; + for(typename set<T>::const_iterator iter = bMinusA.begin(); iter != bMinusA.end(); iter++) { + cout << "> " << *iter << endl; + } +} + +template <class T> void GrammarDiff::listDiff(const list<T> a, const list<T> b) { + list<T> aMinusB; + set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(aMinusB, aMinusB.begin())); + + list<T> bMinusA; + set_difference(b.begin(), b.end(), a.begin(), a.end(), std::inserter(bMinusA, bMinusA.begin())); + + for(typename list<T>::const_iterator iter = aMinusB.begin(); iter != aMinusB.end(); iter++) { + cout << "< " << *iter << endl; + } + cout << "---" << endl; + for(typename list<T>::const_iterator iter = bMinusA.begin(); iter != bMinusA.end(); iter++) { + cout << "> " << *iter << endl; + } +} + +void GrammarDiff::printDiff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b) { + cout << "GrammarDiffer" << endl; + + if(a.getNonTerminalSymbols() != b.getNonTerminalSymbols()) { + cout << "Nonterminal symbols" << endl; + + GrammarDiff::setDiff(a.getNonTerminalSymbols(), b.getNonTerminalSymbols()); + } + + if(a.getRules() != b.getRules()){ + cout << "Rules" << endl; + + GrammarDiff::setDiff(a.getRules(), b.getRules()); + } + + if(a.getStartSymbol() != b.getStartSymbol()){ + cout << "Start symbol" << endl; + + cout << "< " << a.getStartSymbol() << endl; + cout << "---" << endl; + cout << "> " << b.getStartSymbol() << endl; + } + + if(a.getTerminalSymbols() != b.getTerminalSymbols()) { + cout << "Terminal symbols" << endl; + + GrammarDiff::setDiff(a.getTerminalSymbols(), b.getTerminalSymbols()); + } + +} + +void GrammarDiff::diff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b) { + if(!GrammarDiff::testDiff(a, b)) GrammarDiff::printDiff(a, b); +} diff --git a/adiff.grammar/src/GrammarDiff.h b/adiff.grammar/src/GrammarDiff.h new file mode 100644 index 0000000000..4f99f1e8aa --- /dev/null +++ b/adiff.grammar/src/GrammarDiff.h @@ -0,0 +1,27 @@ +/* + * GrammarDiff.h + * + * Created on: Apr 1, 2013 + * Author: honza + */ + +#ifndef GRAMMAR_DIFF_H_ +#define GRAMMAR_DIFF_H_ + +#include <ostream> + +#include <grammar/UnknownGrammar.h> +#include <map> +#include <utility> + +class GrammarDiff { + static bool testDiff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b); + static void printDiff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b); + + template <class T> static void setDiff(const std::set<T> a, const std::set<T> b); + template <class T> static void listDiff(const std::list<T> a, const std::list<T> b); +public: + static void diff(const grammar::UnknownGrammar& a, const grammar::UnknownGrammar& b); +}; + +#endif /* GRAMMAR_DIFF_H_ */ diff --git a/adiff.grammar/src/adiff.grammar.cpp b/adiff.grammar/src/adiff.grammar.cpp new file mode 100644 index 0000000000..85151541f6 --- /dev/null +++ b/adiff.grammar/src/adiff.grammar.cpp @@ -0,0 +1,43 @@ +//============================================================================ +// Name : aconvert.cpp +// Author : Martin Zak +// Version : +// Copyright : +// Description : +//============================================================================ + +#include <iostream> + +#include "grammar/UnknownGrammar.h" +#include "GrammarFactory.h" +#include "AlibException.h" + +using namespace std; +using namespace grammar; +using namespace alib; + +#include "GrammarDiff.h" + +int main(int argc, char** argv) { + + UnknownGrammar grammar1; + UnknownGrammar grammar2; + + try { + + if (argc == 2 && string("-h").compare(argv[1]) == 0) { + cout << "Grammar diff.\nUsage: adiff grammar1.xml grammar2.xml\n"; + return -1; + } + + if (argc == 3) { + grammar1 = GrammarFactory::fromFile(argv[1]); + grammar2 = GrammarFactory::fromFile(argv[2]); + } + + GrammarDiff::diff(grammar1, grammar2); + } catch (AlibException& e) { + cout << e.getCause() << endl; + return 0; + } +} diff --git a/adiff/makefile b/adiff/makefile new file mode 100644 index 0000000000..6773028e5e --- /dev/null +++ b/adiff/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=adiff +CCFLAGS= -std=c++11 -O2 -c -Wall +LDFLAGS= + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/adiff/src/adiff.cpp b/adiff/src/adiff.cpp new file mode 100644 index 0000000000..31614290c0 --- /dev/null +++ b/adiff/src/adiff.cpp @@ -0,0 +1,70 @@ +/* + * diff + * + * Usage: diff [-V] [-t difftype] [diff-options] input1 input2 + * + * Authors: + * + */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <err.h> +#include <stdlib.h> +#include <sys/stat.h> + +#define PROGNAME "./adiff.%s" +#define VERSION "0.0.1" +#define USAGE "adiff [-V] -t difftype [diff-options] input1 input2" + +int main(int argc, char *argv[]) { + if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))) { + char* program_name = argv[0]; + char* p = NULL; + if ((p = strrchr(program_name, '/')) != NULL) + program_name = p + 1; + + printf("%s (%s)\n", program_name, VERSION); + exit(EXIT_SUCCESS); + } + + char* difftype = NULL; + int i, verbose = 0; + + while ((i = getopt(argc, argv, "Vt:")) != -1) + switch (i) { + case 'V': + verbose = 1; + break; + case 't': + difftype = optarg; + break; + default: + optind--; + goto more; + } +more: + + if (optind == argc || difftype == NULL) { + fprintf(stderr, "Usage: %s\n", USAGE); + return EXIT_FAILURE; + } + + if (verbose) + argv[--optind] = (char*) "-V"; + + char* program_name = (char*) malloc(sizeof(PROGNAME) - 3 + strlen(difftype) + 1); + sprintf(program_name, PROGNAME, difftype); + + argv[--optind] = program_name + 2; + + struct stat buffer; + if(stat (program_name, &buffer)) { + program_name += 2; + } + + execvp(program_name, argv + optind); + perror(program_name); + return EXIT_FAILURE; +} diff --git a/aepsilon/makefile b/aepsilon/makefile new file mode 100644 index 0000000000..f8ca8f76bd --- /dev/null +++ b/aepsilon/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aepsilon +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aepsilon/src/EpsilonClosure.cpp b/aepsilon/src/EpsilonClosure.cpp index 06972d3baf..11650dfe90 100644 --- a/aepsilon/src/EpsilonClosure.cpp +++ b/aepsilon/src/EpsilonClosure.cpp @@ -18,11 +18,11 @@ EpsilonClosure::EpsilonClosure( const set<State> & states, const std::map<automaton::State, std::set<automaton::TransitionFSM>> & transitionsBySource ) : m_transitionsBySource( transitionsBySource ), m_states ( states ) { - for( auto state : m_states ) + for( const auto & state : m_states ) closure( state ); } -set<TransitionFSM> EpsilonClosure::getTr ( const State & state ) const +const set<TransitionFSM> EpsilonClosure::getTransitionsFromState ( const State & state ) const { if( m_transitionsBySource.find( state ) == m_transitionsBySource.end( ) ) return set<TransitionFSM>(); @@ -35,25 +35,25 @@ void EpsilonClosure::closure( const State & state ) queue<State> q; map<State, bool> visited; - for( auto state : m_states ) + for( const auto & state : m_states ) visited[ state ] = false; q.push( state ); while( ! q.empty( ) ) { - State & s = q.front( ); + const State & s = q.front( ); q.pop( ); - visited[s] = true; + visited[ s ] = true; m_closure[ state ].insert( s ); - for( auto transition : getTr( s ) ) + for( const auto & transition : getTransitionsFromState( s ) ) if( transition.getInput() == Symbol( "" ) && visited [ transition.getTo( ) ] == false ) q.push( transition.getTo( ) ); } } -set<State> EpsilonClosure::getClosure( const State & state ) const +const set<State> & EpsilonClosure::getClosure( const State & state ) const { if( m_closure.find( state ) == m_closure.end( ) ) throw AlibException( "EpsilonClosure: Trying to get closure of state not in automata." ); diff --git a/aepsilon/src/EpsilonClosure.h b/aepsilon/src/EpsilonClosure.h index 226afd11bf..db525af9fb 100644 --- a/aepsilon/src/EpsilonClosure.h +++ b/aepsilon/src/EpsilonClosure.h @@ -24,11 +24,11 @@ class EpsilonClosure { public: EpsilonClosure( const std::set<automaton::State> & states, const std::map<automaton::State, std::set<automaton::TransitionFSM>> & transitionsBySource ); - std::set<automaton::State> getClosure( const automaton::State & state ) const; + const std::set<automaton::State> & getClosure( const automaton::State & state ) const; private: void closure( const automaton::State & state ); - std::set<automaton::TransitionFSM> getTr ( const automaton::State & state ) const; + const std::set<automaton::TransitionFSM> getTransitionsFromState ( const automaton::State & state ) const; std::map<const automaton::State, std::set<automaton::State>> m_closure; const std::map<automaton::State, std::set<automaton::TransitionFSM>> & m_transitionsBySource; diff --git a/aepsilon/src/EpsilonRemover.cpp b/aepsilon/src/EpsilonRemover.cpp index 31de47e53a..66226c2cc8 100644 --- a/aepsilon/src/EpsilonRemover.cpp +++ b/aepsilon/src/EpsilonRemover.cpp @@ -15,18 +15,18 @@ namespace epsilon EpsilonRemover::EpsilonRemover( const FSM & fsm ) : m_origFSM( fsm ) { - for( auto t : fsm.getTransitions( ) ) + for( const auto & t : fsm.getTransitions( ) ) m_transitionsBySourceState[ t.getFrom() ].insert( t ); m_closure = new EpsilonClosure( fsm.getStates( ), m_transitionsBySourceState ); - for( auto state : fsm.getStates() ) + for( const auto & state : fsm.getStates() ) m_fsm.addState( state ); - for( auto state : fsm.getInitialStates() ) + for( const auto & state : fsm.getInitialStates() ) m_fsm.addInitialState( state ); - for( auto symbol : fsm.getInputAlphabet() ) + for( const auto & symbol : fsm.getInputAlphabet() ) m_fsm.addInputSymbol( symbol ); } @@ -48,9 +48,9 @@ const FSM EpsilonRemover::remove( void ) */ void EpsilonRemover::setTransitions( void ) { - for( auto q : m_fsm.getStates( ) ) - for( auto p : m_closure->getClosure( q ) ) - for( auto transition : m_transitionsBySourceState[p] ) + for( const auto & q : m_fsm.getStates( ) ) + for( const auto & p : m_closure->getClosure( q ) ) + for( const auto & transition : m_transitionsBySourceState[p] ) if( transition.getInput() != Symbol( "" ) ) m_fsm.addTransition( q, transition.getInput( ), transition.getTo( ) ); } @@ -60,25 +60,20 @@ void EpsilonRemover::setTransitions( void ) */ void EpsilonRemover::setFinalStates( void ) { - for( auto q : m_fsm.getStates( ) ) + set<State> finalStates; + + for( const auto & q : m_fsm.getStates( ) ) { - set<State> cl = m_closure->getClosure( q ); - set<State> f = m_origFSM.getFinalStates( ); + const set<State> & cl = m_closure->getClosure( q ), & F = m_origFSM.getFinalStates( ); set<State> intersect; - set_intersection( cl.begin(), cl.end(), f.begin(), f.end(), std::inserter( intersect, intersect.begin() ) ); - if( intersect.size() != 0 ) - { - try - { - m_fsm.addFinalState( q ); - } - catch( AlibException & e ) - { - // already final state. proceed - } - } + set_intersection( cl.begin(), cl.end(), F.begin(), F.end(), std::inserter( intersect, intersect.begin() ) ); + if( intersect.size( ) != 0 ) + finalStates.insert( q ); } + + for( const auto & q : finalStates ) + m_fsm.addFinalState( q ); } } /* namespace epsilon */ diff --git a/alib/makefile b/alib/makefile index 6d1a3f5044..c397f43efc 100644 --- a/alib/makefile +++ b/alib/makefile @@ -1,13 +1,20 @@ +CC=g++ LIBRARY=libalib.so -CXXFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ +CCFLAGS= -std=c++11 -O2 -c -Wall -fPIC -I/usr/include/libxml2/ LDFLAGS= -shared -lxml2 +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) -SOURCES = src/automaton/*.cpp src/automaton/TM/*.cpp src/automaton/FSM/*.cpp src/automaton/PDA/*cpp src/automaton/exception/*.cpp src/regexp/*.cpp src/grammar/*.cpp src/grammar/Regular/*.cpp src/grammar/Linear/*.cpp src/grammar/Unrestricted/*.cpp src/grammar/ContextSensitive/*.cpp src/grammar/ContextFree/*.cpp src/sax/*.cpp src/alphabet/*.cpp src/*.cpp +all: $(SOURCES) lib/$(LIBRARY) -all: - g++ $(CXXFLAGS) $(SOURCES) - g++ $(LDFLAGS) *.o -o $(LIBRARY) +lib/$(LIBRARY): $(OBJECTS) + mkdir -p lib + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ clean: - $(RM) *.o *.d $(LIBRARY) + $(RM) -r *.o *.d lib obj diff --git a/alib/src/AutomatonFactory.cpp b/alib/src/AutomatonFactory.cpp index dabb7b1010..9fe20e2ea0 100644 --- a/alib/src/AutomatonFactory.cpp +++ b/alib/src/AutomatonFactory.cpp @@ -8,6 +8,7 @@ #include "AutomatonFactory.h" #include <algorithm> +#include <iostream> #include "sax/Token.h" #include "sax/SaxInterface.h" @@ -30,6 +31,15 @@ UnknownAutomaton AutomatonFactory::fromString(const string& str) { return parse(tokens); } +UnknownAutomaton AutomatonFactory::fromStdin() { + return AutomatonFactory::fromStream(cin); +} + +UnknownAutomaton AutomatonFactory::fromStream(std::istream& in) { + string input(istreambuf_iterator<char>(in), (istreambuf_iterator<char>())); + return AutomatonFactory::fromString(input); +} + UnknownAutomaton AutomatonFactory::parse(list<Token> tokens) { AutomatonParser parser; return parser.parse(tokens); diff --git a/alib/src/AutomatonFactory.h b/alib/src/AutomatonFactory.h index 3c337d6c47..8a987ca94c 100644 --- a/alib/src/AutomatonFactory.h +++ b/alib/src/AutomatonFactory.h @@ -37,10 +37,22 @@ public: * @return UnknownAutomaton */ static UnknownAutomaton fromString(const string& str); + + /** + * Parses the XML from stdin and returns UnknownAutomaton. + * @return UnknownAutomaton + */ + static UnknownAutomaton fromStdin(); + + /** + * Parses the XML from stream and returns UnknownAutomaton. + * @return UnknownAutomaton + */ + static UnknownAutomaton fromStream(std::istream& in); /** * Tries to create specific automaton from UnknownAutomaton. - * @param automaton source UnknownAutomatn + * @param automaton source UnknownAutomaton * @return pointer to new automaton * @throws AutomatonException when specific automaton cannot * be created form UnknownAutomaton (e.g. automaton type is not recognized) diff --git a/alib/src/GrammarFactory.cpp b/alib/src/GrammarFactory.cpp index 74c1203801..40cf81b817 100644 --- a/alib/src/GrammarFactory.cpp +++ b/alib/src/GrammarFactory.cpp @@ -5,6 +5,8 @@ * Author: martin */ +#include <iostream> + #include "GrammarFactory.h" #include "sax/SaxInterface.h" @@ -24,6 +26,16 @@ UnknownGrammar GrammarFactory::fromString(const string& str) { return parse(tokens); } +UnknownGrammar GrammarFactory::fromStdin() { + return GrammarFactory::fromStream(cin); +} + +UnknownGrammar GrammarFactory::fromStream(std::istream& in) { + string input(istreambuf_iterator<char>(in), (istreambuf_iterator<char>())); + return GrammarFactory::fromString(input); +} + + UnknownGrammar GrammarFactory::parse(list<sax::Token> tokens) { GrammarParser parser; return parser.parse(tokens); diff --git a/alib/src/GrammarFactory.h b/alib/src/GrammarFactory.h index d622843f5e..440a70c8c6 100644 --- a/alib/src/GrammarFactory.h +++ b/alib/src/GrammarFactory.h @@ -21,7 +21,6 @@ namespace grammar { using namespace std; -using namespace sax; /** * Builds specific grammars from UnknownGrammar. @@ -41,6 +40,18 @@ public: * @return UnknownGrammar */ static UnknownGrammar fromString(const string& str); + + /** + * Parses the XML from stdin and returns UnknownGrammar. + * @return UnknownGrammar + */ + static UnknownGrammar fromStdin(); + + /** + * Parses the XML from stream and returns the UnknownGrammar. + * @return RegExp + */ + static UnknownGrammar fromStream(std::istream& in); /** * Tries to build RightRegularGrammar from any grammar. @@ -104,7 +115,7 @@ protected: * @param tokens XML represented as list of tokens * @return parsed UnknownGrammar */ - static UnknownGrammar parse(list<Token> tokens); + static UnknownGrammar parse(list<sax::Token> tokens); }; } /* namespace grammar */ diff --git a/alib/src/RegExpFactory.cpp b/alib/src/RegExpFactory.cpp index 0d5d9c514f..e8d54eaf5f 100644 --- a/alib/src/RegExpFactory.cpp +++ b/alib/src/RegExpFactory.cpp @@ -5,6 +5,8 @@ * Author: martin */ +#include <iostream> + #include "sax/SaxInterface.h" #include "RegExpFactory.h" #include "regexp/RegExpParser.h" @@ -14,13 +16,25 @@ namespace regexp { RegExp RegExpFactory::fromFile(const string& filename) { std::list<Token> tokens; SaxInterface::parseFile(filename, tokens); - RegExpParser parser; - return parser.parse(tokens); + return parse(tokens); } RegExp RegExpFactory::fromString(const string& str) { list<Token> tokens; SaxInterface::parseMemory(str, tokens); + return parse(tokens); +} + +RegExp RegExpFactory::fromStdin() { + return RegExpFactory::fromStream(cin); +} + +RegExp RegExpFactory::fromStream(std::istream& in) { + string input(istreambuf_iterator<char>(in), (istreambuf_iterator<char>())); + return RegExpFactory::fromString(input); +} + +RegExp RegExpFactory::parse(list<sax::Token> tokens) { RegExpParser parser; return parser.parse(tokens); } diff --git a/alib/src/RegExpFactory.h b/alib/src/RegExpFactory.h index e81874405c..510ddddc1d 100644 --- a/alib/src/RegExpFactory.h +++ b/alib/src/RegExpFactory.h @@ -8,11 +8,13 @@ #ifndef REGEXPFACTORY_H_ #define REGEXPFACTORY_H_ +#include "sax/Token.h" #include "regexp/RegExp.h" namespace regexp { using namespace std; +using namespace sax; /** * RegExp builder. @@ -32,6 +34,26 @@ public: * @return RegExp */ static RegExp fromString(const string& str); + + /** + * Parses the XML from stdin and returns the RegExp. + * @return RegExp + */ + static RegExp fromStdin(); + + /** + * Parses the XML from stream and returns the RegExp. + * @return RegExp + */ + static RegExp fromStream(std::istream& in); + +protected: + /** + * Parses the RegExp from list of tokens. + * @param tokens XML represented as list of tokens + * @return parsed RegExp + */ + static RegExp parse(list<Token> tokens); }; } /* namespace regexp */ diff --git a/alib/src/alphabet/Epsilon.cpp b/alib/src/alphabet/Epsilon.cpp new file mode 100644 index 0000000000..22f884f597 --- /dev/null +++ b/alib/src/alphabet/Epsilon.cpp @@ -0,0 +1,34 @@ +/* + * Epsilon.cpp + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#include "Epsilon.h" + +namespace alphabet { + +Epsilon::Epsilon() { + +} + +bool Epsilon::operator <(const Epsilon& other) const { + return false; +} + +bool Epsilon::operator ==(const Epsilon& other) const { + return true; +} + +bool Epsilon::operator !=(const Epsilon& other) const { + return false; +} + +std::ostream& operator<<(std::ostream& out, const Epsilon& symbol) { + + out << "Epsilon"; + return out; +} + +} /* namespace language */ diff --git a/alib/src/alphabet/Epsilon.h b/alib/src/alphabet/Epsilon.h new file mode 100644 index 0000000000..d36616d7ac --- /dev/null +++ b/alib/src/alphabet/Epsilon.h @@ -0,0 +1,32 @@ +/* + * Epsilon.h + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#ifndef EPSILON_H_ +#define EPSILON_H_ + +#include <ostream> + +namespace alphabet { + +/** + * Represents empty word. + */ +class Epsilon { +public: + /** + * Creates new empty string. + */ + Epsilon(); + + bool operator <(const Epsilon& other) const; + bool operator ==(const Epsilon& other) const; + bool operator !=(const Epsilon& other) const; + + friend std::ostream& operator<<(std::ostream&, const Epsilon&); +}; +} +#endif /* EPSILON_H_ */ diff --git a/alib/src/regexp/RegExpEmpty.cpp b/alib/src/regexp/RegExpEmpty.cpp new file mode 100644 index 0000000000..3c5b5711ac --- /dev/null +++ b/alib/src/regexp/RegExpEmpty.cpp @@ -0,0 +1,20 @@ +/* + * RegExpEmpty.cpp + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#include "RegExpEmpty.h" + +namespace regexp { + +RegExpEmpty::RegExpEmpty() { +} + +RegExpElement* RegExpEmpty::clone() const { + return new RegExpEmpty(); +} + +} /* namespace regexp */ + diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h new file mode 100644 index 0000000000..937d04e679 --- /dev/null +++ b/alib/src/regexp/RegExpEmpty.h @@ -0,0 +1,31 @@ +/* + * RegExpEmpty.h + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#ifndef REGEXPEMPTY_H_ +#define REGEXPEMPTY_H_ + +#include "RegExpElement.h" + +namespace regexp { + +using namespace std; + +/** + * Represents empty regular expression in the regular expression. + */ +class RegExpEmpty: public RegExpElement { +public: + RegExpEmpty(); + + /** + * @copydoc RegExpElement::clone() const + */ + RegExpElement* clone() const; +}; + +} /* namespace regexp */ +#endif /* REGEXPEMPTY_H_ */ diff --git a/alib/src/regexp/RegExpEpsilon.cpp b/alib/src/regexp/RegExpEpsilon.cpp new file mode 100644 index 0000000000..fff799e81c --- /dev/null +++ b/alib/src/regexp/RegExpEpsilon.cpp @@ -0,0 +1,20 @@ +/* + * RegExpEpsilon.cpp + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#include "RegExpEpsilon.h" + +namespace regexp { + +RegExpEpsilon::RegExpEpsilon() { +} + +RegExpElement* RegExpEpsilon::clone() const { + return new RegExpEpsilon(); +} + +} /* namespace regexp */ + diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h new file mode 100644 index 0000000000..2d48546fcc --- /dev/null +++ b/alib/src/regexp/RegExpEpsilon.h @@ -0,0 +1,33 @@ +/* + * RegExpEpsilon.h + * + * Created on: Jan 30, 2014 + * Author: honza + */ + +#ifndef REGEXPEPSILON_H_ +#define REGEXPEPSILON_H_ + +#include "RegExpElement.h" +#include "../alphabet/Epsilon.h" + +namespace regexp { + +using namespace std; +using namespace alphabet; + +/** + * Represents epsilon in the regular expression. + */ +class RegExpEpsilon: public RegExpElement, public Epsilon { +public: + RegExpEpsilon(); + + /** + * @copydoc RegExpElement::clone() const + */ + RegExpElement* clone() const; +}; + +} /* namespace regexp */ +#endif /* REGEXPEPSILON_H_ */ diff --git a/alib/src/regexp/RegExpParser.cpp b/alib/src/regexp/RegExpParser.cpp index 24d02f0f52..5bcad37145 100644 --- a/alib/src/regexp/RegExpParser.cpp +++ b/alib/src/regexp/RegExpParser.cpp @@ -22,6 +22,10 @@ RegExp RegExpParser::parse(list<Token>& input) { RegExpElement* RegExpParser::parseElement(list<Token>& input) { if (isToken(input, Token::START_ELEMENT, "symbol")) { return parseSymbol(input); + } else if (isToken(input, Token::START_ELEMENT, "empty")) { + return parseEmpty(input); + } else if (isToken(input, Token::START_ELEMENT, "epsilon")) { + return parseEpsilon(input); } else if (isToken(input, Token::START_ELEMENT, "iteration")) { return parseIteration(input); } else if (isToken(input, Token::START_ELEMENT, "alternation")) { @@ -66,37 +70,38 @@ Iteration* RegExpParser::parseIteration(list<Token>& input) { void RegExpParser::parseContent(list<Token>& input, list<RegExpElement*>& elements) { while (true) { - if (isToken(input, Token::START_ELEMENT, "symbol")) { - elements.push_back(parseSymbol(input)); - } else if (isToken(input, Token::START_ELEMENT, "iteration")) { - elements.push_back(parseIteration(input)); - } else if (isToken(input, Token::START_ELEMENT, "alternation")) { - elements.push_back(parseAlternation(input)); - } else if (isToken(input, Token::START_ELEMENT, "concatenation")) { - elements.push_back(parseConcatenation(input)); - } else { - return; - } + RegExpElement* element = parseElement(input); + if(!element) return; + elements.push_back(element); } +} + +RegExpEpsilon* RegExpParser::parseEpsilon(list<Token>& input) { + popToken(input, Token::START_ELEMENT, "epsilon"); + + RegExpEpsilon* epsilon = new RegExpEpsilon(); + popToken(input, Token::END_ELEMENT, "epsilon"); + return epsilon; } -RegExpSymbol* RegExpParser::parseSymbol(list<Token>& input, string tagName) { - popToken(input, Token::START_ELEMENT, tagName); +RegExpEmpty* RegExpParser::parseEmpty(list<Token>& input) { + popToken(input, Token::START_ELEMENT, "empty"); + + RegExpEmpty* empty = new RegExpEmpty(); + + popToken(input, Token::END_ELEMENT, "empty"); + return empty; +} + +RegExpSymbol* RegExpParser::parseSymbol(list<Token>& input) { + popToken(input, Token::START_ELEMENT, "symbol"); if (input.front().getType() == Token::CHARACTER) { RegExpSymbol* symbol = new RegExpSymbol(input.front().getData()); input.pop_front(); - popToken(input, Token::END_ELEMENT, tagName); + popToken(input, Token::END_ELEMENT, "symbol"); return symbol; - } else if (isToken(input, Token::END_ELEMENT, tagName)) { - input.pop_front(); - return new RegExpSymbol(""); - } else if (isToken(input, Token::START_ELEMENT, "eps")) { - input.pop_front(); - popToken(input, Token::END_ELEMENT, "eps"); - popToken(input, Token::END_ELEMENT, tagName); - return new RegExpSymbol(""); } else { throw ParserException(Token("", Token::CHARACTER), input.front()); } diff --git a/alib/src/regexp/RegExpParser.h b/alib/src/regexp/RegExpParser.h index 1422ec25fa..126f20ee5d 100644 --- a/alib/src/regexp/RegExpParser.h +++ b/alib/src/regexp/RegExpParser.h @@ -11,6 +11,8 @@ #include "RegExp.h" #include "../sax/Token.h" #include "RegExpSymbol.h" +#include "RegExpEpsilon.h" +#include "RegExpEmpty.h" #include "Alternation.h" #include "Concatenation.h" @@ -28,7 +30,9 @@ protected: static void parseContent(list<Token>& input, list<RegExpElement*>& elements); static RegExpElement* parseElement(list<Token>& input); - static RegExpSymbol* parseSymbol(list<Token> &input, string tagName = "symbol"); + static RegExpEpsilon* parseEpsilon(list<Token>& input); + static RegExpEmpty* parseEmpty(list<Token>& input); + static RegExpSymbol* parseSymbol(list<Token> &input); static Iteration* parseIteration(list<Token> &input); static Alternation* parseAlternation(list<Token> &input); static Concatenation* parseConcatenation(list<Token> &input); diff --git a/alib/src/regexp/RegExpPrinter.cpp b/alib/src/regexp/RegExpPrinter.cpp index b9b5a35b19..223ab54691 100644 --- a/alib/src/regexp/RegExpPrinter.cpp +++ b/alib/src/regexp/RegExpPrinter.cpp @@ -36,6 +36,18 @@ void RegExpPrinter::printElement(RegExpElement* element, ostream& out, string pr return; } + RegExpEpsilon* epsilon = dynamic_cast<RegExpEpsilon*>(element); + if (epsilon) { + printEpsilon(epsilon, out, prefix); + return; + } + + RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>(element); + if (empty) { + printEmpty(empty, out, prefix); + return; + } + RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>(element); if (symbol) { printSymbol(symbol, out, prefix); @@ -47,7 +59,6 @@ void RegExpPrinter::printElement(RegExpElement* element, ostream& out, string pr void RegExpPrinter::printContent(list<RegExpElement*>& content, ostream& out, string prefix) { for (auto element : content) { printElement(element, out, prefix); - } } @@ -76,5 +87,15 @@ void RegExpPrinter::printSymbol(RegExpSymbol* symbol, ostream& out, string prefi out << "</symbol>\n"; } +void RegExpPrinter::printEpsilon(RegExpEpsilon* symbol, ostream& out, string prefix) { + out << prefix << "<epsilon>"; + out << "</epsilon>\n"; +} + +void RegExpPrinter::printEmpty(RegExpEmpty* symbol, ostream& out, string prefix) { + out << prefix << "<empty>"; + out << "</empty>\n"; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpPrinter.h b/alib/src/regexp/RegExpPrinter.h index 00466c8ba1..49ba46d027 100644 --- a/alib/src/regexp/RegExpPrinter.h +++ b/alib/src/regexp/RegExpPrinter.h @@ -14,6 +14,8 @@ #include "Concatenation.h" #include "Iteration.h" #include "RegExpSymbol.h" +#include "RegExpEpsilon.h" +#include "RegExpEmpty.h" namespace regexp { @@ -32,6 +34,8 @@ protected: static void printIteration(Iteration* iteration, ostream& out, string prefix); static void printSymbol(RegExpSymbol* symbol, ostream& out, string prefix); + static void printEpsilon(RegExpEpsilon* symbol, ostream& out, string prefix); + static void printEmpty(RegExpEmpty* symbol, ostream& out, string prefix); public: /** diff --git a/alib/src/std/istream.cpp b/alib/src/std/istream.cpp new file mode 100644 index 0000000000..f12a3dceb8 --- /dev/null +++ b/alib/src/std/istream.cpp @@ -0,0 +1,27 @@ +#include "istream.h" + +std::istream& oprr(std::istream& in, const std::string& str, bool start) { + if(str.size() == 0) return in; + char c_str = str[0]; + char c_in = in.peek(); + in.get(); + if(in.good()) { + if(start && (c_in == ' ' || c_in == '\n' || c_in == '\t')) { + oprr(in, str, start); + } else if(c_str == c_in) { + oprr(in, str.substr(1), false); + } else { + in.clear(std::ios::failbit); + } + } + if(in.fail()) { + in.clear(); + in.putback(c_in); + in.clear(std::ios::failbit); + } + return in; +} + +std::istream& operator>>(std::istream& in, const std::string& str) { + return oprr(in, str, true); +} \ No newline at end of file diff --git a/alib/src/std/istream.h b/alib/src/std/istream.h new file mode 100644 index 0000000000..4b285b3d2b --- /dev/null +++ b/alib/src/std/istream.h @@ -0,0 +1,4 @@ +#include <iostream> +#include <string> + +std::istream& operator>>(std::istream& in, const std::string& str); diff --git a/aminimize/makefile b/aminimize/makefile new file mode 100644 index 0000000000..e9430cbc2d --- /dev/null +++ b/aminimize/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTIBLE=aminimize +CCFLAGS= -std=c++11 -O2 -c -Wall -I../alib/src +LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,. + +SOURCES=$(shell find src/ -name *cpp) +OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES)) + +all: $(SOURCES) bin/$(EXECUTIBLE) + +bin/$(EXECUTIBLE): $(OBJECTS) + mkdir -p bin + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aminimize/src/Minimize.cpp b/aminimize/src/Minimize.cpp new file mode 100644 index 0000000000..71c6eb173f --- /dev/null +++ b/aminimize/src/Minimize.cpp @@ -0,0 +1,122 @@ +/* + * Minimize.cpp + * + * Created on: Dec 9, 2013 + * Author: honza + */ + +#include "Minimize.h" + +#include <map> +#include <set> +#include <sstream> +#include <iostream> + +#include "alphabet/Symbol.h" +#include "automaton/FSM/TransitionFSM.h" + +automaton::State fromInteger(int number) { + std::stringstream ss; + ss << number; + return automaton::State(ss.str()); +} + +automaton::FSM Minimize::minimize(automaton::FSM& fsm) { + std::map<automaton::State, std::map<alphabet::Symbol, automaton::State > > refactor; + + for(std::set<automaton::State>::const_iterator iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) { + refactor.insert(std::pair<automaton::State, std::map<alphabet::Symbol, automaton::State> >(*iter, std::map<alphabet::Symbol, automaton::State>())); + } + + for(std::set<automaton::TransitionFSM>::const_iterator iter = fsm.getTransitions().begin(); iter != fsm.getTransitions().end(); iter++) { + refactor[iter->getFrom()].insert(std::pair<alphabet::Symbol, automaton::State>(iter->getInput(), iter->getTo())); + } + + std::map<automaton::State, automaton::State> toEquvivalentStates1;//original state to equivalent state + std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction1; //mapped to the original state + + std::map<automaton::State, automaton::State> toEquvivalentStates2; + std::map<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> > minimizedTransitionFunction2; + + for(auto iter = fsm.getStates().begin(); iter != fsm.getStates().end(); iter++) { + if(fsm.getFinalStates().count(*iter) == 0) { // not a final state + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("0"))); + } else { + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter, automaton::State("1"))); + } + } + + for(auto iter = refactor.begin(); iter != refactor.end(); iter++) { + automaton::State from = toEquvivalentStates2.find(iter->first)->second; + std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction; + + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second)); + } + + std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction); + + if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) { + minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>())); + } + minimizedTransitionFunction2[key].insert(iter->first); + } + + do { + toEquvivalentStates1 = toEquvivalentStates2; + minimizedTransitionFunction1 = minimizedTransitionFunction2; + + toEquvivalentStates2.clear(); + minimizedTransitionFunction2.clear(); + + int number = 0; + for(auto iter = minimizedTransitionFunction1.begin(); iter != minimizedTransitionFunction1.end(); iter++) { + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + toEquvivalentStates2.insert(std::pair<automaton::State, automaton::State>(*iter2, fromInteger(number))); + } + number++; + } + + for(auto iter = refactor.begin(); iter != refactor.end(); iter++) { + automaton::State from = toEquvivalentStates2.find(iter->first)->second; + std::set<std::pair<alphabet::Symbol, automaton::State> > transitionFunction; + + for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + transitionFunction.insert(std::pair<alphabet::Symbol, automaton::State>(iter2->first, toEquvivalentStates2.find(iter2->second)->second)); + } + + std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > > key(from, transitionFunction); + + if(minimizedTransitionFunction2.find(key) == minimizedTransitionFunction2.end()) { + minimizedTransitionFunction2.insert(std::pair<std::pair<automaton::State, std::set<std::pair<alphabet::Symbol, automaton::State> > >, std::set<automaton::State> >(key, std::set<automaton::State>())); + } + + minimizedTransitionFunction2[key].insert(iter->first); + + } + + } while(minimizedTransitionFunction1.size() != minimizedTransitionFunction2.size()); + + automaton::FSM result; + for(auto iter = fsm.getInputAlphabet().begin(); iter != fsm.getInputAlphabet().end(); iter++) { + result.addInputSymbol(*iter); + } + + for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) { + result.addState(iter->first.first); + if(fsm.getFinalStates().find(*(iter->second.begin())) != fsm.getFinalStates().end()) {//TODO improve using intersection + result.addFinalState(iter->first.first); + } + if(iter->second.find(*(fsm.getInitialStates().begin())) != iter->second.end()) { //TODO improve using intersection + result.addInitialState(iter->first.first); + } + } + + for(auto iter = minimizedTransitionFunction2.begin(); iter != minimizedTransitionFunction2.end(); iter++) { + for(auto iter2 = iter->first.second.begin(); iter2 != iter->first.second.end(); iter2++) { + result.addTransition(iter->first.first, iter2->first, iter2->second); + } + } + + return result; +} diff --git a/aminimize/src/Minimize.h b/aminimize/src/Minimize.h new file mode 100644 index 0000000000..51db0171da --- /dev/null +++ b/aminimize/src/Minimize.h @@ -0,0 +1,19 @@ +/* + * Minimize.h + * + * Created on: Dec 9, 2013 + * Author: honza + */ + +#ifndef MINIMIZE_H_ +#define MINIMIZE_H_ + +#include "automaton/FSM/FSM.h" + +class Minimize { +public: + static automaton::FSM minimize(automaton::FSM& fsm); + +}; + +#endif /* MINIMIZE_H_ */ diff --git a/aminimize/src/aminimize.cpp b/aminimize/src/aminimize.cpp new file mode 100644 index 0000000000..c564de72f5 --- /dev/null +++ b/aminimize/src/aminimize.cpp @@ -0,0 +1,61 @@ +//============================================================================ +// Name : aminimize.cpp +// Author : Jan Travnicek +//============================================================================ + +#include <iostream> +#include <string> +#include <set> + +#include "AutomatonFactory.h" +#include "AlibException.h" +#include "automaton/AutomatonParser.h" + +#include "Minimize.h" + +using namespace std; +using namespace automaton; +using namespace alib; + +int main(int argc, char** argv) { + + UnknownAutomaton automaton; + + try { + + if (argc == 2 && string("-h").compare(argv[1]) == 0) { + cout << "Automaton minimize.\nUsage: aminimize automaton.xml\n"; + return -1; + } else if (argc == 1 || argc == 2 && string("--").compare(argv[1]) == 0) { + automaton = AutomatonFactory::fromStdin(); + if(!AutomatonFactory::isFSM(automaton)) { + cout << "Automaton minimize require deterministic finite automaton\n"; + return 1; + } + } else if (argc == 2) { + automaton = AutomatonFactory::fromFile(argv[1]); + if(!AutomatonFactory::isFSM(automaton)) { + cout << "Automaton minimize require deterministic finite automaton\n"; + return 1; + } + } else { + cout << "Automaton minimize require finite automaton\n"; + return 1; + } + automaton::FSM fsm = AutomatonFactory::buildFSM(automaton); + if(!fsm.isDeterministic()) { + cout << "Automaton minimize require deterministic finite automaton\n"; + return 1; + } + + automaton::FSM res = Minimize::minimize(fsm); + res.toXML(cout); + + return 0; + + } catch (AlibException& e) { + cout << e.getCause() << endl; + return 0; + } + +} diff --git a/atrim/src/TrimNFA.cpp b/atrim/src/TrimNFA.cpp index d8796faa0d..1d8badc7b7 100644 --- a/atrim/src/TrimNFA.cpp +++ b/atrim/src/TrimNFA.cpp @@ -25,34 +25,36 @@ const FSM TrimNFA::remove( void ) { set<State> reachableStates = findReachableStates( ); - for( auto q : reachableStates ) + for( auto const & q : reachableStates ) m_FSM.addState( q ); - for( auto symbol : m_origFSM.getInputAlphabet( ) ) + for( auto const & symbol : m_origFSM.getInputAlphabet( ) ) m_FSM.addInputSymbol( symbol ); - for( auto t : m_origFSM.getTransitions( ) ) + for( auto const & t : m_origFSM.getTransitions( ) ) if( isInSet( t.getFrom( ), reachableStates ) ) m_FSM.addTransition( t ); - for( auto state : m_origFSM.getInitialStates( ) ) + for( auto const & state : m_origFSM.getInitialStates( ) ) m_FSM.addInitialState( state ); - set<State> intersect, F = m_origFSM.getFinalStates( ); + + set<State> intersect; + const set<State> & F = m_origFSM.getFinalStates( ); set_intersection( F.begin(), F.end(), reachableStates.begin(), reachableStates.end(), inserter( intersect, intersect.begin() ) ); - for( auto state : intersect ) + + for( auto const & state : intersect ) m_FSM.addFinalState( state ); return m_FSM; } - -set<State> TrimNFA::findReachableStates( void ) const +const set<State> TrimNFA::findReachableStates( void ) const { map<State, set<TransitionFSM>> transitionsBySourceState; - for( auto t : m_origFSM.getTransitions( ) ) + for( auto const & t : m_origFSM.getTransitions( ) ) transitionsBySourceState[ t.getFrom() ].insert( t ); set<State> qprev, qcurr; @@ -62,8 +64,8 @@ set<State> TrimNFA::findReachableStates( void ) const { qprev = qcurr; - for( auto p : qprev ) - for( auto transition : transitionsBySourceState[ p ] ) + for( auto const & p : qprev ) + for( auto const & transition : transitionsBySourceState[ p ] ) qcurr.insert( transition.getTo() ); } while( qcurr != qprev ); @@ -71,5 +73,4 @@ set<State> TrimNFA::findReachableStates( void ) const return qcurr; } - } /* namespace trim */ diff --git a/atrim/src/TrimNFA.h b/atrim/src/TrimNFA.h index 6fc972033b..11523caa52 100644 --- a/atrim/src/TrimNFA.h +++ b/atrim/src/TrimNFA.h @@ -31,7 +31,7 @@ public: const automaton::FSM remove( void ); private: - std::set<automaton::State> findReachableStates( void ) const; + const std::set<automaton::State> findReachableStates( void ) const; const automaton::FSM & m_origFSM; automaton::FSM m_FSM; diff --git a/examples/NFSM1.DET.xml b/examples/NFSM1.DET.xml new file mode 100644 index 0000000000..1a550357ab --- /dev/null +++ b/examples/NFSM1.DET.xml @@ -0,0 +1,60 @@ +<automaton> + <states> + <state>['A', 'C', 'S']</state> + <state>['A', 'S']</state> + <state>['B', 'S']</state> + <state>['S']</state> + </states> + <inputAlphabet> + <symbol>0</symbol> + <symbol>1</symbol> + </inputAlphabet> + <transitions> + <transition> + <from>['A', 'C', 'S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['A', 'C', 'S']</from> + <input>1</input> + <to>['B', 'S']</to> + </transition> + <transition> + <from>['A', 'S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['A', 'S']</from> + <input>1</input> + <to>['B', 'S']</to> + </transition> + <transition> + <from>['B', 'S']</from> + <input>0</input> + <to>['A', 'C', 'S']</to> + </transition> + <transition> + <from>['B', 'S']</from> + <input>1</input> + <to>['S']</to> + </transition> + <transition> + <from>['S']</from> + <input>0</input> + <to>['A', 'S']</to> + </transition> + <transition> + <from>['S']</from> + <input>1</input> + <to>['S']</to> + </transition> + </transitions> + <initialStates> + <state>['S']</state> + </initialStates> + <finalStates> + <state>['A', 'C', 'S']</state> + </finalStates> +</automaton> diff --git a/examples/VPA1.xml b/examples/VPA1.xml new file mode 100644 index 0000000000..0565f6aef8 --- /dev/null +++ b/examples/VPA1.xml @@ -0,0 +1,67 @@ +<automaton> + <states> + <state>0</state> + <state>1</state> + </states> + <inputAlphabet> + <symbol>a</symbol> + <symbol>b</symbol> + <symbol>c</symbol> + </inputAlphabet> + <stackAlphabet> + <symbol>s</symbol> + <symbol>⊥</symbol> + </stackAlphabet> + <transitions> + <transition> + <from>0</from> + <input>a</input> + <to>0</to> + <pop> + </pop> + <push> + <symbol>s</symbol> + </push> + </transition> + <transition> + <from>0</from> + <input>a</input> + <to>1</to> + <pop> + </pop> + <push> + <symbol>s</symbol> + </push> + </transition> + <transition> + <from>1</from> + <input>b</input> + <to>1</to> + <pop> + <symbol>s</symbol> + </pop> + <push></push> + </transition> + <transition> + <from>1</from> + <input>c</input> + <to>1</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>1</from> + <input>c</input> + <to>0</to> + <pop></pop> + <push></push> + </transition> + </transitions> + <initialStates> + <state>0</state> + </initialStates> + <startSymbols> + <symbol>⊥</symbol> + </startSymbols> + <finalStates></finalStates> +</automaton> diff --git a/examples/VPA2.xml b/examples/VPA2.xml new file mode 100644 index 0000000000..59e36c6bcd --- /dev/null +++ b/examples/VPA2.xml @@ -0,0 +1,71 @@ +<automaton> + <states> + <state>0</state> + <state>1</state> + </states> + <inputAlphabet> + <symbol>a</symbol> + <symbol>b</symbol> + <symbol>c</symbol> + <symbol>d</symbol> + </inputAlphabet> + <stackAlphabet> + <symbol>A</symbol> + <symbol>B</symbol> + <symbol>⊥</symbol> + </stackAlphabet> + <transitions> + <transition> + <from>0</from> + <input>a</input> + <to>0</to> + <pop></pop> + <push> + <symbol>A</symbol> + </push> + </transition> + <transition> + <from>0</from> + <input>c</input> + <to>1</to> + <pop></pop> + <push></push> + </transition> + <transition> + <from>0</from> + <input>a</input> + <to>1</to> + <pop></pop> + <push> + <symbol>B</symbol> + </push> + </transition> + <transition> + <from>1</from> + <input>b</input> + <to>1</to> + <pop> + <symbol>A</symbol> + </pop> + <push></push> + </transition> + <transition> + <from>1</from> + <input>d</input> + <to>1</to> + <pop> + <symbol>B</symbol> + </pop> + <push></push> + </transition> + </transitions> + <initialStates> + <state>0</state> + </initialStates> + <startSymbols> + <symbol>⊥</symbol> + </startSymbols> + <finalStates> + <state>1</state> + </finalStates> +</automaton> diff --git a/examples/automaton/DFA.txt b/examples/automaton/DFA.txt new file mode 100644 index 0000000000..4d38ef9168 --- /dev/null +++ b/examples/automaton/DFA.txt @@ -0,0 +1,19 @@ +DFA a b c d +0 1 - - - +1 14 - - - +10 - 2 - - +11 - 8 - - +12 - 7 - - +13 - 16 - - +14 - - 5 12 +15 - - - 13 +<16 - - - - +<17 4 - - - +2 15 - - - +>3 10 9 0 12 +<4 - 11 - - +<5 - 6 5 - +<6 - - 5 - +<7 - - - 12 +8 10 17 0 12 +9 4 - - - diff --git a/examples/automaton/NFA.txt b/examples/automaton/NFA.txt new file mode 100644 index 0000000000..cdd3d18688 --- /dev/null +++ b/examples/automaton/NFA.txt @@ -0,0 +1,32 @@ +NFA a b c d \eps + >0 6|16 21 1|11|26 - 13 + 1 2 - - - - + 2 3 - - - - + 3 - - 4 - - + 4 - 5 - - 5 + <5 - - - - 3 + 6 - 7 - - - + 7 8 - - - - + 8 - - - 9 - + 9 - 10 - - - +<10 - - - - - + 11 12 - - - - + 12 13 - - - - + 13 - - - 14 - + 14 - 15 - - - +<15 - - - - 13 + 16 - 17 - - - + 17 18 - - - - + 18 - - - 19 - + 19 - 20 - - - +<20 - - - - - + 21 22 - - - - + 22 - 23 - - 25 + 23 - 24 - - - + 24 - 25 - - 0 +<25 - - - - - + 26 27 - - - - + 27 28 - - - - + 28 - - 29 - - + 29 - 30 - - - +<30 - - - - - \ No newline at end of file diff --git a/examples/regexp/regexp4.xml b/examples/regexp/regexp4.xml new file mode 100644 index 0000000000..573947d535 --- /dev/null +++ b/examples/regexp/regexp4.xml @@ -0,0 +1,24 @@ +<regexp> + <concatenation> + <symbol>0</symbol> + <symbol>1</symbol> + <iteration> + <alternation> + <symbol>0</symbol> + <symbol>1</symbol> + </alternation> + </iteration> + + <alternation> + <iteration> + <empty></empty> + </iteration> + <iteration> + <concatenation> + <epsilon></epsilon> + <symbol>0</symbol> + </concatenation> + </iteration> + </alternation> + </concatenation> +</regexp> diff --git a/makefile b/makefile new file mode 100644 index 0000000000..474f166440 --- /dev/null +++ b/makefile @@ -0,0 +1,49 @@ +APPPATH = /usr/bin +LIBPATH = /usr/lib/ +BINFOLDER = bin + +SUBDIRS_LIBS = alib adeterminize +SUBDIRS_BINS = acat aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aminimize adeterminize.fsm adiff adiff.automaton adiff.grammar aepsilon + +SUBDIRS_WITH_MAKE = $(dir $(wildcard */makefile)) + +.PHONY: $(SUBDIRS_LIBS) $(SUBDIRS_BINS) + +all: $(SUBDIRS_LIBS) $(SUBDIRS_BINS) copy + +$(SUBDIRS_LIBS): + $(MAKE) -C $@ + +$(SUBDIRS_BINS): + $(MAKE) -C $@ + +clean: + for dir in $(SUBDIRS_WITH_MAKE); do \ + $(MAKE) -C $$dir clean; \ + done + +copy: + mkdir -p $(BINFOLDER) + rm -rf $(BINFOLDER)/* + for dir in $(SUBDIRS_LIBS); do \ + cp $$dir/lib/* $(BINFOLDER); \ + done + for dir in $(SUBDIRS_BINS); do \ + cp $$dir/bin/* $(BINFOLDER); \ + done + +install: + cp alib/lib/libalib.so $(LIBPATH) + cp acat/bin/acat $(APPPATH) + cp aconvert/bin/aconvert $(APPPATH) + cp aconvert.dot/bin/aconvert.dot $(APPPATH) + cp aconvert.gastex/bin/aconvert.gastex $(APPPATH) + cp aminimize/bin/aminimize $(APPPATH) + +uninstall: + rm $(LIBPATH)/libalib.so + rm $(APPPATH)/acat + rm $(APPPATH)/aconvert + rm $(APPPATH)/aconvert.dot + rm $(APPPATH)/aconvert.gastex + rm $(APPPATH)/aminimize -- GitLab