From c088438896d9447cc8be260aeff255aeef3cda19 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Thu, 22 Aug 2019 17:45:19 +0800 Subject: [PATCH] Finish parser and error recognition --- version0.5/ebnf.cpp | 22 +- version0.5/nasal_interpreter.cpp | 17 +- version0.5/nasal_parse.h | 463 ++++++++++++++++++++++++++++--- 3 files changed, 441 insertions(+), 61 deletions(-) diff --git a/version0.5/ebnf.cpp b/version0.5/ebnf.cpp index 5540e8c..9632073 100644 --- a/version0.5/ebnf.cpp +++ b/version0.5/ebnf.cpp @@ -17,8 +17,8 @@ //NUMBER //STRING | - £¿£¿£¿£¿£¿£¿£¿£¿£¿£¿| <+>|<->|<*>||<~>|||<==>||<<>|<<=>|<>>|<>=> | - £¿£¿£¿£¿£¿£¿£¿£¿£¿£¿<(> | <)> // find a way to distinguish while(scalar) with real (scalar+-scalar)*scalar + | <+>|<->|<*>||<~>|||<==>||<<>|<<=>|<>>|<>=> | + <(> | <)> // find a way to distinguish while(scalar) with real (scalar+-scalar)*scalar <2> ::= | <,> | | <,> @@ -56,22 +56,22 @@ <=> <(><)> <{> | <}> <=> <(> | <)> <{> | <}> <10> ::= - <(> <)> - <(> <)> <{> | <}> + + <{> | <}> | <(> <)> | <(> <{> | <}> - <(> <;> <+=>|<-=>|<*=>||<~=>|<=> <)> - <(> <;> <+=>|<-=>|<*=>||<~=>|<=> <)> <{> | <}> + <(> <+=>|<-=>|<*=>||<~=>|<=> <)> + <(> <+=>|<-=>|<*=>||<~=>|<=> <)> <{> | <}> <11> ::= - | <(> <)> <{> | <}> - | <(> <)> - <(> <)> <{> | <}> - <(> <)> + | <{> | <}> + | + <{> | <}> + <{> | <}> <12> ::= ||<__func>|| - || <;> + ||| <;> | <;> <13> ::= | diff --git a/version0.5/nasal_interpreter.cpp b/version0.5/nasal_interpreter.cpp index c44f045..4e6b6ec 100644 --- a/version0.5/nasal_interpreter.cpp +++ b/version0.5/nasal_interpreter.cpp @@ -11,7 +11,7 @@ int main() std::getline(std::cin,command); if(command=="help") { - std::cout<<">> nasal-- script by ValKmjolnir"<> nasal script by ValKmjolnir"<> 1. |input file name to run the lexer."<> 2. \"cls\" |clear the screen."<> 3. \"exit\" |shut down the program."< temp; - for(int i=0;i<7;++i) + for(int i=0;i<10;++i) { if(parser.empty()) break; @@ -574,14 +732,24 @@ bool parse::loop_reduction() tbl[i]=temp.top().type; parser.pop(); } - for(int i=0;i<7;++i) + for(int i=0;i<10;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } - if((tbl[4]==__while) && (tbl[3]==__left_curve) && (tbl[2]==__scalar) && (tbl[1]==__right_curve) && (tbl[0]==__statement)) + if((tbl[2]==__while) && (tbl[1]==__scalar) && (tbl[0]==__statement)) + { + parse_unit t; + t.type=__loop; + t.line=parser.top().line; + for(int i=0;i<3;++i) + parser.pop(); + parser.push(t); + return true; + } + else if((tbl[4]==__while) && (tbl[3]==__scalar) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) { parse_unit t; t.type=__loop; @@ -591,32 +759,50 @@ bool parse::loop_reduction() parser.push(t); return true; } - else if((tbl[6]==__while) && (tbl[5]==__left_curve) && (tbl[4]==__scalar) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) + else if(((tbl[5]==__foreach) || (tbl[5]==__forindex)) && (tbl[4]==__left_curve) && (tbl[3]==__statement) && (tbl[2]==__identifier) && (tbl[1]==__right_curve) && (tbl[0]==__statement)) { parse_unit t; t.type=__loop; t.line=parser.top().line; - for(int i=0;i<7;++i) + for(int i=0;i<6;++i) parser.pop(); parser.push(t); return true; } - else if(((tbl[4]==__for) || (tbl[4]==__foreach) || (tbl[4]==__forindex)) && (tbl[3]==__left_curve) && (tbl[2]==__statements) && (tbl[1]==__right_curve) && (tbl[0]==__statement)) + else if(((tbl[7]==__foreach) || (tbl[7]==__forindex)) && (tbl[6]==__left_curve) && (tbl[5]==__statement) && (tbl[4]==__identifier) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) { parse_unit t; t.type=__loop; t.line=parser.top().line; - for(int i=0;i<5;++i) + for(int i=0;i<8;++i) parser.pop(); parser.push(t); return true; } - else if(((tbl[6]==__for) || (tbl[6]==__foreach) || (tbl[6]==__forindex)) && (tbl[5]==__left_curve) && (tbl[4]==__statements) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) + else if((tbl[7]==__for) && (tbl[6]==__left_curve) && (tbl[5]==__statements) + && (tbl[4]==__identifier) + && ((tbl[3]==__equal) || (tbl[3]==__add_equal) || (tbl[3]==__sub_equal) || (tbl[3]==__mul_equal) || (tbl[3]==__div_equal) || (tbl[3]==__link_equal) || (tbl[3]==__equal)) + && ((tbl[2]==__identifier) || (tbl[2]==__scalar)) + && (tbl[1]==__right_curve) && (tbl[0]==__statement)) { parse_unit t; t.type=__loop; t.line=parser.top().line; - for(int i=0;i<7;++i) + for(int i=0;i<8;++i) + parser.pop(); + parser.push(t); + return true; + } + else if((tbl[9]==__for) && (tbl[8]==__left_curve) && (tbl[7]==__statements) + && (tbl[6]==__identifier) + && ((tbl[5]==__equal) || (tbl[5]==__add_equal) || (tbl[5]==__sub_equal) || (tbl[5]==__mul_equal) || (tbl[5]==__div_equal) || (tbl[5]==__link_equal) || (tbl[5]==__equal)) + && ((tbl[4]==__identifier) || (tbl[4]==__scalar)) + && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) + { + parse_unit t; + t.type=__loop; + t.line=parser.top().line; + for(int i=0;i<10;++i) parser.pop(); parser.push(t); return true; @@ -642,7 +828,17 @@ bool parse::choose_reduction() parser.push(temp.top()); temp.pop(); } - if(((tbl[4]==__if) || (tbl[4]==__elsif)) && (tbl[3]==__left_curve) && (tbl[2]==__scalar) && (tbl[1]==__right_curve) && (tbl[0]==__statement)) + if(((tbl[2]==__if) || (tbl[2]==__elsif)) && (tbl[1]==__scalar) && (tbl[0]==__statement)) + { + parse_unit t; + t.type=__choose; + t.line=parser.top().line; + for(int i=0;i<3;++i) + parser.pop(); + parser.push(t); + return true; + } + else if(((tbl[4]==__if) || (tbl[4]==__elsif)) && (tbl[3]==__scalar) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) { parse_unit t; t.type=__choose; @@ -652,17 +848,17 @@ bool parse::choose_reduction() parser.push(t); return true; } - else if(((tbl[6]==__if) || (tbl[6]==__elsif)) && (tbl[5]==__left_curve) && (tbl[4]==__scalar) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) + else if((tbl[3]==__else) && (tbl[2]==__if) && (tbl[1]==__scalar) && (tbl[0]==__statement)) { parse_unit t; t.type=__choose; t.line=parser.top().line; - for(int i=0;i<7;++i) + for(int i=0;i<4;++i) parser.pop(); parser.push(t); return true; } - else if((tbl[5]==__else) && (tbl[4]==__if) && (tbl[3]==__left_curve) && (tbl[2]==__scalar) && (tbl[1]==__right_curve) && (tbl[0]==__statement)) + else if((tbl[5]==__else) && (tbl[4]==__if) && (tbl[3]==__scalar) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) { parse_unit t; t.type=__choose; @@ -672,16 +868,6 @@ bool parse::choose_reduction() parser.push(t); return true; } - else if((tbl[7]==__else) && (tbl[6]==__if) && (tbl[5]==__left_curve) && (tbl[4]==__scalar) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace)) - { - parse_unit t; - t.type=__choose; - t.line=parser.top().line; - for(int i=0;i<8;++i) - parser.pop(); - parser.push(t); - return true; - } else if((tbl[1]==__else) && (tbl[0]==__statement)) { parse_unit t; @@ -742,7 +928,7 @@ bool parse::statement_check() parser.push(t); return true; } - else if((tbl[2]!=__return) && ((tbl[1]==__identifier) || (tbl[1]==__continue) || (tbl[1]==__break)) && (tbl[0]==__semi)) + else if((tbl[2]!=__return) && ((tbl[1]==__identifier) || (tbl[1]==__continue) || (tbl[1]==__break) || (tbl[1]==__scalar)) && (tbl[0]==__semi)) { parse_unit t; t.type=__statement; @@ -791,7 +977,7 @@ void parse::stack_set_empty() parser.pop(); return; } -void parse::parse_work(token_list& lexer) +void parse::print_parser(token_list& lexer) { parse_unit temp_parse; token_unit *temp=lexer.get_head(); @@ -1004,26 +1190,215 @@ void parse::parse_work(token_list& lexer) } return; } - -void parse::print_stack() +void parse::run_parser(token_list& lexer) { - std::cout<<">> parser stack:"<next) + { + temp=temp->next; + temp_parse.line=temp->line; + if((temp->content=="var") || (temp->content=="func") || (temp->content=="return") || (temp->content=="nil") || (temp->content=="continue") || (temp->content=="break") || (temp->content=="and") || (temp->content=="or")) + { + if(temp->content=="var") + temp_parse.type=__var; + else if(temp->content=="func") + temp_parse.type=__func; + else if(temp->content=="return") + temp_parse.type=__return; + else if(temp->content=="nil") + temp_parse.type=__scalar; + else if(temp->content=="continue") + temp_parse.type=__continue; + else if(temp->content=="break") + temp_parse.type=__break; + else if(temp->content=="and") + temp_parse.type=__and_operator; + else if(temp->content=="or") + temp_parse.type=__or_operator; + } + else if(temp->type==IDENTIFIER) + { + temp_parse.type=__identifier; + } + else if((temp->content=="for") || (temp->content=="foreach") || (temp->content=="while") || (temp->content=="forindex")) + { + if(temp->content=="for") + temp_parse.type=__for; + else if(temp->content=="forindex") + temp_parse.type=__forindex; + else if(temp->content=="foreach") + temp_parse.type=__foreach; + else if(temp->content=="while") + temp_parse.type=__while; + } + else if((temp->content=="if") || (temp->content=="else") || (temp->content=="elsif")) + { + if(temp->content=="if") + temp_parse.type=__if; + else if(temp->content=="else") + temp_parse.type=__else; + else if(temp->content=="elsif") + temp_parse.type=__elsif; + } + else if((temp->content=="==") || (temp->content=="!=") || (temp->content==">") || (temp->content==">=") || (temp->content=="<") || (temp->content=="<=")) + { + if(temp->content=="==") + temp_parse.type=__cmp_equal; + else if(temp->content=="!=") + temp_parse.type=__cmp_not_equal; + else if(temp->content==">") + temp_parse.type=__cmp_more; + else if(temp->content==">=") + temp_parse.type=__cmp_more_or_equal; + else if(temp->content=="<") + temp_parse.type=__cmp_less; + else if(temp->content=="<=") + temp_parse.type=__cmp_less_or_equal; + } + else if((temp->content==";") || (temp->content==",") || (temp->content=="=") || (temp->content==":") || (temp->content==".")) + { + if(temp->content==";") + temp_parse.type=__semi; + else if(temp->content==",") + temp_parse.type=__comma; + else if(temp->content=="=") + temp_parse.type=__equal; + else if(temp->content==":") + temp_parse.type=__colon; + else if(temp->content==".") + temp_parse.type=__dot; + } + else if((temp->type==NUMBER) || (temp->type==STRING)) + { + temp_parse.type=__scalar; + } + else if((temp->content=="+") || (temp->content=="-") || (temp->content=="*") || (temp->content=="/") || (temp->content=="~") || (temp->content=="!")) + { + if(temp->content=="+") + temp_parse.type=__add_operator; + else if(temp->content=="-") + temp_parse.type=__sub_operator; + else if(temp->content=="*") + temp_parse.type=__mul_operator; + else if(temp->content=="/") + temp_parse.type=__div_operator; + else if(temp->content=="~") + temp_parse.type=__link_operator; + else if(temp->content=="!") + temp_parse.type=__nor_operator; + } + else if((temp->content=="+=") || (temp->content=="-=") || (temp->content=="*=") || (temp->content=="/=") || (temp->content=="~=")) + { + if(temp->content=="+=") + temp_parse.type=__add_equal; + else if(temp->content=="-=") + temp_parse.type=__sub_equal; + else if(temp->content=="*=") + temp_parse.type=__mul_equal; + else if(temp->content=="/=") + temp_parse.type=__div_equal; + else if(temp->content=="~=") + temp_parse.type=__link_equal; + } + else if((temp->content=="(") || (temp->content==")") || (temp->content=="[") || (temp->content=="]") || (temp->content=="{") || (temp->content=="}")) + { + char c=temp->content[0]; + switch(c) + { + case '(': + temp_parse.type=__left_curve; + break; + case ')': + temp_parse.type=__right_curve; + break; + case '[': + temp_parse.type=__left_bracket; + break; + case ']': + temp_parse.type=__right_bracket; + break; + case '{': + temp_parse.type=__left_brace; + break; + case '}': + temp_parse.type=__right_brace; + break; + } + } + parser.push(temp_parse);//push this into stack + + bool reduction_complete=false; + while(!reduction_complete) + { + if(scalars_reduction()) + continue; + if(identifier_check()) + continue; + if(identifiers_reduction()) + continue; + if(hashmember_check()) + continue; + if(hashmembers_reduction()) + continue; + if(calculation_reduction()) + continue; + if(loop_reduction()) + continue; + if(choose_reduction()) + continue; + if(definition_check()) + continue; + //assignment check must be put behind the definition check + //because the assignment check has the same method to check + //but assignment checks without a "var" so if you put the + //assignment before definition,there may be a mistake. + if(assignment_check()) + continue; + if(function_def()) + continue; + if(statement_check()) + { + if(statements_reduction()) + ; + continue; + } + reduction_complete=true; + } + } + return; +} + +void parse::print_error() +{ + std::stack temp_stack; while(!parser.empty()) { - if(parser.top().type==__definition) - std::cout<<"line "<>[Error]: Parse error."<> Parse analysis complete."<