919 lines
29 KiB
C++
919 lines
29 KiB
C++
#ifndef __NASAL_PARSER_H__
|
|
#define __NASAL_PARSER_H__
|
|
|
|
#include <stack>
|
|
#include <cstring>
|
|
|
|
enum token_type
|
|
{
|
|
__stack_end=1,
|
|
__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,__func,__return,
|
|
__if,__elsif,__else,
|
|
__id,__dynamic_id,
|
|
__continue,__break,
|
|
__for,__forindex,__foreach,__while,
|
|
//end of operators & reserve words
|
|
__two_operator,
|
|
__scalar,__data_list,
|
|
__number,__string,
|
|
__list,
|
|
__hash,
|
|
__hash_member,__hash_member_list,
|
|
__identifier,
|
|
__statement,__statements,
|
|
__function,
|
|
__call_function,
|
|
__call_list,
|
|
__call_hash,
|
|
__call,
|
|
__definition,__return_scalar,
|
|
__assignment,__pre_assignment,__assignment_operator,
|
|
__calculation,
|
|
__loop,
|
|
__choose,__if_choose,__elsif_choose,__else_choose,
|
|
__program
|
|
};
|
|
|
|
const int max_len=15;
|
|
struct cmp_seq
|
|
{
|
|
int tokens[max_len];
|
|
int res;
|
|
};
|
|
// must put in a reverse way
|
|
cmp_seq par[]=
|
|
{
|
|
{{__program,__statement}, __program},
|
|
{{__add_operator},__two_operator},
|
|
{{__sub_operator},__two_operator},
|
|
{{__mul_operator},__two_operator},
|
|
{{__div_operator},__two_operator},
|
|
{{__link_operator},__two_operator},
|
|
{{__and_operator},__two_operator},
|
|
{{__or_operator},__two_operator},
|
|
{{__cmp_equal},__two_operator},
|
|
{{__cmp_not_equal},__two_operator},
|
|
{{__cmp_less},__two_operator},
|
|
{{__cmp_less_or_equal},__two_operator},
|
|
{{__cmp_more},__two_operator},
|
|
{{__cmp_more_or_equal},__two_operator},
|
|
{{__add_equal},__assignment_operator},
|
|
{{__sub_equal},__assignment_operator},
|
|
{{__mul_equal},__assignment_operator},
|
|
{{__div_equal},__assignment_operator},
|
|
{{__link_equal},__assignment_operator},
|
|
|
|
{{__number},__scalar},
|
|
{{__string},__scalar},
|
|
{{__calculation},__scalar},
|
|
|
|
{{__call_list},__call},
|
|
{{__call_hash},__call},
|
|
{{__call_function},__call},
|
|
|
|
{{__id,__comma,__id},__data_list},
|
|
{{__id,__comma,__scalar},__data_list},
|
|
{{__id,__comma,__call},__data_list},
|
|
{{__id,__comma,__function},__data_list},
|
|
{{__id,__comma,__list},__data_list},
|
|
{{__id,__comma,__hash},__data_list},
|
|
{{__scalar,__comma,__id},__data_list},
|
|
{{__scalar,__comma,__scalar},__data_list},
|
|
{{__scalar,__comma,__call},__data_list},
|
|
{{__scalar,__comma,__function},__data_list},
|
|
{{__scalar,__comma,__list},__data_list},
|
|
{{__scalar,__comma,__hash},__data_list},
|
|
{{__call,__comma,__id},__data_list},
|
|
{{__call,__comma,__scalar},__data_list},
|
|
{{__call,__comma,__call},__data_list},
|
|
{{__call,__comma,__function},__data_list},
|
|
{{__call,__comma,__list},__data_list},
|
|
{{__call,__comma,__hash},__data_list},
|
|
{{__function,__comma,__id},__data_list},
|
|
{{__function,__comma,__scalar},__data_list},
|
|
{{__function,__comma,__call},__data_list},
|
|
{{__function,__comma,__function},__data_list},
|
|
{{__function,__comma,__list},__data_list},
|
|
{{__function,__comma,__hash},__data_list},
|
|
{{__list,__comma,__id},__data_list},
|
|
{{__list,__comma,__scalar},__data_list},
|
|
{{__list,__comma,__call},__data_list},
|
|
{{__list,__comma,__function},__data_list},
|
|
{{__list,__comma,__list},__data_list},
|
|
{{__list,__comma,__hash},__data_list},
|
|
{{__hash,__comma,__id},__data_list},
|
|
{{__hash,__comma,__scalar},__data_list},
|
|
{{__hash,__comma,__call},__data_list},
|
|
{{__hash,__comma,__function},__data_list},
|
|
{{__hash,__comma,__list},__data_list},
|
|
{{__hash,__comma,__hash},__data_list},
|
|
{{__data_list,__comma,__id},__data_list},
|
|
{{__data_list,__comma,__scalar},__data_list},
|
|
{{__data_list,__comma,__call},__data_list},
|
|
{{__data_list,__comma,__function},__data_list},
|
|
{{__data_list,__comma,__list},__data_list},
|
|
{{__data_list,__comma,__hash},__data_list},
|
|
|
|
{{__id,__colon,__id},__hash_member},
|
|
{{__scalar,__colon,__id},__hash_member},
|
|
{{__call,__colon,__id},__hash_member},
|
|
{{__list,__colon,__id},__hash_member},
|
|
{{__hash,__colon,__id},__hash_member},
|
|
{{__right_brace,__left_brace,__colon,__id},__hash_member},
|
|
{{__function,__colon,__id},__hash_member},
|
|
|
|
{{__hash_member,__comma,__hash_member},__hash_member_list},
|
|
{{__hash_member_list,__comma,__hash_member},__hash_member_list},
|
|
|
|
{{__right_bracket,__left_bracket},__list},
|
|
{{__right_bracket,__id,__left_bracket},__list},
|
|
{{__right_bracket,__scalar,__left_bracket},__list},
|
|
{{__right_bracket,__call,__left_bracket},__list},
|
|
{{__right_bracket,__function,__left_bracket},__list},
|
|
{{__right_bracket,__data_list,__left_bracket},__list},
|
|
|
|
{{__right_brace,__hash_member,__left_brace},__hash},
|
|
{{__right_brace,__hash_member_list,__left_brace},__hash},
|
|
|
|
{{__list,__id},__call_list},
|
|
{{__list,__call},__call_list},
|
|
{{__right_bracket,__hash_member,__left_bracket,__id},__call_list},
|
|
{{__right_bracket,__hash_member,__left_bracket,__call},__call_list},
|
|
{{__right_bracket,__colon,__id,__left_bracket,__id},__call_list},
|
|
{{__right_bracket,__colon,__scalar,__left_bracket,__id},__call_list},
|
|
{{__right_bracket,__colon,__call,__left_bracket,__id},__call_list},
|
|
{{__right_bracket,__colon,__id,__left_bracket,__call},__call_list},
|
|
{{__right_bracket,__colon,__scalar,__left_bracket,__call},__call_list},
|
|
{{__right_bracket,__colon,__call,__left_bracket,__call},__call_list},
|
|
|
|
{{__id,__dot,__id},__call_hash},
|
|
{{__id,__dot,__call},__call_hash},
|
|
{{__scalar,__dot,__id},__call_hash},
|
|
{{__scalar,__dot,__call},__call_hash},
|
|
{{__call,__dot,__id},__call_hash},
|
|
{{__call,__dot,__call},__call_hash},
|
|
|
|
{{__right_curve,__left_curve,__id},__call_function},
|
|
{{__right_curve,__id,__left_curve,__id},__call_function},
|
|
{{__right_curve,__scalar,__left_curve,__id},__call_function},
|
|
{{__right_curve,__call,__left_curve,__id},__call_function},
|
|
{{__right_curve,__list,__left_curve,__id},__call_function},
|
|
{{__right_curve,__hash,__left_curve,__id},__call_function},
|
|
{{__right_curve,__function,__left_curve,__id},__call_function},
|
|
{{__right_curve,__data_list,__left_curve,__id},__call_function},
|
|
|
|
{{__id,__two_operator,__id},__calculation},
|
|
{{__id,__two_operator,__scalar},__calculation},
|
|
{{__id,__two_operator,__call},__calculation},
|
|
{{__scalar,__two_operator,__id},__calculation},
|
|
{{__scalar,__two_operator,__scalar},__calculation},
|
|
{{__scalar,__two_operator,__call},__calculation},
|
|
{{__call,__two_operator,__id},__calculation},
|
|
{{__call,__two_operator,__scalar},__calculation},
|
|
{{__call,__two_operator,__call},__calculation},
|
|
{{__id,__nor_operator},__calculation},
|
|
{{__scalar,__nor_operator},__calculation},
|
|
{{__call,__nor_operator},__calculation},
|
|
{{__right_curve,__id,__left_curve},__calculation},
|
|
{{__right_curve,__scalar,__left_curve},__calculation},
|
|
{{__right_curve,__call,__left_curve},__calculation},
|
|
|
|
{{__semi,__id,__return},__return_scalar},
|
|
{{__semi,__scalar,__return},__return_scalar},
|
|
{{__semi,__call,__return},__return_scalar},
|
|
{{__semi,__function,__return},__return_scalar},
|
|
{{__semi,__list,__return},__return_scalar},
|
|
{{__semi,__hash,__return},__return_scalar},
|
|
{{__semi,__return},__return_scalar},
|
|
|
|
{{__right_brace,__left_brace,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__func},__function},
|
|
|
|
{{__right_brace,__left_brace,__right_curve,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__left_curve,__func},__function},
|
|
|
|
{{__right_brace,__left_brace,__right_curve,__id,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__scalar,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__scalar,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__list,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__list,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__hash,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__hash,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__function,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__function,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__dynamic_id,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__dynamic_id,__left_curve,__func},__function},
|
|
{{__right_brace,__left_brace,__right_curve,__data_list,__left_curve,__func},__function},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__data_list,__left_curve,__func},__function},
|
|
|
|
{{__right_brace,__left_brace,__right_curve,__id,__left_curve,__if},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__scalar,__left_curve,__if},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__left_curve,__if},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__left_curve,__if},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__scalar,__left_curve,__if},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__left_curve,__if},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__id,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__scalar,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__scalar,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__left_curve,__if,__else},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__id,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__scalar,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__scalar,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__left_curve,__elsif},__choose},
|
|
{{__right_brace,__left_brace,__else},__choose},
|
|
{{__right_brace,__statement,__left_brace,__else},__choose},
|
|
|
|
{{__semi,__id,__equal,__id,__var},__definition},
|
|
{{__semi,__right_brace,__left_brace,__equal,__id,__var},__definition},
|
|
{{__semi,__scalar,__equal,__id,__var},__definition},
|
|
{{__semi,__call,__equal,__id,__var},__definition},
|
|
{{__semi,__function,__equal,__id,__var},__definition},
|
|
{{__semi,__list,__equal,__id,__var},__definition},
|
|
{{__semi,__hash,__equal,__id,__var},__definition},
|
|
{{__semi,__id,__var},__definition},
|
|
|
|
{{__id,__equal,__id},__pre_assignment},
|
|
{{__scalar,__equal,__id},__pre_assignment},
|
|
{{__call,__equal,__id},__pre_assignment},
|
|
{{__function,__equal,__id},__pre_assignment},
|
|
{{__list,__equal,__id},__pre_assignment},
|
|
{{__hash,__equal,__id},__pre_assignment},
|
|
{{__id,__equal,__call},__pre_assignment},
|
|
{{__scalar,__equal,__call},__pre_assignment},
|
|
{{__call,__equal,__call},__pre_assignment},
|
|
{{__function,__equal,__call},__pre_assignment},
|
|
{{__list,__equal,__call},__pre_assignment},
|
|
{{__hash,__equal,__call},__pre_assignment},
|
|
{{__id,__assignment_operator,__id},__pre_assignment},
|
|
{{__scalar,__assignment_operator,__id},__pre_assignment},
|
|
{{__call,__assignment_operator,__id},__pre_assignment},
|
|
{{__id,__assignment_operator,__call},__pre_assignment},
|
|
{{__scalar,__assignment_operator,__call},__pre_assignment},
|
|
{{__call,__assignment_operator,__call},__pre_assignment},
|
|
{{__semi,__pre_assignment},__assignment},
|
|
|
|
{{__right_brace,__left_brace,__right_curve,__id,__left_curve,__while},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__scalar,__left_curve,__while},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__left_curve,__while},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__left_curve,__while},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__scalar,__left_curve,__while},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__left_curve,__while},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__id,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__list,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__list,__statement,__left_curve,__forindex},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__id,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__call,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__list,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__id,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__call,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__list,__statement,__left_curve,__foreach},__loop},
|
|
{{__right_brace,__left_brace,__right_curve,__pre_assignment,__statement,__left_curve,__for},__loop},
|
|
{{__right_brace,__statement,__left_brace,__right_curve,__pre_assignment,__statement,__left_curve,__for},__loop},
|
|
|
|
{{__semi,__id,__semi},__semi},
|
|
{{__semi,__call,__semi},__semi},
|
|
{{__semi,__scalar,__semi},__semi},
|
|
{{__semi,__list,__semi},__semi},
|
|
{{__semi,__hash,__semi},__semi},
|
|
{{__semi,__semi},__semi},
|
|
{{__semi,__id,__right_brace},__right_brace},
|
|
{{__semi,__call,__right_brace},__right_brace},
|
|
{{__semi,__scalar,__right_brace},__right_brace},
|
|
{{__semi,__list,__right_brace},__right_brace},
|
|
{{__semi,__hash,__right_brace},__right_brace},
|
|
{{__semi,__id,__left_brace},__left_brace},
|
|
{{__semi,__call,__left_brace},__left_brace},
|
|
{{__semi,__scalar,__left_brace},__left_brace},
|
|
{{__semi,__list,__left_brace},__left_brace},
|
|
{{__semi,__hash,__left_brace},__left_brace},
|
|
{{__semi,__id,__left_curve},__left_curve},
|
|
{{__semi,__call,__left_curve},__left_curve},
|
|
{{__semi,__scalar,__left_curve},__left_curve},
|
|
{{__semi,__list,__left_curve},__left_curve},
|
|
{{__semi,__hash,__left_curve},__left_curve},
|
|
|
|
{{__return_scalar},__statement},
|
|
{{__semi,__continue},__statement},
|
|
{{__semi,__break},__statement},
|
|
{{__statement,__statement},__statement},
|
|
{{__loop},__statement},
|
|
{{__choose},__statement},
|
|
{{__definition},__statement},
|
|
{{__assignment},__statement},
|
|
};
|
|
int num_of_par=sizeof(par)/sizeof(cmp_seq);
|
|
|
|
void print_token(int type)
|
|
{
|
|
std::string context="";
|
|
switch(type)
|
|
{
|
|
case __stack_end:
|
|
context="#";
|
|
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 __id:
|
|
context="id";
|
|
break;
|
|
case __dynamic_id:
|
|
context="id...";
|
|
break;
|
|
case __number:
|
|
context="number";
|
|
break;
|
|
case __string:
|
|
context="string";
|
|
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 __scalar:
|
|
context="scalar";
|
|
break;
|
|
case __list:
|
|
context="list";
|
|
break;
|
|
case __hash:
|
|
context="hash";
|
|
break;
|
|
case __hash_member:
|
|
context="hash_member";
|
|
break;
|
|
case __identifier:
|
|
context="identifier";
|
|
break;
|
|
case __statement:
|
|
context="statement";
|
|
break;
|
|
case __statements:
|
|
context="statements";
|
|
break;
|
|
case __function:
|
|
context="function";
|
|
break;
|
|
case __call_function:
|
|
context="call_func";
|
|
break;
|
|
case __call_list:
|
|
context="call_list";
|
|
break;
|
|
case __call_hash:
|
|
context="call_hash";
|
|
break;
|
|
case __definition:
|
|
context="definition;";
|
|
break;
|
|
case __assignment:
|
|
context="assignment;";
|
|
break;
|
|
case __calculation:
|
|
context="calc";
|
|
break;
|
|
case __loop:
|
|
context="loop";
|
|
break;
|
|
case __choose:
|
|
context="choose";
|
|
break;
|
|
case __if_choose:
|
|
context="if_choose";
|
|
break;
|
|
case __elsif_choose:
|
|
context="else_if_choose";
|
|
break;
|
|
case __else_choose:
|
|
context="else_choose";
|
|
break;
|
|
case __program:
|
|
context="program";
|
|
break;
|
|
|
|
case __call:
|
|
context="call";
|
|
break;
|
|
case __data_list:
|
|
context="datas";
|
|
break;
|
|
case __hash_member_list:
|
|
context="hash_members";
|
|
break;
|
|
case __pre_assignment:
|
|
context="pre_assignment";
|
|
break;
|
|
case __two_operator:
|
|
context="operator";
|
|
break;
|
|
case __assignment_operator:
|
|
context="operator";
|
|
break;
|
|
case __return_scalar:
|
|
context="return_scl;";
|
|
break;
|
|
default:
|
|
context="unknown_type";
|
|
break;
|
|
}
|
|
std::cout<<context;
|
|
return;
|
|
}
|
|
|
|
struct parse_unit
|
|
{
|
|
int line;
|
|
int type;
|
|
};
|
|
class PDA
|
|
{
|
|
private:
|
|
std::stack<parse_unit> main_stack;
|
|
std::stack<parse_unit> comp_stack;
|
|
public:
|
|
void set_stack_empty()
|
|
{
|
|
while(!main_stack.empty())
|
|
main_stack.pop();
|
|
while(!comp_stack.empty())
|
|
comp_stack.pop();
|
|
parse_unit temp;
|
|
temp.line=0;
|
|
temp.type=__stack_end;
|
|
main_stack.push(temp);
|
|
temp.type=__var;
|
|
main_stack.push(temp);
|
|
temp.type=__id;
|
|
main_stack.push(temp);
|
|
temp.type=__semi;
|
|
main_stack.push(temp);
|
|
|
|
temp.type=__stack_end;
|
|
comp_stack.push(temp);
|
|
temp.type=__program;
|
|
comp_stack.push(temp);
|
|
}
|
|
void stack_input(std::stack<parse_unit>& temp)
|
|
{
|
|
set_stack_empty();
|
|
while(!temp.empty())
|
|
{
|
|
main_stack.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
return;
|
|
}
|
|
void print_stack(std::stack<parse_unit>& temp)
|
|
{
|
|
std::stack<parse_unit> t;
|
|
while(!temp.empty())
|
|
{
|
|
t.push(temp.top());
|
|
print_token(t.top().type);
|
|
std::cout<<" ";
|
|
temp.pop();
|
|
}
|
|
while(!t.empty())
|
|
{
|
|
temp.push(t.top());
|
|
t.pop();
|
|
}
|
|
return;
|
|
}
|
|
void print_main_and_comp()
|
|
{
|
|
std::cout<<">>[Main stack] ";
|
|
print_stack(main_stack);
|
|
std::cout<<std::endl<<">>[Comp stack] ";
|
|
print_stack(comp_stack);
|
|
std::cout<<std::endl;
|
|
return;
|
|
}
|
|
bool reducable()
|
|
{
|
|
std::stack<parse_unit> temp;
|
|
for(int i=0;i<num_of_par;++i)
|
|
{
|
|
for(int j=max_len-1;j>=0;--j)
|
|
{
|
|
if(!par[i].tokens[j])
|
|
continue;
|
|
// if par[i].tokens[j] is 0 then continue until the tokens[j] is not 0
|
|
temp.push(comp_stack.top());
|
|
comp_stack.pop();
|
|
if((par[i].tokens[j]!=temp.top().type) || (comp_stack.empty() && par[i].tokens[j]))
|
|
{
|
|
while(!temp.empty())
|
|
{
|
|
comp_stack.push(temp.top());
|
|
temp.pop();
|
|
}
|
|
break;
|
|
}
|
|
if((par[i].tokens[j]==temp.top().type) && (j==0))
|
|
{
|
|
parse_unit t;
|
|
t.line=temp.top().line;
|
|
t.type=par[i].res;
|
|
comp_stack.push(t);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
void print_error()
|
|
{
|
|
int cnt_line=0;
|
|
while(!comp_stack.empty())
|
|
{
|
|
if((comp_stack.top().type!=__program) && (comp_stack.top().type!=__stack_end))
|
|
{
|
|
if(cnt_line!=comp_stack.top().line)
|
|
{
|
|
cnt_line=comp_stack.top().line;
|
|
std::cout<<std::endl<<"line "<<cnt_line<<" ";
|
|
}
|
|
print_token(comp_stack.top().type);
|
|
std::cout<<" ";
|
|
}
|
|
comp_stack.pop();
|
|
}
|
|
std::cout<<std::endl;
|
|
return;
|
|
}
|
|
void main_comp_progress(bool show) // show is used to print parser stack
|
|
{
|
|
if(show)
|
|
print_main_and_comp();
|
|
while(main_stack.top().type!=__stack_end)
|
|
{
|
|
comp_stack.push(main_stack.top());
|
|
main_stack.pop();
|
|
if((comp_stack.top().type==__left_curve) && ((main_stack.top().type==__id) || (main_stack.top().type==__if) || (main_stack.top().type==__elsif) || (main_stack.top().type==__while) || (main_stack.top().type==__func)))
|
|
{
|
|
comp_stack.push(main_stack.top());
|
|
main_stack.pop();
|
|
}
|
|
else if((comp_stack.top().type==__id) && (main_stack.top().type==__var))
|
|
{
|
|
comp_stack.push(main_stack.top());
|
|
main_stack.pop();
|
|
}
|
|
else if(((comp_stack.top().type==__sub_operator) || (comp_stack.top().type==__add_operator)) && (main_stack.top().type!=__id) && (main_stack.top().type!=__right_curve) && (main_stack.top().type!=__right_bracket))
|
|
{
|
|
parse_unit t;
|
|
t.line=comp_stack.top().line;
|
|
t.type=__number;
|
|
main_stack.push(t);
|
|
}
|
|
if((comp_stack.top().type==__if) && (main_stack.top().type==__else))
|
|
{
|
|
comp_stack.push(main_stack.top());
|
|
main_stack.pop();
|
|
}
|
|
if(show)
|
|
print_main_and_comp();
|
|
while(1)
|
|
{
|
|
if(!reducable())
|
|
break;
|
|
if(show)
|
|
print_main_and_comp();
|
|
}
|
|
}
|
|
if(comp_stack.top().type==__program)
|
|
{
|
|
comp_stack.pop();
|
|
if(comp_stack.top().type==__stack_end)
|
|
std::cout<<">>[Parse] 0 error(s)."<<std::endl;
|
|
else
|
|
{
|
|
std::cout<<">>[Parse] Error:";
|
|
print_error();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::cout<<">>[Parse] Error:";
|
|
print_error();
|
|
}
|
|
std::cout<<">>[Parse] Complete checking."<<std::endl;
|
|
return;
|
|
}
|
|
};
|
|
|
|
class nasal_parser
|
|
{
|
|
private:
|
|
std::stack<parse_unit> parser;
|
|
public:
|
|
void parse_process(std::list<token>& lexer,bool show)
|
|
{
|
|
while(!parser.empty())
|
|
parser.pop();
|
|
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=__number;
|
|
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)
|
|
{
|
|
temp_parse.type=__id;
|
|
}
|
|
else if((*i).type==DYNAMIC_ID)
|
|
{
|
|
temp_parse.type=__dynamic_id;
|
|
}
|
|
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))
|
|
{
|
|
if((*i).type==NUMBER)
|
|
temp_parse.type=__number;
|
|
else if((*i).type==STRING)
|
|
temp_parse.type=__string;
|
|
}
|
|
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
|
|
}
|
|
if(parser.empty())
|
|
{
|
|
std::cout<<">>[Warning] Empty lexer."<<std::endl;
|
|
std::cout<<">>[Parse] Complete checking."<<std::endl;
|
|
return;
|
|
}
|
|
std::stack<parse_unit> temp;
|
|
while(!parser.empty())
|
|
{
|
|
temp.push(parser.top());
|
|
parser.pop();
|
|
}
|
|
PDA automata;
|
|
automata.stack_input(temp);
|
|
automata.main_comp_progress(show);
|
|
return;
|
|
}
|
|
};
|
|
|
|
#endif
|