From 89d6ca2b2f560273e7aa0f0dec4b49cce3c94177 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 7 Aug 2019 17:16:48 -0700 Subject: Spec language implemented. --- src/network.h | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/src/network.h b/src/network.h index e364459..50906a8 100644 --- a/src/network.h +++ b/src/network.h @@ -2,8 +2,13 @@ #define NEURAL_NETWORK_H #include "neural/node.h" +#include "neural/column.h" +#include "neural/container.h" +#include "neural/row.h" +#include "neural/neuron.h" #include +#include namespace Neural { @@ -24,9 +29,198 @@ namespace Neural static Network *fromStr( const Bu::String &sCode ) { Network *pNet = new Network(); + Bu::String::const_iterator i = sCode.begin(); + pNet->pRoot = parseNode( i ); return pNet; } + Node *getRoot() + { + return pRoot; + } + + private: + // Parser code + enum TokenType + { + tokRow, + tokColumn, + tokNeuron, + tokOpenParen, + tokCloseParen, + tokNumber, + tokComma, + tokEndOfInput + }; + + static TokenType nextToken( Bu::String::const_iterator &i, + int32_t &iValue ) + { + Bu::String sTmp; + for(; i; i++ ) + { + switch( *i ) + { + case ' ': + case '\t': + case '\n': + case '\r': + continue; + + case ',': + i++; + //Bu::println("Token: tokComma"); + return tokComma; + + case '(': + i++; + //Bu::println("Token: tokOpenParen"); + return tokOpenParen; + + case ')': + i++; + //Bu::println("Token: tokCloseParen"); + return tokCloseParen; + + default: + if( (*i >= 'a' && *i <= 'z') || + (*i >= 'A' && *i <= 'Z') ) + { + for(; i; i++ ) + { + if( (*i >= 'a' && *i <= 'z') || + (*i >= 'A' && *i <= 'Z') ) + { + sTmp += *i; + } + else + { + //Bu::println("Read: '%1'").arg( sTmp ); + sTmp = sTmp.toLower(); + if( sTmp == "row" ) + return tokRow; + if( sTmp == "column" ) + return tokColumn; + if( sTmp == "neuron" ) + return tokNeuron; + throw Bu::ExceptionBase( Bu::String( + "Invalid token discovered in input: %1" + ).arg( sTmp ).end().getStr() ); + + } + } + } + else if( *i >= '0' && *i <= '9' ) + { + for(; i; i++ ) + { + if( *i >= '0' && *i <= '9' ) + { + sTmp += *i; + } + else + { + //Bu::println("Read: '%1'").arg( sTmp ); + iValue = strtol( sTmp.getStr(), NULL, 10 ); + return tokNumber; + } + } + } + break; + } + } + return tokEndOfInput; + } + + static Node *parseNode( Bu::String::const_iterator &i ) + { + int iValue; + TokenType eTok = nextToken( i, iValue ); + Node *pNode = NULL; + switch( eTok ) + { + case tokColumn: + pNode = new Column(); + parseNodeParams( (Column *)pNode, i ); + break; + + case tokRow: + pNode = new Row(); + parseNodeParams( (Row *)pNode, i ); + break; + + case tokNeuron: + pNode = new Neuron(); + break; + + default: + throw Bu::ExceptionBase( + "Unexpecetd token parsing neural net specifacion."); + } + return pNode; + } + + static void parseNodeParams( Container *pParent, + Bu::String::const_iterator &i ) + { + int iValue; + TokenType eTok = nextToken( i, iValue ); + if( eTok != tokOpenParen ) + { + throw Bu::ExceptionBase( + "Unexpected token, expected open paren." + ); + } + for(;;) + { + eTok = nextToken( i, iValue ); + switch( eTok ) + { + case tokColumn: + { + Column *pNode = new Column(); + parseNodeParams( pNode, i ); + pParent->addNode( pNode ); + } + break; + + case tokRow: + { + Row *pNode = new Row(); + parseNodeParams( pNode, i ); + pParent->addNode( pNode ); + } + break; + + case tokNeuron: + pParent->addNode( new Neuron() ); + break; + + case tokNumber: + for( int j = 0; j < iValue; j++ ) + { + pParent->addNode( new Neuron() ); + } + break; + + default: + throw Bu::ExceptionBase( + "Unexpecetd token parsing neural net specifacion."); + } + + eTok = nextToken( i, iValue ); + if( eTok == tokCloseParen ) + return; + else if( eTok == tokComma ) + continue; + else + throw new Bu::ExceptionBase( + "Unexpected token parsing neural net specification," + " expected comma or close paren."); + } + + } + private: Node *pRoot; }; -- cgit v1.2.3