|
@@ -238,7 +238,7 @@ void parserIf(PASERSSIGNATURE){
|
|
|
break;
|
|
|
default:{
|
|
|
default_:
|
|
|
- addEnter(pm);
|
|
|
+ addLexToken(pm, MATHER_ENTER);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -317,7 +317,7 @@ void parserWhile(PASERSSIGNATURE){
|
|
|
break;
|
|
|
default: {
|
|
|
default_:
|
|
|
- addEnter(pm);
|
|
|
+ addLexToken(pm, MATHER_ENTER);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -390,7 +390,7 @@ void parserTry(PASERSSIGNATURE){
|
|
|
break;
|
|
|
default: {
|
|
|
default_:
|
|
|
- addEnter(pm);
|
|
|
+ addLexToken(pm, MATHER_ENTER);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -411,28 +411,51 @@ void parserTry(PASERSSIGNATURE){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-bool parserParameter(PASERSSIGNATURE, Parameter **pt){
|
|
|
+/**
|
|
|
+ * @param pm
|
|
|
+ * @param inter
|
|
|
+ * @param pt
|
|
|
+ * @param is_formal 是否为形式参数, 若为true,则限定*args为only_value的结尾, **kwargs为name_value结尾
|
|
|
+ * @param is_list 若为true则关闭对name_value和**kwargs的支持
|
|
|
+ * @param is_dict 若为true则关闭对only_value和*args的支持
|
|
|
+ * @param sep 设定分割符号
|
|
|
+ * @param ass 设定赋值符号
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+bool parserParameter(ParserMessage *pm, Inter *inter, Parameter **pt, bool is_formal, bool is_list, bool is_dict, int sep,
|
|
|
+ int ass) {
|
|
|
Parameter *new_pt = NULL;
|
|
|
Token *tmp;
|
|
|
enum {
|
|
|
s_1, // only_value模式
|
|
|
s_2, // name_value模式
|
|
|
- } status = s_1;
|
|
|
+ s_3, // only_args模式
|
|
|
+ } status;
|
|
|
+ if (is_dict)
|
|
|
+ status = s_2; // is_formal关闭对only_value的支持
|
|
|
+ else
|
|
|
+ status = s_1;
|
|
|
bool last_pt = false;
|
|
|
while (!last_pt){
|
|
|
tmp = NULL;
|
|
|
+ if (!is_dict && status != s_2 && checkToken_(pm, MATHER_MUL)) // // is_formal关闭对*args的支持
|
|
|
+ status = s_3;
|
|
|
parserPolynomial(CALLPASERSSIGNATURE);
|
|
|
if (!call_success(pm))
|
|
|
goto error_;
|
|
|
- if (readBackToken(pm) != POLYNOMIAL)
|
|
|
+ if (readBackToken(pm) != POLYNOMIAL) {
|
|
|
+ if (status == s_3) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get a parameter after *");
|
|
|
+ goto error_;
|
|
|
+ }
|
|
|
break;
|
|
|
+ }
|
|
|
tmp = popAheadToken(pm);
|
|
|
|
|
|
- int pt_type;
|
|
|
+ int pt_type = only_value;
|
|
|
if (status == s_1){
|
|
|
- pt_type = only_value;
|
|
|
- if (!checkToken_(pm, MATHER_COMMA)){
|
|
|
- if (!checkToken_(pm, MATHER_ASSIGNMENT))
|
|
|
+ if (!checkToken_(pm, sep)){
|
|
|
+ if (is_list || !checkToken_(pm, is_formal)) // // is_list关闭对name_value的支持
|
|
|
last_pt = true;
|
|
|
else {
|
|
|
pt_type = name_value;
|
|
@@ -440,22 +463,34 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt){
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- else{
|
|
|
+ else if (status == s_2){
|
|
|
pt_type = name_value;
|
|
|
- if (!checkToken_(pm, MATHER_ASSIGNMENT))
|
|
|
+ if (!checkToken_(pm, is_formal))
|
|
|
goto error_;
|
|
|
}
|
|
|
+ else if (status == s_3){
|
|
|
+ pt_type = only_args;
|
|
|
+ if (!checkToken_(pm, sep))
|
|
|
+ last_pt = true;
|
|
|
+ }
|
|
|
|
|
|
if (pt_type == only_value)
|
|
|
new_pt = connectOnlyValueParameter(tmp->data.st, new_pt);
|
|
|
else if (pt_type == name_value){
|
|
|
Statement *tmp_value;
|
|
|
- if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &tmp_value, "Don't get a parameter value"))
|
|
|
+ if (!callChildStatement(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp_value, "Don't get a parameter value"))
|
|
|
goto error_;
|
|
|
new_pt = connectNameValueParameter(tmp_value, tmp->data.st, new_pt);
|
|
|
- if (!checkToken_(pm, MATHER_COMMA))
|
|
|
+ if (!checkToken_(pm, sep))
|
|
|
last_pt = true;
|
|
|
}
|
|
|
+ else if (pt_type == only_args){
|
|
|
+ new_pt = connectOnlyArgsParameter(tmp->data.st, new_pt);
|
|
|
+ if (is_formal)
|
|
|
+ status = s_2; // 是否规定*args只出现一次
|
|
|
+ else
|
|
|
+ status = s_1;
|
|
|
+ }
|
|
|
freeToken(tmp, true, false);
|
|
|
}
|
|
|
*pt = new_pt;
|
|
@@ -476,27 +511,34 @@ void parserDef(PASERSSIGNATURE){
|
|
|
if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &name_tmp, "Don't get a function name"))
|
|
|
goto error_;
|
|
|
|
|
|
- if (!checkToken_(pm, MATHER_LP))
|
|
|
+ if (!checkToken_(pm, MATHER_LP)) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get a function ( before parameter");
|
|
|
goto error_;
|
|
|
- if (!parserParameter(CALLPASERSSIGNATURE, &pt))
|
|
|
+ }
|
|
|
+ if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get a function parameter");
|
|
|
goto error_;
|
|
|
- if (!checkToken_(pm, MATHER_RP))
|
|
|
+ }
|
|
|
+ if (!checkToken_(pm, MATHER_RP)) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get a function ) after parameter");
|
|
|
goto error_;
|
|
|
+ }
|
|
|
writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: get function title success\n", NULL);
|
|
|
writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserDef: call parserCode\n", NULL);
|
|
|
|
|
|
- if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code"))
|
|
|
+ if (!callParserCode(CALLPASERSSIGNATURE, &code_tmp, "Don't get a function code")) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get a function code");
|
|
|
goto error_;
|
|
|
+ }
|
|
|
|
|
|
st = makeFunctionStatement(name_tmp, code_tmp, pt);
|
|
|
- addEnter(pm);
|
|
|
+ addLexToken(pm, MATHER_ENTER);
|
|
|
addStatementToken(FUNCTION, st, pm);
|
|
|
return;
|
|
|
|
|
|
error_:
|
|
|
freeStatement(name_tmp);
|
|
|
freeStatement(code_tmp);
|
|
|
- syntaxError(pm, syntax_error, 1, "Don't get a function code");
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -572,10 +614,42 @@ bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
|
|
|
return true;
|
|
|
}
|
|
|
void parserAssignment(PASERSSIGNATURE){
|
|
|
- return twoOperation(CALLPASERSSIGNATURE, parserPolynomial, switchAssignment, POLYNOMIAL, ASSIGNMENT,
|
|
|
+ return twoOperation(CALLPASERSSIGNATURE, parserTuple, switchAssignment, TUPLE, ASSIGNMENT,
|
|
|
"polynomial", "assignment");
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 元组匹配
|
|
|
+ * parserTuple
|
|
|
+ * | switchPolynomial
|
|
|
+ * | parserTuple COMMA switchPolynomial
|
|
|
+ * @param pm
|
|
|
+ * @param inter
|
|
|
+ */
|
|
|
+void parserTuple(PASERSSIGNATURE){
|
|
|
+ struct Parameter *pt = NULL;
|
|
|
+ struct Statement *st = NULL;
|
|
|
+ Token *tmp = NULL;
|
|
|
+ if (!callChildToken(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp, NULL, syntax_error))
|
|
|
+ goto return_;
|
|
|
+ if (!checkToken_(pm, MATHER_COMMA)){ // TODO-szh 需要弹出token才可以检查
|
|
|
+ tmp->token_type = TUPLE;
|
|
|
+ addToken_(pm ,tmp);
|
|
|
+ goto return_;
|
|
|
+ }
|
|
|
+ addLexToken(pm, MATHER_COMMA);
|
|
|
+ addToken_(pm ,tmp);
|
|
|
+ if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, true, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
|
|
|
+ syntaxError(pm, syntax_error, 1, "Don't get tuple element");
|
|
|
+ goto return_;
|
|
|
+ }
|
|
|
+ st = makeTupleStatement(pt, tuple_);
|
|
|
+ addStatementToken(TUPLE, st, pm);
|
|
|
+
|
|
|
+ return_:
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 多项式匹配
|
|
|
* parserPolynomial:
|
|
@@ -631,7 +705,7 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
|
|
|
if (readBackToken(pm) != MATHER_LP)
|
|
|
return -1;
|
|
|
delToken(pm);
|
|
|
- if (!parserParameter(CALLPASERSSIGNATURE, &pt)) {
|
|
|
+ if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
|
|
|
syntaxError(pm, syntax_error, 1, "Don't get call parameter");
|
|
|
return 0;
|
|
|
}
|
|
@@ -746,212 +820,3 @@ void parserBaseValue(PASERSSIGNATURE){
|
|
|
return_:
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
-inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int type, int self_type, char *call_name, char *self_name){
|
|
|
- while(true){
|
|
|
- Token *left_token = NULL, *right_token = NULL;
|
|
|
- struct Statement *st = NULL;
|
|
|
-
|
|
|
- readBackToken(pm);
|
|
|
- if (readBackToken(pm) != self_type){
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
|
|
|
- if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
|
|
|
- goto return_;
|
|
|
- addStatementToken(self_type, st, pm);
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
|
|
|
- "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
|
|
|
- continue;
|
|
|
- }
|
|
|
- left_token= popAheadToken(pm);
|
|
|
-
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
|
|
|
- if (getSymbol(CALLPASERSSIGNATURE, readBackToken(pm), &st)){
|
|
|
- delToken(pm);
|
|
|
- }
|
|
|
- else{
|
|
|
- backToken_(pm, left_token);
|
|
|
- goto return_;
|
|
|
- }
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
|
|
|
- "%s: get symbol success\n%s: call %s[right]\n", self_name, self_name, call_name);
|
|
|
-
|
|
|
- callBack(CALLPASERSSIGNATURE); // 获得右值
|
|
|
- if (!call_success(pm)){
|
|
|
- freeToken(left_token, true, false);
|
|
|
- freeStatement(st);
|
|
|
- goto return_;
|
|
|
- }
|
|
|
- if (readBackToken(pm) != type){ // 若非正确数值
|
|
|
- syntaxError(pm, syntax_error, 3, "ERROR from ", self_name, "(get right)");
|
|
|
- freeToken(left_token, true, true);
|
|
|
- freeStatement(st);
|
|
|
- goto return_;
|
|
|
- }
|
|
|
-
|
|
|
- right_token= popAheadToken(pm);
|
|
|
- addToken_(pm, setOperationFromToken(st, left_token, right_token, self_type));
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
|
|
|
- }
|
|
|
- return_:
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-inline void tailOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*tailFunction)(PASERSSIGNATURE, Token *left_token, Statement **st), int type, int self_type, char *call_name, char *self_name){
|
|
|
- while(true){
|
|
|
- Token *left_token = NULL;
|
|
|
- struct Statement *st = NULL;
|
|
|
-
|
|
|
- if (readBackToken(pm) != self_type){
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
|
|
|
- if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
|
|
|
- goto return_;
|
|
|
- addStatementToken(self_type, st, pm);
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
|
|
|
- "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
|
|
|
- continue;
|
|
|
- }
|
|
|
- left_token= popAheadToken(pm);
|
|
|
-
|
|
|
- int tail_status = tailFunction(CALLPASERSSIGNATURE, left_token, &st);
|
|
|
- if (tail_status == -1){
|
|
|
- backToken_(pm, left_token);
|
|
|
- goto return_;
|
|
|
- }
|
|
|
- else if(!tail_status){
|
|
|
- goto error_;
|
|
|
- }
|
|
|
- addStatementToken(self_type, st, pm);
|
|
|
- freeToken(left_token, true, false);
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call tail success\n", self_name);
|
|
|
- continue;
|
|
|
-
|
|
|
- error_:
|
|
|
- freeToken(left_token, true, true);
|
|
|
- goto return_;
|
|
|
- }
|
|
|
- return_:
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * syntax错误处理器
|
|
|
- * @param pm
|
|
|
- * @param message 错误信息
|
|
|
- * @param status 错误类型
|
|
|
- */
|
|
|
-void syntaxError(ParserMessage *pm, int status, int num, ...) {
|
|
|
- if (pm->status != success)
|
|
|
- return;
|
|
|
-
|
|
|
- char *message = NULL;
|
|
|
- va_list message_args;
|
|
|
- if (status <= 0){
|
|
|
- message = "Not message";
|
|
|
- goto not_message;
|
|
|
- }
|
|
|
- va_start(message_args, num);
|
|
|
- for (int i=0; i < num; i++) {
|
|
|
- char *new_message;
|
|
|
- new_message = memStrcat(message, va_arg(message_args, char *));
|
|
|
- memFree(message);
|
|
|
- message = new_message;
|
|
|
- }
|
|
|
- va_end(message_args);
|
|
|
-
|
|
|
- not_message:
|
|
|
- pm->status = status;
|
|
|
- pm->status_message = message;
|
|
|
-}
|
|
|
-
|
|
|
-int readBackToken(ParserMessage *pm){
|
|
|
- writeLog(pm->grammar_debug, GRAMMAR_DEBUG, "token operation number : %d\n", pm->count);
|
|
|
- writeLog(pm->paser_debug, DEBUG, "\ntoken operation number : %d\n", pm->count);
|
|
|
- pm->count ++;
|
|
|
- Token *tmp = popNewToken(pm->tm, pm->paser_debug);
|
|
|
- if (tmp->token_type == -2){
|
|
|
- freeToken(tmp, true, false);
|
|
|
- syntaxError(pm, lexical_error, 1, "lexical make some error");
|
|
|
- }
|
|
|
- addBackToken(pm->tm->ts, tmp, pm->paser_debug);
|
|
|
- return tmp->token_type;
|
|
|
-}
|
|
|
-
|
|
|
-Token *popAheadToken(ParserMessage *pm){
|
|
|
- doubleLog(pm, GRAMMAR_DEBUG, DEBUG, "token operation number : %d\n", pm->count ++);
|
|
|
- return popNewToken(pm->tm, pm->paser_debug);
|
|
|
-}
|
|
|
-
|
|
|
-bool checkToken_(ParserMessage *pm, int type){
|
|
|
- if (readBackToken(pm) != type){
|
|
|
- return false;
|
|
|
- }
|
|
|
- delToken(pm);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool commandCallControl_(PASERSSIGNATURE, Statement *(*callBack)(Statement *), int type, Statement **st, char *message){
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "message", NULL);
|
|
|
- Token *tmp_token = NULL;
|
|
|
- parserControl(CALLPASERSSIGNATURE, callBack, type);
|
|
|
- if (!call_success(pm) || readBackToken(pm) != type)
|
|
|
- return false;
|
|
|
- tmp_token = popAheadToken(pm);
|
|
|
- *st = tmp_token->data.st;
|
|
|
- freeToken(tmp_token, true, false);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-inline bool commandCallBack_(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int type, Statement **st, char *message){
|
|
|
- writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, message, NULL);
|
|
|
- return callChildStatement(CALLPASERSSIGNATURE, callBack, type, st, NULL);
|
|
|
-}
|
|
|
-
|
|
|
-bool callParserCode(PASERSSIGNATURE, Statement **st,char *message){
|
|
|
- Statement *new_st = NULL;
|
|
|
- if(!callChildStatement(CALLPASERSSIGNATURE, parserCode, CODE, &new_st, message)){
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (*st != NULL)
|
|
|
- freeStatement(*st);
|
|
|
- *st = new_st;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool callParserAs(PASERSSIGNATURE, Statement **st,char *message){
|
|
|
- if (readBackToken(pm) == MATHER_AS) {
|
|
|
- delToken(pm);
|
|
|
- return callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, message);
|
|
|
- }
|
|
|
- else
|
|
|
- *st = NULL;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool callChildToken(ParserMessage *pm, Inter *inter, void (*call)(ParserMessage *, Inter *), int type, Token **tmp,
|
|
|
- char *message, int error_type) {
|
|
|
- call(CALLPASERSSIGNATURE);
|
|
|
- if (!call_success(pm)) {
|
|
|
- *tmp = NULL;
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (readBackToken(pm) != type) {
|
|
|
- *tmp = NULL;
|
|
|
- if (message != NULL)
|
|
|
- syntaxError(pm, error_type, 1, message);
|
|
|
- return false;
|
|
|
- }
|
|
|
- *tmp = popAheadToken(pm);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool callChildStatement(PASERSSIGNATURE, void (*call)(PASERSSIGNATURE), int type, Statement **st, char *message){
|
|
|
- Token *tmp = NULL;
|
|
|
- bool status = callChildToken(CALLPASERSSIGNATURE, call, type, &tmp, message, syntax_error);
|
|
|
- if (!status){
|
|
|
- *st = NULL;
|
|
|
- return false;
|
|
|
- }
|
|
|
- *st = tmp->data.st;
|
|
|
- freeToken(tmp, true, false);
|
|
|
- return true;
|
|
|
-}
|