1773 lines
50 KiB
C++
1773 lines
50 KiB
C++
#ifndef __NASAL_PARSER_H__
|
|
#define __NASAL_PARSER_H__
|
|
|
|
#include <cstring>
|
|
#include <stack>
|
|
#include <list>
|
|
|
|
enum token_type
|
|
{
|
|
__stack_end,
|
|
__equal,// =
|
|
__cmp_equal,// ==
|
|
__cmp_not_equal,// !=
|
|
__cmp_less,__cmp_less_or_equal,// < <=
|
|
__cmp_more,__cmp_more_or_equal,// > >=
|
|
__and_operator,__or_operator,__nor_operator,// and or !
|
|
__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
|
|
__unknown_type_id,__identifier,__identifiers,
|
|
__scalar,__scalars,__list,__hash,
|
|
__hash_member,__hash_members,
|
|
__statement,__statements,
|
|
__function,//function(){}
|
|
__definition,__assignment,__calculation,
|
|
__loop,__continue,__break,__for,__forindex,__foreach,__while,// for()while() continue; break;
|
|
__choose,__if,__elsif,__else,// if else if else
|
|
__return
|
|
};
|
|
|
|
void print_token_type(int type)
|
|
{
|
|
std::string context="";
|
|
switch(type)
|
|
{
|
|
case __stack_end:
|
|
context="__stack_end";
|
|
break;
|
|
case __equal:
|
|
context="=";
|
|
break;
|
|
case __cmp_equal:
|
|
context="==";
|
|
break;
|
|
case __cmp_not_equal:
|
|
context="!=";
|
|
break;
|
|
case __cmp_less:
|
|
context="<";
|
|
break;
|
|
case __cmp_less_or_equal:
|
|
context="<=";
|
|
break;
|
|
case __cmp_more:
|
|
context=">";
|
|
break;
|
|
case __cmp_more_or_equal:
|
|
context=">=";
|
|
break;
|
|
case __and_operator:
|
|
context="and";
|
|
break;
|
|
case __or_operator:
|
|
context="or";
|
|
break;
|
|
case __nor_operator:
|
|
context="!";
|
|
break;
|
|
case __add_operator:
|
|
context="+";
|
|
break;
|
|
case __sub_operator:
|
|
context="-";
|
|
break;
|
|
case __mul_operator:
|
|
context="*";
|
|
break;
|
|
case __div_operator:
|
|
context="/";
|
|
break;
|
|
case __link_operator:
|
|
context="~";
|
|
break;
|
|
case __add_equal:
|
|
context="+=";
|
|
break;
|
|
case __sub_equal:
|
|
context="-=";
|
|
break;
|
|
case __mul_equal:
|
|
context="*=";
|
|
break;
|
|
case __div_equal:
|
|
context="/=";
|
|
break;
|
|
case __link_equal:
|
|
context="~=";
|
|
break;
|
|
case __left_brace:
|
|
context="{";
|
|
break;
|
|
case __right_brace:
|
|
context="}";
|
|
break;
|
|
case __left_bracket:
|
|
context="[";
|
|
break;
|
|
case __right_bracket:
|
|
context="]";
|
|
break;
|
|
case __left_curve:
|
|
context="(";
|
|
break;
|
|
case __right_curve:
|
|
context=")";
|
|
break;
|
|
case __semi:
|
|
context=";";
|
|
break;
|
|
case __comma:
|
|
context=",";
|
|
break;
|
|
case __colon:
|
|
context=":";
|
|
break;
|
|
case __dot:
|
|
context=".";
|
|
break;
|
|
case __var:
|
|
context="var";
|
|
break;
|
|
case __func:
|
|
context="func";
|
|
break;
|
|
case __unknown_type_id:
|
|
context="__uid";
|
|
break;
|
|
case __identifier:
|
|
context="__id";
|
|
break;
|
|
case __identifiers:
|
|
context="__ids";
|
|
break;
|
|
case __scalar:
|
|
context="__scl";
|
|
break;
|
|
case __scalars:
|
|
context="__scls";
|
|
break;
|
|
case __list:
|
|
context="list";
|
|
break;
|
|
case __hash:
|
|
context="hash";
|
|
break;
|
|
case __hash_member:
|
|
context="__hmem";
|
|
break;
|
|
case __hash_members:
|
|
context="__hmems";
|
|
break;
|
|
case __continue:
|
|
context="continue";
|
|
break;
|
|
case __break:
|
|
context="break";
|
|
break;
|
|
case __for:
|
|
context="for";
|
|
break;
|
|
case __forindex:
|
|
context="forindex";
|
|
break;
|
|
case __foreach:
|
|
context="foreach";
|
|
break;
|
|
case __while:
|
|
context="while";
|
|
break;
|
|
case __if:
|
|
context="if";
|
|
break;
|
|
case __elsif:
|
|
context="elsif";
|
|
break;
|
|
case __else:
|
|
context="else";
|
|
break;
|
|
case __return:
|
|
context="return";
|
|
break;
|
|
case __calculation:
|
|
context="calculation";
|
|
break;
|
|
case __function:
|
|
context="function_module";
|
|
break;
|
|
}
|
|
std::cout<<context;
|
|
return;
|
|
}
|
|
|
|
struct parse_unit
|
|
{
|
|
int line;
|
|
int type;
|
|
std::string content;
|
|
};
|
|
|
|
class nasal_parser
|
|
{
|
|
private:
|
|
std::stack<parse_unit> parser;
|
|
public:
|
|
void stack_set_empty()
|
|
{
|
|
while(!parser.empty())
|
|
parser.pop();
|
|
return;
|
|
}
|
|
bool unknown_type_id_check()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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]!=__identifier) && (tbl[2]!=__calculation) && ((tbl[1]==__sub_operator) || (tbl[1]==__add_operator)) && (tbl[0]==__unknown_type_id))
|
|
{
|
|
parse_unit t;
|
|
t.type=__unknown_type_id;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool list_check()
|
|
{
|
|
int tbl[4]={0};
|
|
std::stack<parse_unit> 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[1]==__left_bracket) && (tbl[0]==__right_bracket))
|
|
{
|
|
parse_unit t;
|
|
t.type=__list;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(((tbl[3]!=__identifier) && (tbl[3]!=__unknown_type_id)) && (tbl[2]==__left_bracket) && ((tbl[1]==__scalar) || (tbl[1]==__scalars) || (tbl[1]==__identifier) || (tbl[1]==__identifiers) || (tbl[1]==__list) || (tbl[1]==__hash) || (tbl[1]==__calculation)) && (tbl[0]==__right_bracket))
|
|
{
|
|
parse_unit t;
|
|
t.type=__list;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool hash_check()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[2]==__left_brace) && ((tbl[1]==__hash_member) || (tbl[1]==__hash_members)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool scalar_check()
|
|
{
|
|
int tbl[4]={0};
|
|
std::stack<parse_unit> 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[2]!=__scalar) && (tbl[2]!=__identifier) && (tbl[2]!=__calculation) && ((tbl[1]==__sub_operator) || (tbl[1]==__add_operator)) && (tbl[0]==__scalar))
|
|
{
|
|
parse_unit t;
|
|
t.type=__scalar;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[3]!=__unknown_type_id) && (tbl[2]==__left_bracket) && ((tbl[1]==__identifier) || (tbl[1]==__identifiers) || (tbl[1]==__scalar) || (tbl[1]==__scalars)) && (tbl[0]==__right_bracket))
|
|
{
|
|
parse_unit t;
|
|
t.type=__scalar;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[3]!=__unknown_type_id) && (tbl[2]==__left_brace) && ((tbl[1]==__hash_member) || (tbl[1]==__hash_members)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__scalar;// !
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool scalars_reduction()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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[2]==__list) || (tbl[2]==__hash) || (tbl[2]==__calculation) || (tbl[2]==__function)) && (tbl[1]==__comma) && ((tbl[0]==__scalar) || (tbl[0]==__identifier) || (tbl[0]==__function) || (tbl[0]==__calculation)))
|
|
{
|
|
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) || (tbl[0]==__list) || (tbl[0]==__hash) || (tbl[0]==__calculation) || (tbl[0]==__function)))
|
|
{
|
|
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 identifier_check()
|
|
{
|
|
int tbl[4]={0};
|
|
std::stack<parse_unit> 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[2]!=__scalar) && (tbl[2]!=__identifier) && (tbl[2]!=__calculation) && ((tbl[1]==__sub_operator) || (tbl[1]==__add_operator)) && (tbl[0]==__identifier))
|
|
{
|
|
parse_unit t;
|
|
t.type=__identifier;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[3]==__unknown_type_id) && (tbl[2]==__left_bracket) && ((tbl[1]==__identifier) || (tbl[1]==__scalar) || (tbl[1]==__calculation)) && (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]==__unknown_type_id) || (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]==__unknown_type_id) && (tbl[2]==__dot) && (tbl[1]==__dot) && (tbl[0]==__dot))
|
|
{
|
|
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[3]==__unknown_type_id) && (tbl[2]==__left_curve) && ((tbl[1]==__identifier) || (tbl[1]==__identifiers) || (tbl[1]==__scalar) || (tbl[1]==__scalars) || (tbl[1]==__calculation) || (tbl[1]==__list) || (tbl[1]==__hash)) && (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]==__unknown_type_id) && (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 identifiers_reduction()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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 hashmember_check()
|
|
{
|
|
int tbl[9]={0};
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<9;++i)
|
|
{
|
|
if(parser.empty())
|
|
break;
|
|
temp.push(parser.top());
|
|
tbl[i]=temp.top().type;
|
|
parser.pop();
|
|
}
|
|
for(int i=0;i<9;++i)
|
|
{
|
|
if(temp.empty())
|
|
break;
|
|
parser.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
if((tbl[2]==__identifier) && (tbl[1]==__colon) && ((tbl[0]==__identifier) || (tbl[0]==__scalar) || (tbl[0]==__list) || (tbl[0]==__hash) || (tbl[0]==__calculation)))
|
|
{
|
|
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;
|
|
}
|
|
else if((tbl[6]==__identifier) && (tbl[5]==__colon) && (tbl[4]==__func) && (tbl[3]==__left_curve) && (tbl[2]==__right_curve) && (tbl[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash_member;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<7;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[7]==__identifier) && (tbl[6]==__colon) && (tbl[5]==__func) && (tbl[4]==__left_curve) && ((tbl[3]==__identifier) || (tbl[3]==__identifiers)) && (tbl[2]==__right_curve) && (tbl[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash_member;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<8;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[7]==__identifier) && (tbl[6]==__colon) && (tbl[5]==__func) && (tbl[4]==__left_curve) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash_member;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<8;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[8]==__identifier) && (tbl[7]==__colon) && (tbl[6]==__func) && (tbl[5]==__left_curve) && ((tbl[4]==__identifier) || (tbl[4]==__identifiers)) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash_member;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<9;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool hashmembers_reduction()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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;
|
|
}
|
|
else if(((tbl[2]==__hash_member) || (tbl[2]==__hash_members)) && (tbl[1]==__comma) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__hash_members;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
t.type=__right_brace;
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool calculation_reduction() //use __scalar
|
|
{
|
|
int tbl[7]={0};
|
|
std::stack<parse_unit> 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[1]==__nor_operator) && ((tbl[0]==__identifier) || (tbl[0]==__scalar)))
|
|
{
|
|
parse_unit t;
|
|
t.type=__calculation;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(((tbl[2]==__identifier) || (tbl[2]==__scalar) || (tbl[2]==__calculation))
|
|
&& ((tbl[1]==__add_operator) || (tbl[1]==__sub_operator)
|
|
|| (tbl[1]==__mul_operator) || (tbl[1]==__div_operator)
|
|
|| (tbl[1]==__link_operator) || (tbl[1]==__and_operator)
|
|
|| (tbl[1]==__or_operator) || (tbl[1]==__cmp_equal) || (tbl[1]==__cmp_not_equal)
|
|
|| (tbl[1]==__cmp_less) || (tbl[1]==__cmp_less_or_equal)
|
|
|| (tbl[1]==__cmp_more) || (tbl[1]==__cmp_more_or_equal))
|
|
&& ((tbl[0]==__identifier) || (tbl[0]==__scalar) || (tbl[0]==__calculation)))
|
|
{
|
|
parse_unit t;
|
|
t.type=__calculation;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[4]==__left_curve) && ((tbl[3]==__identifier) || (tbl[3]==__scalar) || (tbl[3]==__calculation)) && (tbl[2]==__right_curve)
|
|
&& ((tbl[1]==__add_operator) || (tbl[1]==__sub_operator)
|
|
|| (tbl[1]==__mul_operator) || (tbl[1]==__div_operator)
|
|
|| (tbl[1]==__link_operator) || (tbl[1]==__and_operator)
|
|
|| (tbl[1]==__or_operator) || (tbl[1]==__cmp_equal) || (tbl[1]==__cmp_not_equal)
|
|
|| (tbl[1]==__cmp_less) || (tbl[1]==__cmp_less_or_equal)
|
|
|| (tbl[1]==__cmp_more) || (tbl[1]==__cmp_more_or_equal))
|
|
&& ((tbl[0]==__identifier) || (tbl[0]==__scalar) || (tbl[0]==__calculation)))
|
|
{
|
|
parse_unit t;
|
|
t.type=__calculation;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<5;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(((tbl[4]==__identifier) || (tbl[4]==__scalar) || (tbl[4]==__calculation))
|
|
&& ((tbl[3]==__add_operator) || (tbl[3]==__sub_operator)
|
|
|| (tbl[3]==__mul_operator) || (tbl[3]==__div_operator)
|
|
|| (tbl[3]==__link_operator) || (tbl[3]==__and_operator)
|
|
|| (tbl[3]==__or_operator) || (tbl[3]==__cmp_equal) || (tbl[3]==__cmp_not_equal)
|
|
|| (tbl[3]==__cmp_less) || (tbl[3]==__cmp_less_or_equal)
|
|
|| (tbl[3]==__cmp_more) || (tbl[3]==__cmp_more_or_equal))
|
|
&& (tbl[2]==__left_curve) && ((tbl[1]==__identifier) || (tbl[1]==__scalar) || (tbl[1]==__calculation)) && (tbl[0]==__right_curve))
|
|
{
|
|
parse_unit t;
|
|
t.type=__calculation;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<5;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[6]==__left_curve) && ((tbl[5]==__identifier) || (tbl[5]==__scalar) || (tbl[5]==__calculation)) && (tbl[4]==__right_curve)
|
|
&& ((tbl[3]==__add_operator) || (tbl[3]==__sub_operator)
|
|
|| (tbl[3]==__mul_operator) || (tbl[3]==__div_operator)
|
|
|| (tbl[3]==__link_operator) || (tbl[3]==__and_operator)
|
|
|| (tbl[3]==__or_operator) || (tbl[3]==__cmp_equal) || (tbl[3]==__cmp_not_equal)
|
|
|| (tbl[3]==__cmp_less) || (tbl[3]==__cmp_less_or_equal)
|
|
|| (tbl[3]==__cmp_more) || (tbl[3]==__cmp_more_or_equal))
|
|
&& (tbl[2]==__left_curve) && ((tbl[1]==__identifier) || (tbl[1]==__scalar) || (tbl[1]==__calculation)) && (tbl[0]==__right_curve))
|
|
{
|
|
parse_unit t;
|
|
t.type=__calculation;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<7;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool definition_check()
|
|
{
|
|
int tbl[7]={0};
|
|
std::stack<parse_unit> 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[1]==__list) || (tbl[1]==__hash) || (tbl[1]==__calculation)) && (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[6]==__var) && (tbl[5]==__identifier) && (tbl[4]==__equal) && (tbl[3]==__left_curve) && ((tbl[2]==__identifier) || (tbl[2]==__scalar) || (tbl[2]==__list) || (tbl[2]==__hash) || (tbl[2]==__calculation)) && (tbl[1]==__right_curve) && (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[3]=__var) && (tbl[2]==__identifier) && (tbl[1]==__equal) && (tbl[0]==__function))
|
|
{
|
|
parse_unit t;
|
|
t.type=__definition;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<4;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool assignment_check()
|
|
{
|
|
int tbl[6]={0};
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<6;++i)
|
|
{
|
|
if(parser.empty())
|
|
break;
|
|
temp.push(parser.top());
|
|
tbl[i]=temp.top().type;
|
|
parser.pop();
|
|
}
|
|
for(int i=0;i<6;++i)
|
|
{
|
|
if(temp.empty())
|
|
break;
|
|
parser.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
if((tbl[3]==__identifier)
|
|
&& ((tbl[2]==__equal) || (tbl[2]==__add_equal) || (tbl[2]==__sub_equal)
|
|
|| (tbl[2]==__mul_equal) || (tbl[2]==__div_equal) || (tbl[2]==__link_equal))
|
|
&& ((tbl[1]==__identifier) || (tbl[1]==__scalar) || (tbl[1]==__list) || (tbl[1]==__hash) || (tbl[1]==__calculation)) && (tbl[0]==__semi))
|
|
{
|
|
parse_unit t;
|
|
t.type=__assignment;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<4;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[5]==__identifier) && ((tbl[4]==__equal) || (tbl[4]==__add_equal) || (tbl[4]==__sub_equal)
|
|
|| (tbl[4]==__mul_equal) || (tbl[4]==__div_equal) || (tbl[4]==__link_equal))
|
|
&& (tbl[3]==__left_curve) && ((tbl[2]==__identifier) || (tbl[2]==__scalar) || (tbl[2]==__list) || (tbl[2]==__hash) || (tbl[2]==__calculation)) && (tbl[1]==__right_curve) && (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;
|
|
}
|
|
return false;
|
|
}
|
|
bool function_def()
|
|
{
|
|
int tbl[7]={0};
|
|
std::stack<parse_unit> 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[2]==__func)&& (tbl[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[3]==__func) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<4;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[4]==__func) && (tbl[3]==__left_curve) && (tbl[2]==__right_curve) && (tbl[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<5;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[5]==__func) && (tbl[4]==__left_curve) && ((tbl[3]==__identifier) || (tbl[3]==__identifiers)) && (tbl[2]==__right_curve) && (tbl[1]==__left_brace) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<6;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[5]==__func) && (tbl[4]==__left_curve) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<6;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[6]==__func) && (tbl[5]==__left_curve) && ((tbl[4]==__identifier) || (tbl[4]==__identifiers)) && (tbl[3]==__right_curve) && (tbl[2]==__left_brace) && ((tbl[1]==__statement) || (tbl[1]==__statements)) && (tbl[0]==__right_brace))
|
|
{
|
|
parse_unit t;
|
|
t.type=__function;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<7;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool loop_reduction()
|
|
{
|
|
int tbl[10]={0};
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<10;++i)
|
|
{
|
|
if(parser.empty())
|
|
break;
|
|
temp.push(parser.top());
|
|
tbl[i]=temp.top().type;
|
|
parser.pop();
|
|
}
|
|
for(int i=0;i<10;++i)
|
|
{
|
|
if(temp.empty())
|
|
break;
|
|
parser.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
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;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<5;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
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<6;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
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<8;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
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<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;
|
|
}
|
|
return false;
|
|
}
|
|
bool choose_reduction()
|
|
{
|
|
int tbl[8]={0};
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<8;++i)
|
|
{
|
|
if(parser.empty())
|
|
break;
|
|
temp.push(parser.top());
|
|
tbl[i]=temp.top().type;
|
|
parser.pop();
|
|
}
|
|
for(int i=0;i<8;++i)
|
|
{
|
|
if(temp.empty())
|
|
break;
|
|
parser.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
if(((tbl[4]==__if) || (tbl[4]==__elsif))&& (tbl[3]==__left_curve) && ((tbl[2]==__scalar) || (tbl[2]==__identifier) || (tbl[2]==__calculation)) && (tbl[1]==__right_curve) && (tbl[0]==__statement))
|
|
{
|
|
parse_unit t;
|
|
t.type=__choose;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<5;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(((tbl[6]==__if) || (tbl[6]==__elsif)) && (tbl[5]==__left_curve) && ((tbl[4]==__scalar) || (tbl[4]==__identifier) || (tbl[4]==__calculation)) && (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<7;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[5]==__else) && (tbl[4]==__if) && (tbl[3]==__left_curve) && ((tbl[2]==__scalar) || (tbl[2]==__identifier) || (tbl[2]==__calculation)) && (tbl[1]==__right_curve) && (tbl[0]==__statement))
|
|
{
|
|
parse_unit t;
|
|
t.type=__choose;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<6;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[7]==__else) && (tbl[6]==__if) && (tbl[5]==__left_curve) && ((tbl[4]==__scalar) || (tbl[4]==__identifier) || (tbl[4]==__calculation)) && (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;
|
|
t.type=__choose;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[3]==__else) && (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<4;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool statement_check()
|
|
{
|
|
int tbl[3]={0};
|
|
std::stack<parse_unit> 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[0]==__definition) || (tbl[0]==__assignment) || (tbl[0]==__loop) || (tbl[0]==__choose))
|
|
{
|
|
parse_unit t;
|
|
t.type=__statement;
|
|
t.line=parser.top().line;
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[2]==__return) && ((tbl[1]==__identifier) || (tbl[1]==__scalar) || (tbl[1]==__list) || (tbl[1]==__hash) || (tbl[1]==__calculation)) && (tbl[0]==__semi))
|
|
{
|
|
parse_unit t;
|
|
t.type=__statement;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<3;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(((tbl[1]==__continue) || (tbl[1]==__break) || (tbl[1]==__return)) && (tbl[0]==__semi))
|
|
{
|
|
parse_unit t;
|
|
t.type=__statement;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if((tbl[2]!=__return) && (tbl[2]!=__dot) && (tbl[1]==__identifier) && (tbl[0]==__semi))
|
|
{
|
|
parse_unit t;
|
|
t.type=__statement;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
else if(tbl[0]==__semi)
|
|
{
|
|
parse_unit t;
|
|
t.type=__statement;
|
|
t.line=parser.top().line;
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
bool statements_reduction()
|
|
{
|
|
int tbl[2]={0};
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<2;++i)
|
|
{
|
|
if(parser.empty())
|
|
break;
|
|
temp.push(parser.top());
|
|
tbl[i]=temp.top().type;
|
|
parser.pop();
|
|
}
|
|
for(int i=0;i<2;++i)
|
|
{
|
|
if(temp.empty())
|
|
break;
|
|
parser.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
if(((tbl[1]==__statement) || (tbl[1]==__statements)) && ((tbl[0]==__statement) || (tbl[0]==__semi)))
|
|
{
|
|
parse_unit t;
|
|
t.type=__statements;
|
|
t.line=parser.top().line;
|
|
for(int i=0;i<2;++i)
|
|
parser.pop();
|
|
parser.push(t);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
void parse_process(std::list<token>& lexer)
|
|
{
|
|
stack_set_empty();
|
|
for(std::list<token>::iterator i=lexer.begin();i!=lexer.end();++i)
|
|
{
|
|
parse_unit temp_parse;
|
|
temp_parse.line=(*i).line;
|
|
if(((*i).content=="var") || ((*i).content=="func") || ((*i).content=="return") || ((*i).content=="nil") || ((*i).content=="continue") || ((*i).content=="break") || ((*i).content=="and") || ((*i).content=="or"))
|
|
{
|
|
if((*i).content=="var")
|
|
temp_parse.type=__var;
|
|
else if((*i).content=="func")
|
|
temp_parse.type=__func;
|
|
else if((*i).content=="return")
|
|
temp_parse.type=__return;
|
|
else if((*i).content=="nil")
|
|
temp_parse.type=__scalar;
|
|
else if((*i).content=="continue")
|
|
temp_parse.type=__continue;
|
|
else if((*i).content=="break")
|
|
temp_parse.type=__break;
|
|
else if((*i).content=="and")
|
|
temp_parse.type=__and_operator;
|
|
else if((*i).content=="or")
|
|
temp_parse.type=__or_operator;
|
|
}
|
|
else if((*i).type==IDENTIFIER)
|
|
{
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="[") && (temp_content!="(") && (temp_content!="."))
|
|
temp_parse.type=__identifier;
|
|
else
|
|
temp_parse.type=__unknown_type_id;
|
|
}
|
|
else
|
|
temp_parse.type=__unknown_type_id;
|
|
--i;
|
|
}
|
|
else if(((*i).content=="for") || ((*i).content=="foreach") || ((*i).content=="while") || ((*i).content=="forindex"))
|
|
{
|
|
if((*i).content=="for")
|
|
temp_parse.type=__for;
|
|
else if((*i).content=="forindex")
|
|
temp_parse.type=__forindex;
|
|
else if((*i).content=="foreach")
|
|
temp_parse.type=__foreach;
|
|
else if((*i).content=="while")
|
|
temp_parse.type=__while;
|
|
}
|
|
else if(((*i).content=="if") || ((*i).content=="else") || ((*i).content=="elsif"))
|
|
{
|
|
if((*i).content=="if")
|
|
temp_parse.type=__if;
|
|
else if((*i).content=="else")
|
|
temp_parse.type=__else;
|
|
else if((*i).content=="elsif")
|
|
temp_parse.type=__elsif;
|
|
}
|
|
else if(((*i).content=="==") || ((*i).content=="!=") || ((*i).content==">") || ((*i).content==">=") || ((*i).content=="<") || ((*i).content=="<="))
|
|
{
|
|
if((*i).content=="==")
|
|
temp_parse.type=__cmp_equal;
|
|
else if((*i).content=="!=")
|
|
temp_parse.type=__cmp_not_equal;
|
|
else if((*i).content==">")
|
|
temp_parse.type=__cmp_more;
|
|
else if((*i).content==">=")
|
|
temp_parse.type=__cmp_more_or_equal;
|
|
else if((*i).content=="<")
|
|
temp_parse.type=__cmp_less;
|
|
else if((*i).content=="<=")
|
|
temp_parse.type=__cmp_less_or_equal;
|
|
}
|
|
else if(((*i).content==";") || ((*i).content==",") || ((*i).content=="=") || ((*i).content==":") || ((*i).content=="."))
|
|
{
|
|
if((*i).content==";")
|
|
temp_parse.type=__semi;
|
|
else if((*i).content==",")
|
|
temp_parse.type=__comma;
|
|
else if((*i).content=="=")
|
|
temp_parse.type=__equal;
|
|
else if((*i).content==":")
|
|
temp_parse.type=__colon;
|
|
else if((*i).content==".")
|
|
temp_parse.type=__dot;
|
|
}
|
|
else if(((*i).type==NUMBER) || ((*i).type==STRING))
|
|
{
|
|
temp_parse.type=__scalar;
|
|
}
|
|
else if(((*i).content=="+") || ((*i).content=="-") || ((*i).content=="*") || ((*i).content=="/") || ((*i).content=="~") || ((*i).content=="!"))
|
|
{
|
|
if((*i).content=="+")
|
|
temp_parse.type=__add_operator;
|
|
else if((*i).content=="-")
|
|
temp_parse.type=__sub_operator;
|
|
else if((*i).content=="*")
|
|
temp_parse.type=__mul_operator;
|
|
else if((*i).content=="/")
|
|
temp_parse.type=__div_operator;
|
|
else if((*i).content=="~")
|
|
temp_parse.type=__link_operator;
|
|
else if((*i).content=="!")
|
|
temp_parse.type=__nor_operator;
|
|
}
|
|
else if(((*i).content=="+=") || ((*i).content=="-=") || ((*i).content=="*=") || ((*i).content=="/=") || ((*i).content=="~="))
|
|
{
|
|
if((*i).content=="+=")
|
|
temp_parse.type=__add_equal;
|
|
else if((*i).content=="-=")
|
|
temp_parse.type=__sub_equal;
|
|
else if((*i).content=="*=")
|
|
temp_parse.type=__mul_equal;
|
|
else if((*i).content=="/=")
|
|
temp_parse.type=__div_equal;
|
|
else if((*i).content=="~=")
|
|
temp_parse.type=__link_equal;
|
|
}
|
|
else if(((*i).content=="(") || ((*i).content==")") || ((*i).content=="[") || ((*i).content=="]") || ((*i).content=="{") || ((*i).content=="}"))
|
|
{
|
|
char c=(*i).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;
|
|
bool check_continue;
|
|
while(!reduction_complete)
|
|
{
|
|
check_continue=false;
|
|
if(unknown_type_id_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": -Uid"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(list_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": List"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(hash_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Hash"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(scalar_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Special Scalar"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="+") && (temp_content!="-") && (temp_content!="*") && (temp_content!="/") && (temp_content!="~")
|
|
&& (temp_content!="==") && (temp_content!="<") && (temp_content!="<=") && (temp_content!=">") && (temp_content!=">=") && (temp_content!="!=")
|
|
&& (temp_content!="and") && (temp_content!="or") && scalars_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Scalars"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(scalars_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Scalars"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
}
|
|
--i;
|
|
//scalars should avoid the operator after identifier
|
|
if(identifier_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Identifier | Call function | Call hash | Call array"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if(((temp_content==".") || (temp_content=="[")) && (!parser.empty()) && (parser.top().type==__identifier))
|
|
parser.top().type=__unknown_type_id;
|
|
}
|
|
--i;
|
|
if(identifiers_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Identifiers"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
//begin hashmember check
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="+") && (temp_content!="-") && (temp_content!="*") && (temp_content!="/") && (temp_content!="~")
|
|
&& (temp_content!="==") && (temp_content!="<") && (temp_content!="<=") && (temp_content!=">") && (temp_content!=">=") && (temp_content!="!=")
|
|
&& (temp_content!="and") && (temp_content!="or") && hashmember_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Hash member"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(hashmember_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Hash member"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
}
|
|
--i;
|
|
//end hashmember check
|
|
if(hashmembers_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Hash members"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(calculation_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": in Calculation"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(loop_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Loop"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(choose_reduction())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": If-else"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(definition_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Definition"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
//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())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Assignment"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(function_def())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Definition for func()"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(statement_check())
|
|
{
|
|
std::cout<<"line "<<parser.top().line<<": Statement"<<std::endl;
|
|
if(statements_reduction())
|
|
std::cout<<"line "<<parser.top().line<<": Statements"<<std::endl;
|
|
check_continue=true;
|
|
}
|
|
if(check_continue)
|
|
reduction_complete=false;
|
|
else
|
|
reduction_complete=true;
|
|
}
|
|
}
|
|
std::cout<<">>[Parser] Complete scanning."<<std::endl;
|
|
return;
|
|
}
|
|
void parse_quiet_process(std::list<token>& lexer)
|
|
{
|
|
stack_set_empty();
|
|
for(std::list<token>::iterator i=lexer.begin();i!=lexer.end();++i)
|
|
{
|
|
parse_unit temp_parse;
|
|
temp_parse.line=(*i).line;
|
|
if(((*i).content=="var") || ((*i).content=="func") || ((*i).content=="return") || ((*i).content=="nil") || ((*i).content=="continue") || ((*i).content=="break") || ((*i).content=="and") || ((*i).content=="or"))
|
|
{
|
|
if((*i).content=="var")
|
|
temp_parse.type=__var;
|
|
else if((*i).content=="func")
|
|
temp_parse.type=__func;
|
|
else if((*i).content=="return")
|
|
temp_parse.type=__return;
|
|
else if((*i).content=="nil")
|
|
temp_parse.type=__scalar;
|
|
else if((*i).content=="continue")
|
|
temp_parse.type=__continue;
|
|
else if((*i).content=="break")
|
|
temp_parse.type=__break;
|
|
else if((*i).content=="and")
|
|
temp_parse.type=__and_operator;
|
|
else if((*i).content=="or")
|
|
temp_parse.type=__or_operator;
|
|
}
|
|
else if((*i).type==IDENTIFIER)
|
|
{
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="[") && (temp_content!="(") && (temp_content!="."))
|
|
temp_parse.type=__identifier;
|
|
else
|
|
temp_parse.type=__unknown_type_id;
|
|
}
|
|
else
|
|
temp_parse.type=__unknown_type_id;
|
|
--i;
|
|
}
|
|
else if(((*i).content=="for") || ((*i).content=="foreach") || ((*i).content=="while") || ((*i).content=="forindex"))
|
|
{
|
|
if((*i).content=="for")
|
|
temp_parse.type=__for;
|
|
else if((*i).content=="forindex")
|
|
temp_parse.type=__forindex;
|
|
else if((*i).content=="foreach")
|
|
temp_parse.type=__foreach;
|
|
else if((*i).content=="while")
|
|
temp_parse.type=__while;
|
|
}
|
|
else if(((*i).content=="if") || ((*i).content=="else") || ((*i).content=="elsif"))
|
|
{
|
|
if((*i).content=="if")
|
|
temp_parse.type=__if;
|
|
else if((*i).content=="else")
|
|
temp_parse.type=__else;
|
|
else if((*i).content=="elsif")
|
|
temp_parse.type=__elsif;
|
|
}
|
|
else if(((*i).content=="==") || ((*i).content=="!=") || ((*i).content==">") || ((*i).content==">=") || ((*i).content=="<") || ((*i).content=="<="))
|
|
{
|
|
if((*i).content=="==")
|
|
temp_parse.type=__cmp_equal;
|
|
else if((*i).content=="!=")
|
|
temp_parse.type=__cmp_not_equal;
|
|
else if((*i).content==">")
|
|
temp_parse.type=__cmp_more;
|
|
else if((*i).content==">=")
|
|
temp_parse.type=__cmp_more_or_equal;
|
|
else if((*i).content=="<")
|
|
temp_parse.type=__cmp_less;
|
|
else if((*i).content=="<=")
|
|
temp_parse.type=__cmp_less_or_equal;
|
|
}
|
|
else if(((*i).content==";") || ((*i).content==",") || ((*i).content=="=") || ((*i).content==":") || ((*i).content=="."))
|
|
{
|
|
if((*i).content==";")
|
|
temp_parse.type=__semi;
|
|
else if((*i).content==",")
|
|
temp_parse.type=__comma;
|
|
else if((*i).content=="=")
|
|
temp_parse.type=__equal;
|
|
else if((*i).content==":")
|
|
temp_parse.type=__colon;
|
|
else if((*i).content==".")
|
|
temp_parse.type=__dot;
|
|
}
|
|
else if(((*i).type==NUMBER) || ((*i).type==STRING))
|
|
{
|
|
temp_parse.type=__scalar;
|
|
}
|
|
else if(((*i).content=="+") || ((*i).content=="-") || ((*i).content=="*") || ((*i).content=="/") || ((*i).content=="~") || ((*i).content=="!"))
|
|
{
|
|
if((*i).content=="+")
|
|
temp_parse.type=__add_operator;
|
|
else if((*i).content=="-")
|
|
temp_parse.type=__sub_operator;
|
|
else if((*i).content=="*")
|
|
temp_parse.type=__mul_operator;
|
|
else if((*i).content=="/")
|
|
temp_parse.type=__div_operator;
|
|
else if((*i).content=="~")
|
|
temp_parse.type=__link_operator;
|
|
else if((*i).content=="!")
|
|
temp_parse.type=__nor_operator;
|
|
}
|
|
else if(((*i).content=="+=") || ((*i).content=="-=") || ((*i).content=="*=") || ((*i).content=="/=") || ((*i).content=="~="))
|
|
{
|
|
if((*i).content=="+=")
|
|
temp_parse.type=__add_equal;
|
|
else if((*i).content=="-=")
|
|
temp_parse.type=__sub_equal;
|
|
else if((*i).content=="*=")
|
|
temp_parse.type=__mul_equal;
|
|
else if((*i).content=="/=")
|
|
temp_parse.type=__div_equal;
|
|
else if((*i).content=="~=")
|
|
temp_parse.type=__link_equal;
|
|
}
|
|
else if(((*i).content=="(") || ((*i).content==")") || ((*i).content=="[") || ((*i).content=="]") || ((*i).content=="{") || ((*i).content=="}"))
|
|
{
|
|
char c=(*i).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;
|
|
bool check_continue;
|
|
while(!reduction_complete)
|
|
{
|
|
check_continue=false;
|
|
if(unknown_type_id_check())
|
|
check_continue=true;
|
|
if(list_check())
|
|
check_continue=true;
|
|
if(hash_check())
|
|
check_continue=true;
|
|
if(scalar_check())
|
|
check_continue=true;
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="+") && (temp_content!="-") && (temp_content!="*") && (temp_content!="/") && (temp_content!="~")
|
|
&& (temp_content!="==") && (temp_content!="<") && (temp_content!="<=") && (temp_content!=">") && (temp_content!=">=") && (temp_content!="!=")
|
|
&& (temp_content!="and") && (temp_content!="or") && scalars_reduction())
|
|
check_continue=true;
|
|
}
|
|
else
|
|
{
|
|
if(scalars_reduction())
|
|
check_continue=true;
|
|
}
|
|
--i;
|
|
//scalars should avoid the operator after identifier
|
|
if(identifier_check())
|
|
check_continue=true;
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if(((temp_content==".") || (temp_content=="[")) && (!parser.empty()) && (parser.top().type==__identifier))
|
|
parser.top().type=__unknown_type_id;
|
|
}
|
|
--i;
|
|
if(identifiers_reduction())
|
|
check_continue=true;
|
|
//begin hashmember check
|
|
++i;
|
|
if(i!=lexer.end())
|
|
{
|
|
std::string temp_content=(*i).content;
|
|
if((temp_content!="+") && (temp_content!="-") && (temp_content!="*") && (temp_content!="/") && (temp_content!="~")
|
|
&& (temp_content!="==") && (temp_content!="<") && (temp_content!="<=") && (temp_content!=">") && (temp_content!=">=") && (temp_content!="!=")
|
|
&& (temp_content!="and") && (temp_content!="or") && hashmember_check())
|
|
check_continue=true;
|
|
}
|
|
else
|
|
{
|
|
if(hashmember_check())
|
|
check_continue=true;
|
|
}
|
|
--i;
|
|
//end hashmember check
|
|
if(hashmembers_reduction())
|
|
check_continue=true;
|
|
if(calculation_reduction())
|
|
check_continue=true;
|
|
if(loop_reduction())
|
|
check_continue=true;
|
|
if(choose_reduction())
|
|
check_continue=true;
|
|
if(definition_check())
|
|
check_continue=true;
|
|
//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())
|
|
check_continue=true;
|
|
if(function_def())
|
|
check_continue=true;
|
|
if(statement_check())
|
|
{
|
|
if(statements_reduction())
|
|
;
|
|
check_continue=true;
|
|
}
|
|
if(check_continue)
|
|
reduction_complete=false;
|
|
else
|
|
reduction_complete=true;
|
|
}
|
|
}
|
|
std::cout<<">>[Parser] Complete scanning."<<std::endl;
|
|
return;
|
|
}
|
|
void print_error()
|
|
{
|
|
std::stack<parse_unit> temp_stack;
|
|
while(!parser.empty())
|
|
{
|
|
if((parser.top().type!=__statement) && (parser.top().type!=__statements) && (parser.top().type!=__function) && (parser.top().type!=__definition) && (parser.top().type!=__assignment) && (parser.top().type!=__loop) && (parser.top().type!=__choose))
|
|
temp_stack.push(parser.top());
|
|
parser.pop();
|
|
}
|
|
if(!temp_stack.empty())
|
|
{
|
|
std::cout<<">>[Error] Parse error."<<std::endl;
|
|
while(!temp_stack.empty())
|
|
{
|
|
int l=temp_stack.top().line;
|
|
std::cout<<"line "<<l<<": ";
|
|
while(l==temp_stack.top().line)
|
|
{
|
|
print_token_type(temp_stack.top().type);
|
|
std::cout<<" ";
|
|
temp_stack.pop();
|
|
if(temp_stack.empty())
|
|
break;
|
|
}
|
|
std::cout<<std::endl;
|
|
}
|
|
}
|
|
else
|
|
std::cout<<">>[Parser] Parse analysis complete."<<std::endl;
|
|
return;
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|