diff options
author | Mike Buland <eichlan@xagasoft.com> | 2016-11-30 14:52:39 -0700 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2016-11-30 14:52:39 -0700 |
commit | 2297488eae424197dce4ed6b1dc50ae67c093074 (patch) | |
tree | c28956f193f9ee8bdde083f780984736d48a5e41 /src | |
parent | 0321e6e39b8cf24718cf853c28f0f35443753264 (diff) | |
download | clic-2297488eae424197dce4ed6b1dc50ae67c093074.tar.gz clic-2297488eae424197dce4ed6b1dc50ae67c093074.tar.bz2 clic-2297488eae424197dce4ed6b1dc50ae67c093074.tar.xz clic-2297488eae424197dce4ed6b1dc50ae67c093074.zip |
I managed to confuse myself pretty well.
I'm doing some reading up on LR(n) parsers, I just sort of started without
thinking about it this time, not a great approach. I feel like it can't hurt
to have an update on how this works anyway. I think the idea was solid, but
I was trying to do too much at once.
One question is what my goal should be for this. I could just solve the
equation as we go, or I could generate code that will let us solve the equation.
The later is obviously attractive in that it will let us run an expression
more than once, and maybe even define functions. I like that.
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.cpp | 13 | ||||
-rw-r--r-- | src/parser.cpp | 34 | ||||
-rw-r--r-- | src/parser.h | 2 | ||||
-rw-r--r-- | src/token.cpp | 26 | ||||
-rw-r--r-- | src/token.h | 2 |
5 files changed, 69 insertions, 8 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp index fbcaafb..55d155d 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp | |||
@@ -26,15 +26,15 @@ Lexer::~Lexer() | |||
26 | 26 | ||
27 | void Lexer::nextToken() | 27 | void Lexer::nextToken() |
28 | { | 28 | { |
29 | if( iLookAheadSize <= 1 ) | 29 | if( iLookAheadUsed <= 1 ) |
30 | { | 30 | { |
31 | iLookAheadSize = 0; | 31 | iLookAheadUsed = 0; |
32 | iLookAheadStart = 0; | 32 | iLookAheadStart = 0; |
33 | } | 33 | } |
34 | else | 34 | else |
35 | { | 35 | { |
36 | iLookAheadStart = (iLookAheadStart+1)%iLookAheadSize; | 36 | iLookAheadStart = (iLookAheadStart+1)%iLookAheadSize; |
37 | iLookAheadSize--; | 37 | iLookAheadUsed--; |
38 | } | 38 | } |
39 | } | 39 | } |
40 | 40 | ||
@@ -55,11 +55,16 @@ void Lexer::fillToken() | |||
55 | default: | 55 | default: |
56 | throw Bu::ExceptionBase("Invalid mode."); | 56 | throw Bu::ExceptionBase("Invalid mode."); |
57 | } | 57 | } |
58 | 58 | /* | |
59 | Bu::sio << "read[" | 59 | Bu::sio << "read[" |
60 | << ((iLookAheadUsed+iLookAheadStart)%iLookAheadSize) | 60 | << ((iLookAheadUsed+iLookAheadStart)%iLookAheadSize) |
61 | << "]: " | 61 | << "]: " |
62 | << aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].eType; | 62 | << aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].eType; |
63 | if( aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].eType == Token::tNumber ) | ||
64 | Bu::sio << "(" | ||
65 | << aLookAhead[(iLookAheadUsed+iLookAheadStart)%iLookAheadSize].nVal->toString() << ")"; | ||
66 | Bu::sio << Bu::sio.nl; | ||
67 | */ | ||
63 | } | 68 | } |
64 | 69 | ||
65 | Token Lexer::nextTokenNormal() | 70 | Token Lexer::nextTokenNormal() |
diff --git a/src/parser.cpp b/src/parser.cpp index 1f9a193..0131ba3 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
@@ -23,25 +23,53 @@ void Parser::parse() | |||
23 | for(;;) | 23 | for(;;) |
24 | { | 24 | { |
25 | lex.nextToken(); | 25 | lex.nextToken(); |
26 | if( lex[0].eType == Token::tEndOfInput ) | ||
27 | break; | ||
28 | |||
26 | expr(); | 29 | expr(); |
27 | 30 | ||
31 | Bu::sio << "Final stack:"; | ||
28 | for( TokenStack::iterator i = tsStack.begin(); i; i++ ) | 32 | for( TokenStack::iterator i = tsStack.begin(); i; i++ ) |
29 | { | 33 | { |
30 | Bu::sio << *i << " "; | 34 | Bu::sio << " " << (*i).eType; |
35 | if( (*i).eType == Token::tNumber ) | ||
36 | { | ||
37 | Bu::sio << "(" << (*i).nVal->toString() << ")"; | ||
38 | } | ||
31 | } | 39 | } |
40 | Bu::sio << Bu::sio.nl; | ||
32 | } | 41 | } |
33 | } | 42 | } |
34 | 43 | ||
35 | void Parser::expr() | 44 | void Parser::expr() |
36 | { | 45 | { |
46 | if( lex[0].eType == Token::tEndOfInput ) | ||
47 | return; | ||
37 | if( lex[0].eType == Token::tVariable && | 48 | if( lex[0].eType == Token::tVariable && |
38 | lex[1].eType == Token::tEquals ) | 49 | lex[1].eType == Token::tEquals ) |
39 | { | 50 | { |
40 | // Assignment! | 51 | Token t = lex[0]; |
52 | lex.nextToken(); | ||
53 | lex.nextToken(); | ||
41 | expr(); | 54 | expr(); |
55 | |||
42 | return; | 56 | return; |
43 | } | 57 | } |
44 | exprP(); | 58 | exprP(); |
59 | |||
60 | switch( lex[0].eType ) | ||
61 | { | ||
62 | case Token::tPlus: | ||
63 | case Token::tMinus: | ||
64 | case Token::tMultiply: | ||
65 | case Token::tDivide: | ||
66 | case Token::tModulus: | ||
67 | Token t = lex[0]; | ||
68 | lex.nextToken(); | ||
69 | expr(); | ||
70 | tsStack.push( t ); | ||
71 | break; | ||
72 | } | ||
45 | } | 73 | } |
46 | 74 | ||
47 | void Parser::exprP() | 75 | void Parser::exprP() |
@@ -222,7 +250,7 @@ void Parser::setVariable( const Bu::String &sName, const Number &rValue ) | |||
222 | hVars.insert( sName, rValue ); | 250 | hVars.insert( sName, rValue ); |
223 | } | 251 | } |
224 | 252 | ||
225 | void Parser::unwind() | 253 | void Parser::reduce() |
226 | { | 254 | { |
227 | /* | 255 | /* |
228 | for(;;) | 256 | for(;;) |
diff --git a/src/parser.h b/src/parser.h index d50951b..05fab0b 100644 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -57,7 +57,7 @@ private: | |||
57 | void exprP(); | 57 | void exprP(); |
58 | 58 | ||
59 | private: | 59 | private: |
60 | void unwind(); | 60 | void reduce(); |
61 | int reqTokens( Token::Type eType ); | 61 | int reqTokens( Token::Type eType ); |
62 | int getPriority( Token::Type eType ); | 62 | int getPriority( Token::Type eType ); |
63 | Number &deref( Token &t ); | 63 | Number &deref( Token &t ); |
diff --git a/src/token.cpp b/src/token.cpp index 30f3566..c591e6a 100644 --- a/src/token.cpp +++ b/src/token.cpp | |||
@@ -55,6 +55,32 @@ Token::~Token() | |||
55 | } | 55 | } |
56 | } | 56 | } |
57 | 57 | ||
58 | Token &Token::operator=( const Token &rhs ) | ||
59 | { | ||
60 | switch( eType ) | ||
61 | { | ||
62 | case tNumber: | ||
63 | delete nVal; | ||
64 | break; | ||
65 | |||
66 | case tVariable: | ||
67 | case tCommand: | ||
68 | case tString: | ||
69 | delete sVal; | ||
70 | break; | ||
71 | |||
72 | default: | ||
73 | break; | ||
74 | } | ||
75 | eType = rhs.eType; | ||
76 | sVal = rhs.sVal; | ||
77 | |||
78 | Token &rMod = const_cast<Token &>(rhs); | ||
79 | rMod.sVal = 0; | ||
80 | |||
81 | return *this; | ||
82 | } | ||
83 | |||
58 | Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) | 84 | Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) |
59 | { | 85 | { |
60 | switch( eType ) | 86 | switch( eType ) |
diff --git a/src/token.h b/src/token.h index 12a4904..8d7dc20 100644 --- a/src/token.h +++ b/src/token.h | |||
@@ -41,6 +41,8 @@ public: | |||
41 | Token( const Token &rSrc ); | 41 | Token( const Token &rSrc ); |
42 | ~Token(); | 42 | ~Token(); |
43 | 43 | ||
44 | Token &operator=( const Token &rhs ); | ||
45 | |||
44 | Type eType; | 46 | Type eType; |
45 | union | 47 | union |
46 | { | 48 | { |