Skip to content
Snippets Groups Projects
Commit 760e6f64 authored by Tomáš Pecka's avatar Tomáš Pecka
Browse files

Adapt Derivatives

parent 18d2886d
No related branches found
No related tags found
No related merge requests found
...@@ -25,7 +25,9 @@ ...@@ -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.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"> <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="&quot;${workspace_loc:/alib/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/src}&quot;"/>
<listOptionValue builtIn="false" value="/usr/include/libxml2"/>
</option> </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"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2087782350" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </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"> <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 @@ ...@@ -40,6 +42,7 @@
</option> </option>
<option id="gnu.cpp.link.option.paths.644657276" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> <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="&quot;${workspace_loc:/alib/Debug}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/lib}&quot;"/>
</option> </option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1392298582" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1392298582" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
......
...@@ -20,41 +20,51 @@ BrzozowskiDerivative::BrzozowskiDerivative( const RegExp & re ) : m_re( re ) ...@@ -20,41 +20,51 @@ BrzozowskiDerivative::BrzozowskiDerivative( const RegExp & re ) : m_re( re )
m_regexpRoot = const_cast<RegExp&>( m_re ).getRegExp( ); 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; 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( ); expression = expression->clone( );
else if( dynamic_cast<RegExpSymbol*>( dSymbol ) )
expression = derivative( expression, * dynamic_cast<RegExpSymbol*>( dSymbol ) );
else else
expression = derivative( expression, dSymbol ); throw ConversionException( "BrzozowskiDerivative::derivative - invalid/unknown RegExpElement node passed in dString." );
} }
   
RegExpNormalize norm; // RegExpNormalize norm;
return norm.normalize( expression ); // 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 ) Alternation * alternation = dynamic_cast<Alternation*>( node );
return NULL; Concatenation * concatenation = dynamic_cast<Concatenation*>( node );
Iteration * iteration = dynamic_cast<Iteration*>( node );
Alternation* alternation = dynamic_cast<Alternation*>( element ); RegExpSymbol * symbol = dynamic_cast<RegExpSymbol*>( node );
Concatenation* concatenation = dynamic_cast<Concatenation*>( element ); RegExpEpsilon * eps = dynamic_cast<RegExpEpsilon*>( node );
Iteration* iteration = dynamic_cast<Iteration*>( element ); RegExpEmpty * empty = dynamic_cast<RegExpEmpty*>( node );
RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( element );
   
if( alternation ) if( alternation )
return derivative( alternation, dSymbol ); return derivative( alternation, dSymbol );
else if( concatenation ) if( concatenation )
return derivative( concatenation, dSymbol); return derivative( concatenation, dSymbol);
else if( iteration ) if( iteration )
return derivative( iteration, dSymbol ); return derivative( iteration, dSymbol );
else if( symbol ) if( symbol )
return derivative( symbol, dSymbol ); 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 RegExpElement * BrzozowskiDerivative::derivative( Alternation * element, const RegExpSymbol & dSymbol ) const
...@@ -63,11 +73,7 @@ RegExpElement * BrzozowskiDerivative::derivative( Alternation * element, const R ...@@ -63,11 +73,7 @@ RegExpElement * BrzozowskiDerivative::derivative( Alternation * element, const R
list<RegExpElement*> & retElements = ret->getElements( ); list<RegExpElement*> & retElements = ret->getElements( );
   
for( const auto & e : element->getElements( ) ) for( const auto & e : element->getElements( ) )
{ retElements.push_back( derivative( e, dSymbol ) );
RegExpElement* d = derivative( e, dSymbol );
if( d != NULL ) // Melichar 2.87, A3: x + NULL = x
retElements.push_back( d );
}
   
return ret; return ret;
} }
...@@ -88,14 +94,12 @@ RegExpElement * BrzozowskiDerivative::derivative( Concatenation * element, const ...@@ -88,14 +94,12 @@ RegExpElement * BrzozowskiDerivative::derivative( Concatenation * element, const
while( ++ succeedingElem != element->getElements( ).end( ) ) while( ++ succeedingElem != element->getElements( ).end( ) )
concatElements.push_back( ( * succeedingElem )->clone( ) ); concatElements.push_back( ( * succeedingElem )->clone( ) );
   
// altElements.push_back( RegExpNormalize::normalize( concat ) );
altElements.push_back( concat ); altElements.push_back( concat );
   
if( ! RegExpUtils::containsEpsilon( * elem ) ) if( ! RegExpUtils::containsEpsilon( * elem ) )
break; break;
} }
   
