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 | |
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.
-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 |