From 0e7aceaf8401fc0b2d0f0ad592260d35f30a1a61 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Fri, 23 Aug 2019 17:58:51 +0800 Subject: [PATCH] New version with STL list & stack --- version0.6/main.cpp | 66 ++++++++ version0.6/nasal.h | 8 + version0.6/nasal_lexer.h | 323 ++++++++++++++++++++++++++++++++++++++ version0.6/nasal_parser.h | 62 ++++++++ 4 files changed, 459 insertions(+) create mode 100644 version0.6/main.cpp create mode 100644 version0.6/nasal.h create mode 100644 version0.6/nasal_lexer.h create mode 100644 version0.6/nasal_parser.h diff --git a/version0.6/main.cpp b/version0.6/main.cpp new file mode 100644 index 0000000..6fb6b5d --- /dev/null +++ b/version0.6/main.cpp @@ -0,0 +1,66 @@ +#include "nasal.h" +#include + +int main() +{ + resource_programme_process prog; + nasal_lexer lex; + nasal_parser par; + std::string command; + std::cout<<">> nasal-- script by ValKmjolnir"<> input \"help\" to find help."<> "; + std::getline(std::cin,command); + if(command=="help") + { + std::cout<<">> nasal script interpreter by ValKmjolnir"<> 1. |input file name to run the lexer. (-lexer)"<> 2. \"cls\" |clear the screen."<> 3. \"exit\" |shut down the program."<> 4. \"lexer\" |see tokens in stack."<> 5. \"parser\"|run parser. (-parser)"<> 6. \"del\" |delete all elements in stack."<> 7. \"run\" |run the programme in stack. (-lexer -parser)"<> 8. \"rs\" |check the source program."<>[Delete] Complete."< +#include +#include +#include + +#define OPERATOR 1 //界符 or 运算符 +#define IDENTIFIER 2 //自定义标识符 +#define NUMBER 3 //数字 +#define RESERVEWORD 4 //关键字 +#define STRING 5 //字符串类型 +#define FAIL -1 //失败 +#define SCANEND -2 //扫描完成 +#define ERRORFOUND -3 //异常错误 + +std::string reserve_word[15]= +{ + "for","foreach","forindex","while", + "var","func","break","continue","return", + "if","else","elsif","nil","and","or" +}; + +int isReserveWord(std::string &p) +{ + for(int i=0;i<15;++i) + if(reserve_word[i]==p) + return i+1; + return FAIL; +} + +bool isLetter(char t) +{ + return (('a'<=t) && (t<='z') || ('A'<=t) && (t<='Z')); +} + +bool isNumber(char t) +{ + return (('0'<=t) && (t<='9')); +} + +class resource_programme_process +{ + private: + char *resource; + public: + resource_programme_process() + { + resource=NULL; + resource=new char[16777216]; + } + ~resource_programme_process() + { + if(resource) + delete []resource; + } + char* use_file() + { + return resource; + } + void input_file(std::string& filename) + { + std::ifstream fin(filename); + if(fin.fail()) + { + std::cout<<">> [Error] Cannot load file: "< lexer; + public: + void scanner(int &syn,const char* source,std::string &__token,int &ptr,int &line) + { + char temp; + temp=source[ptr]; + while(temp==' ' || temp=='\n' || temp=='\t' || temp=='\r' || temp<0 || temp>127) + { + ++ptr; + if(temp=='\n') + ++line; + temp=source[ptr]; + } + __token=""; + if(isLetter(temp) || temp=='_') + { + __token+=temp; + ++ptr; + temp=source[ptr]; + while(isLetter(temp) || isNumber(temp) || temp=='_') + { + __token+=temp; + ++ptr; + temp=source[ptr]; + } + syn=isReserveWord(__token); + if(syn==FAIL) + syn=IDENTIFIER; + else + syn=RESERVEWORD; + } + else if(isNumber(temp)) + { + int PointCnt=0; + while(isNumber(temp)) + { + __token+=temp; + ++ptr; + temp=source[ptr]; + if(temp=='.' && !PointCnt) + { + ++PointCnt; + __token+=temp; + ++ptr; + temp=source[ptr]; + } + } + syn=NUMBER; + } + else if(temp=='(' || temp==')' || temp=='[' || temp==']' || temp=='{' || + temp=='}' || temp==',' || temp==';' || temp=='|' || temp==':' || + temp=='?' || temp=='.' || temp=='`' || temp=='\'' || temp=='&'|| + temp=='%' || temp=='$' || temp=='^') + { + __token+=temp; + ++ptr; + syn=OPERATOR; + } + else if(temp=='=' || temp=='+' || temp=='-' || temp=='*' || temp=='!' || temp=='/' || temp=='<' || temp=='>' || temp=='~') + { + syn=OPERATOR; + __token+=temp; + ++ptr; + temp=source[ptr]; + if(temp=='=') + { + __token+=temp; + ++ptr; + } + } + else if(temp=='\\') + { + syn=OPERATOR; + __token+=temp; + ++ptr; + temp=source[ptr]; + if(temp=='=' || temp=='n' || temp=='t' || temp=='r' || temp=='\\' || temp=='\'' || temp=='\"') + { + __token+=temp; + ++ptr; + } + } + else if(temp=='\"') + { + syn=STRING; + __token+=temp; + ++ptr; + temp=source[ptr]; + while(temp!='\"') + { + if(temp=='\\') + { + __token+=temp; + + ++ptr; + temp=source[ptr]; + __token+=temp; + + ++ptr; + temp=source[ptr]; + } + else + { + __token+=temp; + ++ptr; + temp=source[ptr]; + } + if(temp==0 || temp=='\n') + break; + } + //add the last char \" + if(temp=='\"') + { + __token+=temp; + ++ptr; + } + else + __token+=" __missing_end_of_string"; + } + else if(temp==0) + { + syn=SCANEND; + return; + } + else + { + syn=FAIL; + std::cout<<">>[Error] Unexpected error occurred: "<>[Error] Cannot identify "<>[Lexer] max size: "<0)//all Syn type is larger than zero + { + temp.line=line; + temp.type=syn; + temp.content=__token; + lexer.push_back(temp); + } + } + std::cout<<">>[Lexer] Complete scanning."<::iterator i=lexer.begin();i!=lexer.end();++i) + { + temp=*i; + std::cout<<"line "<& return_list() + { + return lexer; + } +}; + + + + +#endif diff --git a/version0.6/nasal_parser.h b/version0.6/nasal_parser.h new file mode 100644 index 0000000..aa547a0 --- /dev/null +++ b/version0.6/nasal_parser.h @@ -0,0 +1,62 @@ +#ifndef __NASAL_PARSER_H__ +#define __NASAL_PARSER_H__ + +#include +#include +#include +#include + +struct parse_unit +{ + int line; + std::string content; +}; + +class nasal_parser +{ + private: + std::stack parser; + public: + void parse_process(std::list& lexer) + { + for(std::list::iterator i=lexer.begin();i!=lexer.end();++i) + { + parse_unit temp; + temp.line=(*i).line; + temp.content=(*i).content; + parser.push(temp); + } + std::cout<<">>[Parser] Complete scanning."< temp; + while(!parser.empty()) + { + temp.push(parser.top()); + parser.pop(); + } + int nowline=0; + if(temp.empty()) + { + std::cout<<">>[Parser] Empty stack."<