// return RegExpNormalize::normalize( alt );
return alt; return alt;
} }
   
...@@ -107,24 +111,25 @@ RegExpElement * BrzozowskiDerivative::derivative( Iteration * element, const Reg ...@@ -107,24 +111,25 @@ RegExpElement * BrzozowskiDerivative::derivative( Iteration * element, const Reg
retElements.push_back( derivative( element->getElement( ), dSymbol ) ); retElements.push_back( derivative( element->getElement( ), dSymbol ) );
retElements.push_back( element->clone( ) ); 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; return ret;
} }
   
RegExpElement * BrzozowskiDerivative::derivative( RegExpSymbol * element, const RegExpSymbol & dSymbol ) const 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 */ } /* namespace conversions */
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <regexp/Concatenation.h> #include <regexp/Concatenation.h>
#include <regexp/Iteration.h> #include <regexp/Iteration.h>
#include <regexp/RegExpSymbol.h> #include <regexp/RegExpSymbol.h>
#include <regexp/RegExpEmpty.h>
#include <regexp/RegExpEpsilon.h>
   
#include <list> #include <list>
   
...@@ -34,7 +36,7 @@ class BrzozowskiDerivative ...@@ -34,7 +36,7 @@ class BrzozowskiDerivative
{ {
public: public:
BrzozowskiDerivative( const regexp::RegExp & re ); 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: private:
regexp::RegExpElement * derivative( regexp::RegExpElement * element, const regexp::RegExpSymbol & dSymbol ) const; regexp::RegExpElement * derivative( regexp::RegExpElement * element, const regexp::RegExpSymbol & dSymbol ) const;
...@@ -42,11 +44,8 @@ private: ...@@ -42,11 +44,8 @@ private:
regexp::RegExpElement * derivative( regexp::Concatenation * element, const regexp::RegExpSymbol & dSymbol ) const; 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::Iteration * element, const regexp::RegExpSymbol & dSymbol ) const;
regexp::RegExpElement * derivative( regexp::RegExpSymbol * element, const regexp::RegExpSymbol & dSymbol ) const; regexp::RegExpElement * derivative( regexp::RegExpSymbol * element, const regexp::RegExpSymbol & dSymbol ) const;
regexp::RegExpElement * derivative( regexp::RegExpEpsilon * element, const regexp::RegExpSymbol & dSymbol ) const;
/** regexp::RegExpElement * derivative( regexp::RegExpEmpty * element, const regexp::RegExpSymbol & dSymbol ) const;
* No warranty for this one, unsourced, created by me.
*/
bool containsEpsilon( regexp::RegExpElement * element ) const;
   
const regexp::RegExp & m_re; const regexp::RegExp & m_re;
regexp::RegExpElement* m_regexpRoot; regexp::RegExpElement* m_regexpRoot;
......
...@@ -30,12 +30,15 @@ int main(int argc, char** argv) ...@@ -30,12 +30,15 @@ int main(int argc, char** argv)
SaxInterface::parseMemory(input, tokens); SaxInterface::parseMemory(input, tokens);
RegExp re = RegExpParser::parse(tokens); RegExp re = RegExpParser::parse(tokens);
   
list<RegExpSymbol> dString; list<RegExpElement*> dString;
for( int i = 1; i < argc ; i++ ) for( int i = 1; i < argc ; i++ )
{ {
string symbol( argv[ i ] ); string symbol( argv[ i ] );
// cout << "'" << symbol << "'" << endl; // 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 ); BrzozowskiDerivative d( re );
d.derivative( dString ).toXML( cout ); d.derivative( dString ).toXML( cout );
......
#include "RegExpUtils.h" #include "RegExpUtils.h"
   
#include<iostream>
using namespace alphabet; using namespace alphabet;
using namespace regexp; using namespace regexp;
using namespace std; using namespace std;
...@@ -21,12 +23,14 @@ list<RegExpSymbol*> RegExpUtils::getRegExpSymbols( const RegExp & re ) ...@@ -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); Alternation* alternation = dynamic_cast<Alternation*>( node );
Concatenation* concatenation = dynamic_cast<Concatenation*>(element); Concatenation* concatenation = dynamic_cast<Concatenation*>( node );
Iteration* iteration = dynamic_cast<Iteration*>(element); Iteration* iteration = dynamic_cast<Iteration*>( node );
RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>(element); RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node );
RegExpEmpty * empty = dynamic_cast<RegExpEmpty*>( node );
RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node );
   
