#ifndef __NASAL_PARSE_H__ #define __NASAL_PARSE_H__ #include "nasal_lexer.h" #include "nasal_token.h" enum token_type { __stack_end, __equal,// = __add_operator,__sub_operator,__mul_operator,__div_operator,__link_operator,// + - * / ~ __add_equal,__sub_equal,__mul_equal,__div_equal,__link_equal,// += -= *= /= ~= __left_brace,__right_brace,// {} __left_bracket,__right_bracket,// [] __left_curve,__right_curve,// () __semi,// ; __comma,// , __colon,// : __dot,// . __var,// var reserve word __func,// func reserve word __identifier,__identifiers, __scalar,__scalars, __hash_member,__hash_members, __statement,__statements, __function,//function(){} __definition,__assignment, __loop,__continue,__break,// for()while() continue; break; __choose,// if else if else __return,__func_return }; struct parse_unit { int type; int line; }; class parse { public: std::stack parser; public: bool scalars_reduction(); bool identifier_check(); bool identifiers_reduction(); bool hashmember_check(); bool hashmembers_reduction(); bool definition_check(); void parse_work(token_list&); void print_stack(); void stack_set_empty(); }; bool parse::scalars_reduction() { int tbl[3]={0}; std::stack temp; for(int i=0;i<3;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<3;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if(((tbl[2]==__scalar) || (tbl[2]==__scalars)) && (tbl[1]==__comma) && ((tbl[0]==__scalar) || (tbl[0]==__identifier))) { parse_unit t; t.type=__scalars; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } else if(((tbl[2]==__identifier) || (tbl[2]==__identifiers)) && (tbl[1]==__comma) && (tbl[0]==__scalar)) { parse_unit t; t.type=__scalars; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } return false; } bool parse::identifier_check() { int tbl[4]={0}; std::stack temp; for(int i=0;i<4;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<4;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if((tbl[3]==__identifier) && (tbl[2]==__left_bracket) && ((tbl[1]==__identifier) || (tbl[1]==__scalar)) && (tbl[0]==__right_bracket)) { parse_unit t; t.type=__identifier; t.line=parser.top().line; for(int i=0;i<4;++i) parser.pop(); parser.push(t); return true; } else if((tbl[2]==__identifier) && (tbl[1]==__dot) && (tbl[0]==__identifier)) { parse_unit t; t.type=__identifier; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } else if((tbl[3]==__identifier) && (tbl[2]==__left_curve) && ((tbl[1]==__identifier) || (tbl[1]==__identifiers) || (tbl[1]==__scalar) || (tbl[1]==__scalars)) && (tbl[0]==__right_curve)) { parse_unit t; t.type=__identifier; t.line=parser.top().line; for(int i=0;i<4;++i) parser.pop(); parser.push(t); return true; } else if((tbl[2]==__identifier) && (tbl[1]==__left_curve) && (tbl[0]==__right_curve)) { parse_unit t; t.type=__identifier; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } return false; } bool parse::identifiers_reduction() { int tbl[3]={0}; std::stack temp; for(int i=0;i<3;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<3;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if(((tbl[2]==__identifier) || (tbl[2]==__identifiers)) && (tbl[1]==__comma) && (tbl[0]==__identifier)) { parse_unit t; t.type=__identifiers; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } return false; } bool parse::hashmember_check() { int tbl[3]={0}; std::stack temp; for(int i=0;i<3;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<3;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if((tbl[2]==__identifier) && (tbl[1]==__colon) && ((tbl[0]==__identifier) || (tbl[0]==__scalar))) { parse_unit t; t.type=__hash_member; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } return false; } bool parse::hashmembers_reduction() { int tbl[3]={0}; std::stack temp; for(int i=0;i<3;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<3;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if(((tbl[2]==__hash_member) || (tbl[2]==__hash_members)) && (tbl[1]==__comma) && (tbl[0]==__hash_member)) { parse_unit t; t.type=__hash_members; t.line=parser.top().line; for(int i=0;i<3;++i) parser.pop(); parser.push(t); return true; } return false; } bool parse::definition_check() { int tbl[7]={0}; std::stack temp; for(int i=0;i<7;++i) { if(parser.empty()) break; temp.push(parser.top()); tbl[i]=temp.top().type; parser.pop(); } for(int i=0;i<7;++i) { if(temp.empty()) break; parser.push(temp.top()); temp.pop(); } if((tbl[4]==__var) && (tbl[3]==__identifier) && (tbl[2]==__equal) && ((tbl[1]==__identifier) || (tbl[1]==__scalar)) && (tbl[0]==__semi)) { parse_unit t; t.type=__definition; t.line=parser.top().line; for(int i=0;i<5;++i) parser.pop(); parser.push(t); return true; } else if((tbl[5]==__var) && (tbl[4]==__identifier) && (tbl[3]==__equal) && (tbl[2]==__left_bracket) && (tbl[1]==__right_bracket) && (tbl[0]==__semi)) { parse_unit t; t.type=__definition; t.line=parser.top().line; for(int i=0;i<6;++i) parser.pop(); parser.push(t); return true; } else if((tbl[5]==__var) && (tbl[4]==__identifier) && (tbl[3]==__equal) && (tbl[2]==__left_brace) && (tbl[1]==__right_brace) && (tbl[0]==__semi)) { parse_unit t; t.type=__definition; t.line=parser.top().line; for(int i=0;i<6;++i) parser.pop(); parser.push(t); return true; } else if((tbl[6]==__var) && (tbl[5]==__identifier) && (tbl[4]==__equal) && (tbl[3]==__left_bracket) && ((tbl[2]==__scalar) || (tbl[2]==__scalars) || (tbl[2]==__identifier) || (tbl[2]==__identifiers)) && (tbl[1]==__right_bracket) && (tbl[0]==__semi)) { parse_unit t; t.type=__definition; t.line=parser.top().line; for(int i=0;i<7;++i) parser.pop(); parser.push(t); return true; } else if((tbl[6]==__var) && (tbl[5]==__identifier) && (tbl[4]==__equal) && (tbl[3]==__left_brace) && ((tbl[2]==__hash_member) || (tbl[2]==__hash_members)) && (tbl[1]==__right_brace) && (tbl[0]==__semi)) { parse_unit t; t.type=__definition; t.line=parser.top().line; for(int i=0;i<7;++i) parser.pop(); parser.push(t); return true; } return false; } void parse::stack_set_empty() { while(!parser.empty()) parser.pop(); return; } void parse::parse_work(token_list& lexer) { parse_unit temp_parse; token_unit *temp=lexer.get_head(); stack_set_empty(); while(temp->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")) { 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->type==IDENTIFIER) { temp_parse.type=__identifier; } 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=="~")) { 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->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); bool reduction_complete=false; while(!reduction_complete) { if(scalars_reduction()) { std::cout<<"line "<> parser stack:"<