|
|
|
发新文章 |
|
|
好友学习递归时无法理解用递归下降的方式分析表达式,所以写了个简单的例子, 为了使代码尽可能简单,省略了此法分析模块,直接使用人脑分析的词法^_^ 由于好友不懂c++,所以这里虽然用的c++,但还是按照c的方式写的代码。
#include <vector> #include <iostream> #include <assert.h>
using namespace std;
#define MAX_ID_LENGTH 20
#define ID 1 #define DIGIT 2 #define EQUAL 3 #define PLUS 4 #define MUL 5 #define SUB 6
#define INPUT_CODE "var = 20 - 59"
char* KeyWord[] = { "print", "status", };
typedef struct _TOKEN_ { int type; char str[MAX_ID_LENGTH]; }Token;
typedef vector<Token> Tokens; Tokens g_tokens; int g_tokenIndex = 0;
int ParseStatement(); int ParseExpresstion(); int ParseTerm(); int ParseFactor();
void PushBackToken(int type, const char* str) { Token token = { 0 }; token.type = type; strcpy(token.str, str);
g_tokens.push_back(token); }
void GetAllTokens() { PushBackToken(ID, "var"); PushBackToken(EQUAL, "="); PushBackToken(DIGIT, "20"); PushBackToken(MUL, "*"); PushBackToken(DIGIT, "3"); }
bool IsEnd() { return g_tokenIndex == g_tokens.size(); }
Token GetNextToken() { if ( g_tokenIndex <= g_tokens.size() - 1 ) { return g_tokens[g_tokenIndex++]; } else { Token token = { 0 }; return token; } }
void UnGetNextToken() { --g_tokenIndex; }
void ShowAllTokens() { for (int i = 0; i < g_tokens.size(); i++) { cout << g_tokens[i].str; } }
int ParseStatement() { Token token = GetNextToken();
if ( ID != token.type ) { cout << "statement should begin with identifier" << endl; }
token = GetNextToken(); if ( EQUAL != token.type ) { cout << "= lost" << endl; }
return ParseExpresstion(); }
int ParseExpresstion() { int sum = ParseTerm(); while (true) { if ( IsEnd() ) { return sum; }
Token token = GetNextToken(); if ( PLUS == token.type ) { sum += ParseTerm(); } else if ( SUB == token.type ) { sum -= ParseTerm(); } //todo: add "-" else { UnGetNextToken(); break; } }
return sum; }
int ParseTerm() { int mulResult = ParseFactor(); while ( true ) { if ( IsEnd() ) { return mulResult; } Token token = GetNextToken(); if ( MUL == token.type ) { mulResult *= ParseFactor(); } else { UnGetNextToken(); break; } //todo add "/" }
return mulResult; }
int ParseFactor() { Token token = GetNextToken(); if ( ID == token.type ) { cout << "statement should begin with identifier" << endl; } else if( DIGIT == token.type ) { return atoi(token.str); } else { UnGetNextToken(); //cout << "bug found" << endl; }
return 1; }
void TestPlus() { g_tokenIndex = 0; g_tokens.clear(); PushBackToken(ID, "var"); PushBackToken(EQUAL, "="); PushBackToken(DIGIT, "20"); PushBackToken(PLUS, "+"); PushBackToken(DIGIT, "30"); PushBackToken(PLUS, "+"); PushBackToken(DIGIT, "30"); PushBackToken(SUB, "-"); PushBackToken(DIGIT, "1"); assert(79 == ParseStatement()); }
void TestSub() { g_tokenIndex = 0; g_tokens.clear(); PushBackToken(ID, "var"); PushBackToken(EQUAL, "="); PushBackToken(DIGIT, "20"); PushBackToken(SUB, "-"); PushBackToken(DIGIT, "30"); assert(-10 == ParseStatement()); }
void TestMul() { g_tokenIndex = 0; g_tokens.clear(); PushBackToken(ID, "var"); PushBackToken(EQUAL, "="); PushBackToken(DIGIT, "20"); PushBackToken(PLUS, "+"); PushBackToken(DIGIT, "30"); PushBackToken(MUL, "*"); PushBackToken(DIGIT, "30"); assert(920 == ParseStatement()); }
int main() { TestPlus(); //测试加法 TestSub(); //测试减法 TestMul(); //测试乘法
return 0; }
|