summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2016-11-30 14:52:39 -0700
committerMike Buland <eichlan@xagasoft.com>2016-11-30 14:52:39 -0700
commit2297488eae424197dce4ed6b1dc50ae67c093074 (patch)
treec28956f193f9ee8bdde083f780984736d48a5e41
parent0321e6e39b8cf24718cf853c28f0f35443753264 (diff)
downloadclic-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.
-rw-r--r--src/lexer.cpp13
-rw-r--r--src/parser.cpp34
-rw-r--r--src/parser.h2
-rw-r--r--src/token.cpp26
-rw-r--r--src/token.h2
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
27void Lexer::nextToken() 27void 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
65Token Lexer::nextTokenNormal() 70Token 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
35void Parser::expr() 44void 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
47void Parser::exprP() 75void 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
225void Parser::unwind() 253void 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
59private: 59private:
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
58Token &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
58Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) 84Bu::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 {