diff --git a/aconversions/.cproject b/aconversions/.cproject index 2234d0ce3bb06130e69f82b9cb518011f701ce95..a127e88b8af02da8996f1ce96fc00aef629236cc 100644 --- a/aconversions/.cproject +++ b/aconversions/.cproject @@ -25,7 +25,9 @@ <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.590531226" 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.2109499447" 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.1786233414" 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.2087782350" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> </tool> <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.185152796" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> @@ -40,6 +42,7 @@ </option> <option id="gnu.cpp.link.option.paths.644657276" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> <listOptionValue builtIn="false" value=""${workspace_loc:/alib/Debug}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/lib}""/> </option> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1392298582" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> diff --git a/aconversions/src/derivatives/BrzozowskiDerivative.cpp b/aconversions/src/derivatives/BrzozowskiDerivative.cpp index f73e38eb4dc39f9221f03e91d2c4a139af3c39f8..bfa61df7758018e12f76d0fee5c80ff0ef47f8b7 100644 --- a/aconversions/src/derivatives/BrzozowskiDerivative.cpp +++ b/aconversions/src/derivatives/BrzozowskiDerivative.cpp @@ -20,41 +20,51 @@ BrzozowskiDerivative::BrzozowskiDerivative( const RegExp & re ) : m_re( re ) m_regexpRoot = const_cast<RegExp&>( m_re ).getRegExp( ); } -RegExp BrzozowskiDerivative::derivative ( const list<RegExpSymbol> & string ) const +RegExp BrzozowskiDerivative::derivative ( const list<RegExpElement*> & dString ) const { RegExpElement * expression = m_regexpRoot; - for( const auto & dSymbol : string ) // dV/d(ab) = d( dV/da )/db + for( const auto & dSymbol : dString ) // dV/d(ab) = d( dV/da )/db { - if( dSymbol.getSymbol( ) == "" ) + // FIXME: memory leak + if( dynamic_cast<RegExpEpsilon*>( dSymbol ) ) expression = expression->clone( ); + + else if( dynamic_cast<RegExpSymbol*>( dSymbol ) ) + expression = derivative( expression, * dynamic_cast<RegExpSymbol*>( dSymbol ) ); + else - expression = derivative( expression, dSymbol ); + throw ConversionException( "BrzozowskiDerivative::derivative - invalid/unknown RegExpElement node passed in dString." ); } - RegExpNormalize norm; - return norm.normalize( expression ); + // RegExpNormalize norm; + // return norm.normalize( expression ); + + return expression; } -RegExpElement * BrzozowskiDerivative::derivative( RegExpElement * element, const RegExpSymbol & dSymbol ) const +RegExpElement * BrzozowskiDerivative::derivative( RegExpElement * node, const RegExpSymbol & dSymbol ) const { - if( element == NULL ) - return NULL; - - Alternation* alternation = dynamic_cast<Alternation*>( element ); - Concatenation* concatenation = dynamic_cast<Concatenation*>( element ); - Iteration* iteration = dynamic_cast<Iteration*>( element ); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( element ); + Alternation * alternation = dynamic_cast<Alternation*>( node ); + Concatenation * concatenation = dynamic_cast<Concatenation*>( node ); + Iteration * iteration = dynamic_cast<Iteration*>( node ); + RegExpSymbol * symbol = dynamic_cast<RegExpSymbol*>( node ); + RegExpEpsilon * eps = dynamic_cast<RegExpEpsilon*>( node ); + RegExpEmpty * empty = dynamic_cast<RegExpEmpty*>( node ); if( alternation ) return derivative( alternation, dSymbol ); - else if( concatenation ) + if( concatenation ) return derivative( concatenation, dSymbol); - else if( iteration ) + if( iteration ) return derivative( iteration, dSymbol ); - else if( symbol ) + if( symbol ) return derivative( symbol, dSymbol ); + if( eps ) + return derivative( eps, dSymbol ); + if( empty ) + return derivative( empty, dSymbol ); - throw ConversionException( "BrzozowskiDerivative::derivative - unknown RegExpElement type" ); + throw ConversionException( "BrzozowskiDerivative::derivative() - unknown RegExpElement node" ); } RegExpElement * BrzozowskiDerivative::derivative( Alternation * element, const RegExpSymbol & dSymbol ) const @@ -63,11 +73,7 @@ RegExpElement * BrzozowskiDerivative::derivative( Alternation * element, const R list<RegExpElement*> & retElements = ret->getElements( ); for( const auto & e : element->getElements( ) ) - { - RegExpElement* d = derivative( e, dSymbol ); - if( d != NULL ) // Melichar 2.87, A3: x + NULL = x - retElements.push_back( d ); - } + retElements.push_back( derivative( e, dSymbol ) ); return ret; } @@ -88,14 +94,12 @@ RegExpElement * BrzozowskiDerivative::derivative( Concatenation * element, const while( ++ succeedingElem != element->getElements( ).end( ) ) concatElements.push_back( ( * succeedingElem )->clone( ) ); - // altElements.push_back( RegExpNormalize::normalize( concat ) ); altElements.push_back( concat ); if( ! RegExpUtils::containsEpsilon( * elem ) ) break; } - // return RegExpNormalize::normalize( alt ); return alt; } @@ -107,24 +111,25 @@ RegExpElement * BrzozowskiDerivative::derivative( Iteration * element, const Reg retElements.push_back( derivative( element->getElement( ), dSymbol ) ); retElements.push_back( element->clone( ) ); - // Melichar 2.87, A7: x.NULL = NULL - for( const auto & e : retElements ) - { - if( e == NULL ) - { - delete ret; - ret = NULL; - break; - } - } - return ret; } RegExpElement * BrzozowskiDerivative::derivative( RegExpSymbol * element, const RegExpSymbol & dSymbol ) const { - return dSymbol == element->getSymbol( ) ? new RegExpSymbol( "" ) : NULL; + if( dSymbol == element->getSymbol( ) ) + return new RegExpEpsilon( ); + else + return new RegExpEmpty( ); } +RegExpElement * BrzozowskiDerivative::derivative( RegExpEpsilon * element, const RegExpSymbol & dSymbol ) const +{ + return new RegExpEmpty( ); +} + +RegExpElement * BrzozowskiDerivative::derivative( RegExpEmpty * element, const RegExpSymbol & dSymbol ) const +{ + return new RegExpEmpty( ); +} } /* namespace conversions */ diff --git a/aconversions/src/derivatives/BrzozowskiDerivative.h b/aconversions/src/derivatives/BrzozowskiDerivative.h index c04521fea049ee9189d556483aab83d9d2a4e11f..d9cc458e47cfd7bfedfbe2a24610bc7defaafe68 100644 --- a/aconversions/src/derivatives/BrzozowskiDerivative.h +++ b/aconversions/src/derivatives/BrzozowskiDerivative.h @@ -14,6 +14,8 @@ #include <regexp/Concatenation.h> #include <regexp/Iteration.h> #include <regexp/RegExpSymbol.h> +#include <regexp/RegExpEmpty.h> +#include <regexp/RegExpEpsilon.h> #include <list> @@ -34,7 +36,7 @@ class BrzozowskiDerivative { public: BrzozowskiDerivative( const regexp::RegExp & re ); - regexp::RegExp derivative ( const std::list<regexp::RegExpSymbol> & string ) const; + regexp::RegExp derivative ( const std::list<regexp::RegExpElement*> & dString ) const; private: regexp::RegExpElement * derivative( regexp::RegExpElement * element, const regexp::RegExpSymbol & dSymbol ) const; @@ -42,11 +44,8 @@ private: regexp::RegExpElement * derivative( regexp::Concatenation * element, const regexp::RegExpSymbol & dSymbol ) const; regexp::RegExpElement * derivative( regexp::Iteration * element, const regexp::RegExpSymbol & dSymbol ) const; regexp::RegExpElement * derivative( regexp::RegExpSymbol * element, const regexp::RegExpSymbol & dSymbol ) const; - - /** - * No warranty for this one, unsourced, created by me. - */ - bool containsEpsilon( regexp::RegExpElement * element ) const; + regexp::RegExpElement * derivative( regexp::RegExpEpsilon * element, const regexp::RegExpSymbol & dSymbol ) const; + regexp::RegExpElement * derivative( regexp::RegExpEmpty * element, const regexp::RegExpSymbol & dSymbol ) const; const regexp::RegExp & m_re; regexp::RegExpElement* m_regexpRoot; diff --git a/aconversions/src/derivatives/aderivative.cpp b/aconversions/src/derivatives/aderivative.cpp index 9f8570bd4bcf3075e2e36787d92c50ccf8fc586d..fb4d9d707a66fdf8f9084c9a91990ef7998bf2bc 100644 --- a/aconversions/src/derivatives/aderivative.cpp +++ b/aconversions/src/derivatives/aderivative.cpp @@ -30,12 +30,15 @@ int main(int argc, char** argv) SaxInterface::parseMemory(input, tokens); RegExp re = RegExpParser::parse(tokens); - list<RegExpSymbol> dString; + list<RegExpElement*> dString; for( int i = 1; i < argc ; i++ ) { string symbol( argv[ i ] ); // cout << "'" << symbol << "'" << endl; - dString.push_back( RegExpSymbol( symbol ) ); + if( symbol == "" ) + dString.push_back( new RegExpEpsilon( ) ); + else + dString.push_back( new RegExpSymbol( symbol ) ); } BrzozowskiDerivative d( re ); d.derivative( dString ).toXML( cout ); diff --git a/aconversions/src/utils/RegExpUtils.cpp b/aconversions/src/utils/RegExpUtils.cpp index 259a4f019fb8a46d179e13b385302e09e7317bae..bac97834748bf67835dba8a575331545d8457914 100644 --- a/aconversions/src/utils/RegExpUtils.cpp +++ b/aconversions/src/utils/RegExpUtils.cpp @@ -1,5 +1,7 @@ #include "RegExpUtils.h" +#include<iostream> + using namespace alphabet; using namespace regexp; using namespace std; @@ -21,12 +23,14 @@ list<RegExpSymbol*> RegExpUtils::getRegExpSymbols( const RegExp & re ) } -void RegExpUtils::traverseSymbols( RegExpElement * element, list<RegExpSymbol*> & alphabet ) +void RegExpUtils::traverseSymbols( RegExpElement * node, list<RegExpSymbol*> & alphabet ) { - Alternation* alternation = dynamic_cast<Alternation*>(element); - Concatenation* concatenation = dynamic_cast<Concatenation*>(element); - Iteration* iteration = dynamic_cast<Iteration*>(element); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>(element); + Alternation* alternation = dynamic_cast<Alternation*>( node ); + Concatenation* concatenation = dynamic_cast<Concatenation*>( node ); + Iteration* iteration = dynamic_cast<Iteration*>( node ); + RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node ); + RegExpEmpty * empty = dynamic_cast<RegExpEmpty*>( node ); + RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node ); if( symbol ) { @@ -54,41 +58,88 @@ void RegExpUtils::traverseSymbols( RegExpElement * element, list<RegExpSymbol*> return; } + else if( empty ) + return; + + else if( eps ) + return; - throw ConversionException( "Captain's log. Stardate 3413.6. Approaching TraverseSymbols, class RegExpUtils planet. Encountered invalid RegExpElement. Sending away team to explore." ); + + throw ConversionException( "RegExpUtils::traverseSymbols() - unknown RegExpElement node" ); } +// ---------------------------------------------------------------------------- + bool RegExpUtils::containsEpsilon( const RegExp & re ) { return containsEpsilon( const_cast<RegExp&>( re ).getRegExp( ) ); } -bool RegExpUtils::containsEpsilon( RegExpElement * element ) +bool RegExpUtils::containsEpsilon( RegExpElement * node ) { - Alternation* alternation = dynamic_cast<Alternation*>( element ); - Concatenation* concatenation = dynamic_cast<Concatenation*>( element ); - Iteration* iteration = dynamic_cast<Iteration*>( element ); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( element ); + Alternation* alternation = dynamic_cast<Alternation*>( node ); + Concatenation* concatenation = dynamic_cast<Concatenation*>( node ); + Iteration* iteration = dynamic_cast<Iteration*>( node ); + RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node ); + RegExpEmpty * empty = dynamic_cast<RegExpEmpty*>( node ); + RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node ); + + if( alternation ) + return containsEpsilon( alternation ); + if( concatenation ) + return containsEpsilon( concatenation ); + if( iteration ) + return containsEpsilon( iteration ); + if( symbol ) + return containsEpsilon( symbol ); + if( empty ) + return containsEpsilon( empty ); + if( eps ) + return containsEpsilon( eps ); + + throw ConversionException( "RegExpUtils::containsEpsilon() - unknown RegExpElement node" ); +} - if( alternation ) - { - for( const auto & e : alternation->getElements( ) ) - if( containsEpsilon( e ) ) - return true; +bool RegExpUtils::containsEpsilon( Alternation * node ) +{ + for( const auto & e : node->getElements( ) ) + if( containsEpsilon( e ) ) + return true; - return false; - } + return false; +} - if( concatenation ) - { - for( const auto & e : concatenation->getElements( ) ) - if( ! containsEpsilon( e ) ) - return false; +bool RegExpUtils::containsEpsilon( Concatenation * node ) +{ + for( const auto & e : node->getElements( ) ) + if( ! containsEpsilon( e ) ) + return false; + return true; +} + +bool RegExpUtils::containsEpsilon( Iteration * node ) +{ + return true; +} + +bool RegExpUtils::containsEpsilon( RegExpSymbol * node ) +{ + // backwards compatibility for alib versions without RegExpEpsilon + if( node->getSymbol( ) == "" ) return true; - } - return iteration || ( symbol && *symbol == RegExpSymbol( "" ) ); + return false; +} + +bool RegExpUtils::containsEpsilon( RegExpEmpty * element ) +{ + return false; +} + +bool RegExpUtils::containsEpsilon( RegExpEpsilon * element ) +{ + return true; } } /* namespace conversions */ diff --git a/aconversions/src/utils/RegExpUtils.h b/aconversions/src/utils/RegExpUtils.h index cdfd791ab375c6de54217474e0799dbf8ee146ec..9080f01dc51e1c0048e7f4d27b4cc9b5a74a4d97 100644 --- a/aconversions/src/utils/RegExpUtils.h +++ b/aconversions/src/utils/RegExpUtils.h @@ -7,6 +7,8 @@ #include <regexp/Concatenation.h> #include <regexp/Iteration.h> #include <regexp/RegExpSymbol.h> +#include <regexp/RegExpEmpty.h> +#include <regexp/RegExpEpsilon.h> #include "utils.h" #include "ConversionException.h" @@ -18,12 +20,21 @@ class RegExpUtils { public: static std::list<regexp::RegExpSymbol*> getRegExpSymbols( const regexp::RegExp & re ); - static bool containsEpsilon( regexp::RegExpElement * element ); + + static bool containsEpsilon( regexp::RegExpElement * node ); static bool containsEpsilon( const regexp::RegExp & re ); + static bool isRegExpEmpty( const regexp::RegExp & re ); private: static void traverseSymbols( regexp::RegExpElement * element, std::list<regexp::RegExpSymbol*> & alphabet ); + + static bool containsEpsilon( regexp::Alternation * node ); + static bool containsEpsilon( regexp::Concatenation * node ); + static bool containsEpsilon( regexp::Iteration * node ); + static bool containsEpsilon( regexp::RegExpSymbol * node ); + static bool containsEpsilon( regexp::RegExpEmpty * node ); + static bool containsEpsilon( regexp::RegExpEpsilon * node ); }; } /* namespace conversions */ diff --git a/aconvert.grammar/.cproject b/aconvert.grammar/.cproject index c0b3d1801bed674eef2e340c67d441155a5c8576..81a7e0ba15361bdc11ccb8841967b1b46866255a 100644 --- a/aconvert.grammar/.cproject +++ b/aconvert.grammar/.cproject @@ -27,7 +27,7 @@ <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"/> + <option id="gnu.cpp.compiler.option.other.other.31259776" name="Other flags" 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"> @@ -42,7 +42,7 @@ </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=""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/alib/Debug}""/> </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)"/>