if( symbol ) if( symbol )
{ {
...@@ -54,41 +58,88 @@ void RegExpUtils::traverseSymbols( RegExpElement * element, list<RegExpSymbol*> ...@@ -54,41 +58,88 @@ void RegExpUtils::traverseSymbols( RegExpElement * element, list<RegExpSymbol*>
return; 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 ) bool RegExpUtils::containsEpsilon( const RegExp & re )
{ {
return containsEpsilon( const_cast<RegExp&>( re ).getRegExp( ) ); return containsEpsilon( const_cast<RegExp&>( re ).getRegExp( ) );
} }
   
bool RegExpUtils::containsEpsilon( RegExpElement * element ) bool RegExpUtils::containsEpsilon( RegExpElement * node )
{ {
Alternation* alternation = dynamic_cast<Alternation*>( element ); Alternation* alternation = dynamic_cast<Alternation*>( node );
Concatenation* concatenation = dynamic_cast<Concatenation*>( element ); Concatenation* concatenation = dynamic_cast<Concatenation*>( node );
Iteration* iteration = dynamic_cast<Iteration*>( element ); Iteration* iteration = dynamic_cast<Iteration*>( node );
RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( element ); 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 ) bool RegExpUtils::containsEpsilon( Alternation * node )
{ {
for( const auto & e : alternation->getElements( ) ) for( const auto & e : node->getElements( ) )
if( containsEpsilon( e ) ) if( containsEpsilon( e ) )
return true; return true;
   
return false; return false;
} }
   
if( concatenation ) bool RegExpUtils::containsEpsilon( Concatenation * node )
{ {
for( const auto & e : concatenation->getElements( ) ) for( const auto & e : node->getElements( ) )
if( ! containsEpsilon( e ) ) if( ! containsEpsilon( e ) )
return false; 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 true;
}
   
return iteration || ( symbol && *symbol == RegExpSymbol( "" ) ); return false;
}
bool RegExpUtils::containsEpsilon( RegExpEmpty * element )
{
return false;
}
bool RegExpUtils::containsEpsilon( RegExpEpsilon * element )
{
return true;
} }
   
} /* namespace conversions */ } /* namespace conversions */
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <regexp/Concatenation.h> #include <regexp/Concatenation.h>
#include <regexp/Iteration.h> #include <regexp/Iteration.h>
#include <regexp/RegExpSymbol.h> #include <regexp/RegExpSymbol.h>
#include <regexp/RegExpEmpty.h>
#include <regexp/RegExpEpsilon.h>
   
#include "utils.h" #include "utils.h"
#include "ConversionException.h" #include "ConversionException.h"
...@@ -18,12 +20,21 @@ class RegExpUtils ...@@ -18,12 +20,21 @@ class RegExpUtils
{ {
public: public:
static std::list<regexp::RegExpSymbol*> getRegExpSymbols( const regexp::RegExp & re ); 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 containsEpsilon( const regexp::RegExp & re );
static bool isRegExpEmpty( const regexp::RegExp & re ); static bool isRegExpEmpty( const regexp::RegExp & re );
   
private: private:
static void traverseSymbols( regexp::RegExpElement * element, std::list<regexp::RegExpSymbol*> & alphabet ); 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 */ } /* namespace conversions */
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/src}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/src}&quot;"/>
<listOptionValue builtIn="false" value="/usr/include/libxml2"/> <listOptionValue builtIn="false" value="/usr/include/libxml2"/>
</option> </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"/> <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2079250197" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool> </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"> <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 @@ ...@@ -42,7 +42,7 @@
</option> </option>
<option id="gnu.cpp.link.option.paths.591596312" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths"> <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="&quot;${workspace_loc:/alib/lib}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/lib}&quot;"/>
<listOptionValue builtIn="false" value=""/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/alib/Debug}&quot;"/>
</option> </option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1424246647" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <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="additionalinputdependency" paths="$(USER_OBJS)"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment