From b0a39c415bb0a4271f90649d5ff33a11af276822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Thu, 20 Feb 2014 16:29:54 +0100 Subject: [PATCH] aaccept: Simulates NFA run on given word (singlethread only) --- aaccept/.cproject | 126 ++++++++++++++++++++++++++++++++++++++++ aaccept/.project | 27 +++++++++ aaccept/makefile | 20 +++++++ aaccept/src/NFARun.cpp | 77 ++++++++++++++++++++++++ aaccept/src/NFARun.h | 62 ++++++++++++++++++++ aaccept/src/aaccept.cpp | 58 ++++++++++++++++++ makefile | 2 +- 7 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 aaccept/.cproject create mode 100644 aaccept/.project create mode 100644 aaccept/makefile create mode 100644 aaccept/src/NFARun.cpp create mode 100644 aaccept/src/NFARun.h create mode 100644 aaccept/src/aaccept.cpp diff --git a/aaccept/.cproject b/aaccept/.cproject new file mode 100644 index 0000000000..625f8b6b47 --- /dev/null +++ b/aaccept/.cproject @@ -0,0 +1,126 @@ +<?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.1136649547"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1136649547" 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.1136649547" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1136649547." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.708621400" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1417795952" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> + <builder buildPath="${workspace_loc:/aaccept}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1612593257" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.62366364" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1629750565" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1504222072" 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.602153299" 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.522669201" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/src}""/> + <listOptionValue builtIn="false" value=""/> + <listOptionValue builtIn="false" value="/usr/include/libxml2"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1708574173" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.726514711" 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.291666271" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.debug.option.debugging.level.792409484" 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.2046761190" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1431230759" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1451546180" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> + <option id="gnu.cpp.link.option.libs.1032685989" superClass="gnu.cpp.link.option.libs" valueType="libs"> + <listOptionValue builtIn="false" value="alib"/> + </option> + <option id="gnu.cpp.link.option.paths.1855082735" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/lib}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/Debug}""/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1299720088" 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.402703871" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1163222934" 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.659551761"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.659551761" 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.659551761" name="Release" parent="cdt.managedbuild.config.gnu.exe.release"> + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.659551761." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1444248623" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1739139487" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> + <builder buildPath="${workspace_loc:/aaccept}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1201862111" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.971653413" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.441963012" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.790835495" 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.1440841816" 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.1734342402" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.358533828" 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.321911617" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/> + <option id="gnu.c.compiler.exe.release.option.debugging.level.1102813690" 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.593598136" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.716157219" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.700906020" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.137966374" 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.568761504" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1589351551" 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="aaccept.cdt.managedbuild.target.gnu.exe.723060388" 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.debug.1136649547;cdt.managedbuild.config.gnu.exe.debug.1136649547.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.726514711;cdt.managedbuild.tool.gnu.c.compiler.input.2046761190"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.659551761;cdt.managedbuild.config.gnu.exe.release.659551761.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.358533828;cdt.managedbuild.tool.gnu.c.compiler.input.593598136"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1136649547;cdt.managedbuild.config.gnu.exe.debug.1136649547.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1629750565;cdt.managedbuild.tool.gnu.cpp.compiler.input.1708574173"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.659551761;cdt.managedbuild.config.gnu.exe.release.659551761.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.441963012;cdt.managedbuild.tool.gnu.cpp.compiler.input.1734342402"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> +</cproject> diff --git a/aaccept/.project b/aaccept/.project new file mode 100644 index 0000000000..d1533fe275 --- /dev/null +++ b/aaccept/.project @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>aaccept</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/aaccept/makefile b/aaccept/makefile new file mode 100644 index 0000000000..d4fe0b6935 --- /dev/null +++ b/aaccept/makefile @@ -0,0 +1,20 @@ +CC=g++ +EXECUTABLE=aaccept +CCFLAGS= -std=c++11 -O2 -g -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/$(EXECUTABLE) + +bin/$(EXECUTABLE): $(OBJECTS) + mkdir -p bin + $(CC) $(OBJECTS) -o $@ $(LDFLAGS) + +obj/%.o: src/%.cpp + mkdir -p $(dir $@) + $(CC) $(CCFLAGS) $< -o $@ + +clean: + $(RM) -r *.o *.d bin obj diff --git a/aaccept/src/NFARun.cpp b/aaccept/src/NFARun.cpp new file mode 100644 index 0000000000..a4c695f2c7 --- /dev/null +++ b/aaccept/src/NFARun.cpp @@ -0,0 +1,77 @@ +/* + * NFARun.cpp + * + * Created on: 14. 2. 2014 + * Author: tomas + */ + +#include "NFARun.h" +#include <iostream> + +using namespace alib; +using namespace automaton; +using namespace std; + +NFARun::NFARun( const FSM & fsm ) : m_fsm( fsm ) +{ + +} + +bool NFARun::simulate( const list<Symbol> & string ) const +{ + if( ! checkAlphabet( string ) ) + throw AlibException( "String alphabet does not match automaton alphabet." ); + + for( const auto & state : m_fsm.getInitialStates( ) ) + if( configuration( state, string ) ) + return true; + + return false; +} + +bool NFARun::checkAlphabet( const list<Symbol> & string ) const +{ + const auto & alphabet = m_fsm.getInputAlphabet( ); + for( const auto & symbol : string ) + if( alphabet.find( symbol ) == alphabet.end( ) ) + return false; + + return true; +} + +bool NFARun::configuration( const State & state, const list<Symbol> & string ) const +{ + if( string.empty( ) ) + return m_fsm.getFinalStates( ).find( state ) != m_fsm.getFinalStates( ).end( ); + + const Symbol & inputSymbol = string.front( ); + + list<Symbol> newString = string; + newString.pop_front( ); + + for( const auto & transition : m_fsm.getTransitionsFromState( state ) ) + if( transition.getInput( ) == inputSymbol && configuration( transition.getTo( ), newString ) ) + return true; + + return false; +} + +State NFARun::createUniqueState( const string & desiredName ) const +{ + //TODO: No need for this method after utils from aconversions project is merged into alib + + State s( desiredName ); + if( m_fsm.getStates( ).find( s ) == m_fsm.getStates( ).end( ) ) + return s; + + int i = 0; + while( true ) + { + State s( desiredName + to_string( i ++ ) ); + + // state not present in totalFSM + if( m_fsm.getStates( ).find( s ) == m_fsm.getStates( ).end( ) ) + return s; + } + throw AlibException( "WordAcceptance - Unable to create trash state" ); +} diff --git a/aaccept/src/NFARun.h b/aaccept/src/NFARun.h new file mode 100644 index 0000000000..d0ca42db08 --- /dev/null +++ b/aaccept/src/NFARun.h @@ -0,0 +1,62 @@ +/* + * NFARun.h + * + * Created on: 14. 2. 2014 + * Author: tomas + */ + +#ifndef NFARUN_H_ +#define NFARUN_H_ + +#include <automaton/FSM/FSM.h> +#include <alphabet/Symbol.h> +#include <AlibException.h> + +#include <climits> +#include <list> +#include <map> +#include <stdexcept> + +/** + * @brief Simulates NFA run + */ +class NFARun +{ +public: + NFARun( const automaton::FSM & fsm ); + + /** + * Simulates run of FSM with input word + * @param word Input word + * @return bool boolean value whether word was accepted + */ + bool simulate( const std::list<alphabet::Symbol> & string ) const; + +private: + /** + * Create unique state in automaton. If state with desired name is + * already present, tries to create state with same name and integer suffix + * @param desiredName desired name of state + * @return new unique state + * @throws AutomatonException if was unable to create unique state (counter + * reached INT_MAX) + */ + automaton::State createUniqueState( const std::string & desiredName ) const; + + /** + * @return true if all symbols are in the automata's input alphabet + */ + bool checkAlphabet( const std::list<alphabet::Symbol> & string ) const; + + /* + * Puts automaton into configuration Q x T* and checks if + * @param state state of automata + * @param string unreaded substring + * @return true if in configuration ( q, \eps ), q is accepting state + */ + bool configuration( const automaton::State & state, const std::list<alphabet::Symbol> & string ) const; + + automaton::FSM m_fsm; +}; + +#endif /* NFARUN_H_ */ diff --git a/aaccept/src/aaccept.cpp b/aaccept/src/aaccept.cpp new file mode 100644 index 0000000000..01442e54ec --- /dev/null +++ b/aaccept/src/aaccept.cpp @@ -0,0 +1,58 @@ +#include <iostream> +#include <string> +#include <list> + +#include <AlibException.h> +#include <automaton/AutomatonParser.h> +#include <automaton/UnknownAutomaton.h> +#include <AutomatonFactory.h> +#include <sax/SaxInterface.h> + +#include "NFARun.h" + +using namespace alib; +using namespace automaton; +using namespace alphabet; +using namespace std; +using namespace sax; + +/* + * Usage: + * aacept.fsm "a" "b" "cc" < fsm.xml (accepts FSM.xml word <a><b><cc> ?) + */ + +int main(int argc, char** argv) +{ + try + { + list<Token> tokens; + string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>())); + SaxInterface::parseMemory(input, tokens); + + UnknownAutomaton unknownAutomaton = AutomatonParser::parse(tokens); + FSM fsm = AutomatonFactory::buildFSM( unknownAutomaton ); + NFARun nfa( fsm ); + list<Symbol> word; + + for( int i = 1; i < argc ; i++ ) + word.push_back( Symbol ( argv[ i ] ) ); + + if( nfa.simulate( word ) ) + { + cout << "Automaton accepted word." << endl; + return 0; + } + else + { + cout << "Automaton did not accept word" << endl; + return 1; + } + } + catch( AlibException & e ) + { + cout << e.what() << endl; + return 255; + } + + return 0; +} diff --git a/makefile b/makefile index 861018a33a..893678ff09 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ LIBPATH = /usr/lib/ BINFOLDER = bin SUBDIRS_LIBS = alib adeterminize -SUBDIRS_BINS = acat aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar aminimize adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adiff adiff.automaton adiff.grammar aepsilon atrim +SUBDIRS_BINS = acat aconvert aconvert.dot aconvert.gastex aconvert.regexp aconvert.automaton aconvert.grammar aminimize adeterminize.fsm adeterminize.idpda adeterminize.vpa adeterminize.vpa2 adeterminize.vpa3 adiff adiff.automaton adiff.grammar aepsilon atrim aaccept SUBDIRS_WITH_MAKE = $(dir $(wildcard */makefile)) -- GitLab