diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2016-11-30 13:57:04 -0700 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2016-11-30 13:57:04 -0700 |
| commit | 0321e6e39b8cf24718cf853c28f0f35443753264 (patch) | |
| tree | 878bdaa2296014244f2dbe90d61c5c869e8204b7 /src | |
| parent | f50e787110c8b3ecbc1b07262842dd5fdc8a5e42 (diff) | |
| download | clic-0321e6e39b8cf24718cf853c28f0f35443753264.tar.gz clic-0321e6e39b8cf24718cf853c28f0f35443753264.tar.bz2 clic-0321e6e39b8cf24718cf853c28f0f35443753264.tar.xz clic-0321e6e39b8cf24718cf853c28f0f35443753264.zip | |
Working on the parser, some issues.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lexer.cpp | 42 | ||||
| -rw-r--r-- | src/lexer.h | 8 | ||||
| -rw-r--r-- | src/options.cpp | 2 | ||||
| -rw-r--r-- | src/parser.cpp | 55 | ||||
| -rw-r--r-- | src/parser.h | 37 | ||||
| -rw-r--r-- | src/token.cpp | 6 | ||||
| -rw-r--r-- | src/token.h | 6 | ||||
| -rw-r--r-- | src/unitparser.cpp | 7 | ||||
| -rw-r--r-- | src/unitparser.h | 1 |
9 files changed, 155 insertions, 9 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp index b0d0fd1..fbcaafb 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp | |||
| @@ -11,27 +11,55 @@ Lexer::Lexer( Bu::Stream &rIn ) : | |||
| 11 | iRadix( 10 ), | 11 | iRadix( 10 ), |
| 12 | numRangeTop('9'), | 12 | numRangeTop('9'), |
| 13 | ascRangeTop('a'-1), | 13 | ascRangeTop('a'-1), |
| 14 | eMode( modeNormal ) | 14 | eMode( modeNormal ), |
| 15 | iLookAheadSize( 2 ), | ||
| 16 | iLookAheadUsed( 0 ), | ||
| 17 | iLookAheadStart( 0 ), | ||
| 18 | aLookAhead( 0 ) | ||
| 15 | { | 19 | { |
| 20 | aLookAhead = new Token[iLookAheadSize]; | ||
| 16 | } | 21 | } |
| 17 | 22 | ||
| 18 | Lexer::~Lexer() | 23 | Lexer::~Lexer() |
| 19 | { | 24 | { |
| 20 | } | 25 | } |
| 21 | 26 | ||
| 22 | Token Lexer::nextToken() | 27 | void Lexer::nextToken() |
| 28 | { | ||
| 29 | if( iLookAheadSize <= 1 ) | ||
| 30 | { | ||
| 31 | iLookAheadSize = 0; | ||
| 32 | iLookAheadStart = 0; | ||
| 33 | } | ||
| 34 | else | ||
| 35 | { | ||
| 36 | iLookAheadStart = (iLookAheadStart+1)%iLookAheadSize; | ||
| 37 | iLookAheadSize--; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | void Lexer::fillToken() | ||
| 23 | { | 42 | { |
| 24 | switch( eMode ) | 43 | switch( eMode ) |
| 25 | { | 44 | { |
| 26 | case modeNormal: | 45 | case modeNormal: |
| 27 | return nextTokenNormal(); | 46 | aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize] = |
| 47 | nextTokenNormal(); | ||
| 48 | break; | ||
| 28 | 49 | ||
| 29 | case modeCommand: | 50 | case modeCommand: |
| 30 | return nextTokenCommand(); | 51 | aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize] = |
| 52 | nextTokenCommand(); | ||
| 53 | break; | ||
| 31 | 54 | ||
| 32 | default: | 55 | default: |
| 33 | throw Bu::ExceptionBase("Invalid mode."); | 56 | throw Bu::ExceptionBase("Invalid mode."); |
| 34 | } | 57 | } |
| 58 | |||
| 59 | Bu::sio << "read[" | ||
| 60 | << ((iLookAheadUsed+iLookAheadStart)%iLookAheadSize) | ||
| 61 | << "]: " | ||
| 62 | << aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].eType; | ||
| 35 | } | 63 | } |
| 36 | 64 | ||
| 37 | Token Lexer::nextTokenNormal() | 65 | Token Lexer::nextTokenNormal() |
| @@ -235,5 +263,11 @@ void Lexer::setRadix( int i ) | |||
| 235 | 263 | ||
| 236 | Token &Lexer::operator[]( int iIdx ) | 264 | Token &Lexer::operator[]( int iIdx ) |
| 237 | { | 265 | { |
| 266 | while( iIdx >= iLookAheadUsed ) | ||
| 267 | { | ||
| 268 | fillToken(); | ||
| 269 | iLookAheadUsed++; | ||
| 270 | } | ||
| 271 | return aLookAhead[(iLookAheadStart+iIdx)%iLookAheadSize]; | ||
| 238 | } | 272 | } |
| 239 | 273 | ||
diff --git a/src/lexer.h b/src/lexer.h index d5631d4..193a22b 100644 --- a/src/lexer.h +++ b/src/lexer.h | |||
| @@ -20,7 +20,7 @@ public: | |||
| 20 | void setMode( Mode e ) { eMode = e; } | 20 | void setMode( Mode e ) { eMode = e; } |
| 21 | Mode getMode() const { return eMode; } | 21 | Mode getMode() const { return eMode; } |
| 22 | 22 | ||
| 23 | Token nextToken(); | 23 | void nextToken(); |
| 24 | 24 | ||
| 25 | int getScale() const { return iScale; } | 25 | int getScale() const { return iScale; } |
| 26 | void setScale( int i ) { iScale = i; } | 26 | void setScale( int i ) { iScale = i; } |
| @@ -31,6 +31,7 @@ public: | |||
| 31 | Token &operator[]( int iIdx ); | 31 | Token &operator[]( int iIdx ); |
| 32 | 32 | ||
| 33 | private: | 33 | private: |
| 34 | void fillToken(); | ||
| 34 | Token nextTokenNormal(); | 35 | Token nextTokenNormal(); |
| 35 | Token nextTokenCommand(); | 36 | Token nextTokenCommand(); |
| 36 | 37 | ||
| @@ -43,6 +44,11 @@ private: | |||
| 43 | char numRangeTop; | 44 | char numRangeTop; |
| 44 | char ascRangeTop; | 45 | char ascRangeTop; |
| 45 | Mode eMode; | 46 | Mode eMode; |
| 47 | |||
| 48 | int iLookAheadSize; | ||
| 49 | int iLookAheadUsed; | ||
| 50 | int iLookAheadStart; | ||
| 51 | Token *aLookAhead; | ||
| 46 | }; | 52 | }; |
| 47 | 53 | ||
| 48 | #endif | 54 | #endif |
diff --git a/src/options.cpp b/src/options.cpp index c127022..3c016a6 100644 --- a/src/options.cpp +++ b/src/options.cpp | |||
| @@ -191,7 +191,7 @@ int Options::execute( Bu::StringArray aArgs ) | |||
| 191 | mbIn.write(" "); | 191 | mbIn.write(" "); |
| 192 | mbIn.write( aArgs[j] ); | 192 | mbIn.write( aArgs[j] ); |
| 193 | } | 193 | } |
| 194 | // Bu::println("eq: '''%1'''").arg( mbIn.getString() ); | 194 | Bu::println("eq: '''%1'''").arg( mbIn.getString() ); |
| 195 | mbIn.setPos( 0 ); | 195 | mbIn.setPos( 0 ); |
| 196 | Bu::MemBuf mbOut; | 196 | Bu::MemBuf mbOut; |
| 197 | Lexer lex( mbIn ); | 197 | Lexer lex( mbIn ); |
diff --git a/src/parser.cpp b/src/parser.cpp index 153b6fe..1f9a193 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
| @@ -22,6 +22,58 @@ void Parser::parse() | |||
| 22 | { | 22 | { |
| 23 | for(;;) | 23 | for(;;) |
| 24 | { | 24 | { |
| 25 | lex.nextToken(); | ||
| 26 | expr(); | ||
| 27 | |||
| 28 | for( TokenStack::iterator i = tsStack.begin(); i; i++ ) | ||
| 29 | { | ||
| 30 | Bu::sio << *i << " "; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | void Parser::expr() | ||
| 36 | { | ||
| 37 | if( lex[0].eType == Token::tVariable && | ||
| 38 | lex[1].eType == Token::tEquals ) | ||
| 39 | { | ||
| 40 | // Assignment! | ||
| 41 | expr(); | ||
| 42 | return; | ||
| 43 | } | ||
| 44 | exprP(); | ||
| 45 | } | ||
| 46 | |||
| 47 | void Parser::exprP() | ||
| 48 | { | ||
| 49 | switch( lex[0].eType ) | ||
| 50 | { | ||
| 51 | case Token::tNumber: | ||
| 52 | case Token::tVariable: | ||
| 53 | tsStack.push( lex[0] ); | ||
| 54 | lex.nextToken(); | ||
| 55 | break; | ||
| 56 | |||
| 57 | case Token::tOpenParen: | ||
| 58 | lex.nextToken(); | ||
| 59 | expr(); | ||
| 60 | if( lex[0].eType != Token::tCloseParen ) | ||
| 61 | { | ||
| 62 | throw Bu::ExceptionBase("Expected close paren"); | ||
| 63 | } | ||
| 64 | lex.nextToken(); | ||
| 65 | break; | ||
| 66 | |||
| 67 | case Token::tMinus: | ||
| 68 | lex.nextToken(); | ||
| 69 | exprP(); | ||
| 70 | tsStack.push( Token( Token::tNegate ) ); | ||
| 71 | break; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | /* | ||
| 75 | for(;;) | ||
| 76 | { | ||
| 25 | Token t = lex.nextToken(); | 77 | Token t = lex.nextToken(); |
| 26 | switch( t.eType ) | 78 | switch( t.eType ) |
| 27 | { | 79 | { |
| @@ -158,6 +210,7 @@ void Parser::parse() | |||
| 158 | } | 210 | } |
| 159 | } | 211 | } |
| 160 | } | 212 | } |
| 213 | */ | ||
| 161 | 214 | ||
| 162 | Number Parser::getVariable( const Bu::String &sName ) | 215 | Number Parser::getVariable( const Bu::String &sName ) |
| 163 | { | 216 | { |
| @@ -171,6 +224,7 @@ void Parser::setVariable( const Bu::String &sName, const Number &rValue ) | |||
| 171 | 224 | ||
| 172 | void Parser::unwind() | 225 | void Parser::unwind() |
| 173 | { | 226 | { |
| 227 | /* | ||
| 174 | for(;;) | 228 | for(;;) |
| 175 | { | 229 | { |
| 176 | DBS_START( PARSE ); | 230 | DBS_START( PARSE ); |
| @@ -312,6 +366,7 @@ void Parser::unwind() | |||
| 312 | getPriority( t.eType ) ) | 366 | getPriority( t.eType ) ) |
| 313 | return; | 367 | return; |
| 314 | } | 368 | } |
| 369 | */ | ||
| 315 | } | 370 | } |
| 316 | 371 | ||
| 317 | int Parser::reqTokens( Token::Type eType ) | 372 | int Parser::reqTokens( Token::Type eType ) |
diff --git a/src/parser.h b/src/parser.h index e163212..d50951b 100644 --- a/src/parser.h +++ b/src/parser.h | |||
| @@ -13,6 +13,35 @@ namespace Bu | |||
| 13 | 13 | ||
| 14 | class Lexer; | 14 | class Lexer; |
| 15 | 15 | ||
| 16 | /** | ||
| 17 | * | ||
| 18 | * expr: literal | ||
| 19 | * | variable | ||
| 20 | * | expr '+' expr | ||
| 21 | * | expr '-' expr | ||
| 22 | * | expr '*' expr | ||
| 23 | * | expr '/' expr | ||
| 24 | * | '(' expr ')' | ||
| 25 | * | '-' expr | ||
| 26 | * | variable '=' expr | ||
| 27 | * ; | ||
| 28 | * | ||
| 29 | * ----- | ||
| 30 | * | ||
| 31 | * expr': literal | ||
| 32 | * | variable | ||
| 33 | * | '(' expr ')' | ||
| 34 | * | '-' expr' | ||
| 35 | * ; | ||
| 36 | * | ||
| 37 | * expr: expr' '+' expr | ||
| 38 | * | expr' '-' expr | ||
| 39 | * | expr' '*' expr | ||
| 40 | * | expr' '/' expr | ||
| 41 | * | expr' | ||
| 42 | * | variable '=' expr | ||
| 43 | * ; | ||
| 44 | */ | ||
| 16 | class Parser | 45 | class Parser |
| 17 | { | 46 | { |
| 18 | public: | 47 | public: |
| @@ -24,6 +53,10 @@ public: | |||
| 24 | void setVariable( const Bu::String &sName, const Number &rValue ); | 53 | void setVariable( const Bu::String &sName, const Number &rValue ); |
| 25 | 54 | ||
| 26 | private: | 55 | private: |
| 56 | void expr(); | ||
| 57 | void exprP(); | ||
| 58 | |||
| 59 | private: | ||
| 27 | void unwind(); | 60 | void unwind(); |
| 28 | int reqTokens( Token::Type eType ); | 61 | int reqTokens( Token::Type eType ); |
| 29 | int getPriority( Token::Type eType ); | 62 | int getPriority( Token::Type eType ); |
| @@ -34,8 +67,8 @@ private: | |||
| 34 | Bu::Stream &rOut; | 67 | Bu::Stream &rOut; |
| 35 | typedef Bu::List<Token> TokenStack; | 68 | typedef Bu::List<Token> TokenStack; |
| 36 | typedef Bu::Hash<Bu::String, Number> VarHash; | 69 | typedef Bu::Hash<Bu::String, Number> VarHash; |
| 37 | TokenStack tsTerminal; | 70 | TokenStack tsStack; |
| 38 | TokenStack tsNonTerminal; | 71 | // TokenStack tsNonTerminal; |
| 39 | Number nZero; | 72 | Number nZero; |
| 40 | VarHash hVars; | 73 | VarHash hVars; |
| 41 | }; | 74 | }; |
diff --git a/src/token.cpp b/src/token.cpp index a03c821..30f3566 100644 --- a/src/token.cpp +++ b/src/token.cpp | |||
| @@ -4,6 +4,12 @@ | |||
| 4 | #include <bu/formatter.h> | 4 | #include <bu/formatter.h> |
| 5 | #include <bu/string.h> | 5 | #include <bu/string.h> |
| 6 | 6 | ||
| 7 | Token::Token() : | ||
| 8 | eType( tUninitialized ), | ||
| 9 | sVal( 0 ) | ||
| 10 | { | ||
| 11 | } | ||
| 12 | |||
| 7 | Token::Token( Type eType ) : | 13 | Token::Token( Type eType ) : |
| 8 | eType( eType ), | 14 | eType( eType ), |
| 9 | sVal( 0 ) | 15 | sVal( 0 ) |
diff --git a/src/token.h b/src/token.h index 92a7bcc..12a4904 100644 --- a/src/token.h +++ b/src/token.h | |||
| @@ -26,11 +26,15 @@ public: | |||
| 26 | tEquals, | 26 | tEquals, |
| 27 | tString, | 27 | tString, |
| 28 | 28 | ||
| 29 | tNegate, | ||
| 29 | tEndOfLine, | 30 | tEndOfLine, |
| 30 | 31 | ||
| 31 | tEndOfInput | 32 | tEndOfInput, |
| 33 | |||
| 34 | tUninitialized | ||
| 32 | }; | 35 | }; |
| 33 | 36 | ||
| 37 | Token(); | ||
| 34 | Token( Type eType ); | 38 | Token( Type eType ); |
| 35 | Token( Type eType, Bu::String *s ); | 39 | Token( Type eType, Bu::String *s ); |
| 36 | Token( Type eType, Number *n ); | 40 | Token( Type eType, Number *n ); |
diff --git a/src/unitparser.cpp b/src/unitparser.cpp index f518fdc..09b5982 100644 --- a/src/unitparser.cpp +++ b/src/unitparser.cpp | |||
| @@ -13,6 +13,8 @@ UnitParser::UnitParser() | |||
| 13 | "order1", Bu::UnitSuite::expectPass ); | 13 | "order1", Bu::UnitSuite::expectPass ); |
| 14 | add( static_cast<Bu::UnitSuite::Test>(&UnitParser::assignment), | 14 | add( static_cast<Bu::UnitSuite::Test>(&UnitParser::assignment), |
| 15 | "assignment", Bu::UnitSuite::expectPass ); | 15 | "assignment", Bu::UnitSuite::expectPass ); |
| 16 | add( static_cast<Bu::UnitSuite::Test>(&UnitParser::parse1), | ||
| 17 | "parse1", Bu::UnitSuite::expectPass ); | ||
| 16 | } | 18 | } |
| 17 | 19 | ||
| 18 | UnitParser::~UnitParser() | 20 | UnitParser::~UnitParser() |
| @@ -55,3 +57,8 @@ void UnitParser::assignment() | |||
| 55 | unitTest( mbOut.getString().trimWhitespace() == parser.getVariable("test").toString() ); | 57 | unitTest( mbOut.getString().trimWhitespace() == parser.getVariable("test").toString() ); |
| 56 | } | 58 | } |
| 57 | 59 | ||
| 60 | void UnitParser::parse1() | ||
| 61 | { | ||
| 62 | unitTest(parse("-5") == "-5"); | ||
| 63 | } | ||
| 64 | |||
diff --git a/src/unitparser.h b/src/unitparser.h index 744deef..c3b3687 100644 --- a/src/unitparser.h +++ b/src/unitparser.h | |||
| @@ -11,6 +11,7 @@ public: | |||
| 11 | 11 | ||
| 12 | void order1(); | 12 | void order1(); |
| 13 | void assignment(); | 13 | void assignment(); |
| 14 | void parse1(); | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | #endif | 17 | #endif |
