add func_call_parser

This commit is contained in:
xianjimli 2018-10-20 17:49:04 +08:00
parent fab3d865ed
commit 8911bc3dad
3 changed files with 225 additions and 0 deletions

View File

@ -0,0 +1,74 @@
/**
* File: func_call_parser.h
* Author: AWTK Develop Team
* Brief: func_call_parser
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is difunc_call_parseributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-10-20 Li XianJing <xianjimli@hotmail.com> adapt from uclib
*
*/
#include "base/utils.h"
#include "base/func_call_parser.h"
func_call_parser_t* func_call_parser_init(func_call_parser_t* parser, const char* str,
uint32_t size) {
return_value_if_fail(parser != NULL && str != NULL, NULL);
tokenizer_init(&(parser->tokenizer), str, size, "(=,) ");
return parser;
}
ret_t func_call_parser_parse(func_call_parser_t* parser) {
const char* token = NULL;
char name[NAME_LEN + 1];
tokenizer_t* tokenizer = NULL;
return_value_if_fail(parser != NULL, RET_BAD_PARAMS);
tokenizer = &(parser->tokenizer);
return_value_if_fail(tokenizer_has_more(tokenizer) == TRUE, RET_BAD_PARAMS);
token = tokenizer_next(tokenizer);
if (parser->on_name != NULL) {
parser->on_name(parser, token);
}
while (tokenizer_has_more(tokenizer)) {
token = tokenizer_next(tokenizer);
tk_strncpy(name, token, NAME_LEN);
ENSURE(tokenizer_has_more(tokenizer));
token = tokenizer_next(tokenizer);
if (parser->on_param != NULL) {
parser->on_param(parser, name, token);
}
}
if (parser->on_done != NULL) {
parser->on_done(parser);
}
return RET_OK;
}
ret_t func_call_parser_deinit(func_call_parser_t* parser) {
return_value_if_fail(parser != NULL, RET_BAD_PARAMS);
tokenizer_deinit(&(parser->tokenizer));
memset(parser, 0x00, sizeof(func_call_parser_t));
return RET_OK;
}

View File

@ -0,0 +1,91 @@
/**
* File: func_call_parser.h
* Author: AWTK Develop Team
* Brief: func_call_parser
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is difunc_call_parseributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-10-20 Li XianJing <xianjimli@hotmail.com> adapt from uclib
*
*/
#ifndef TK_FUNC_CALL_PARSER_H
#define TK_FUNC_CALL_PARSER_H
#include "base/tokenizer.h"
BEGIN_C_DECLS
struct _func_call_parser_t;
typedef struct _func_call_parser_t func_call_parser_t;
/*子类需要实现的虚函数*/
typedef ret_t (*func_call_parser_on_name_t)(func_call_parser_t* parser, const char* func_name);
typedef ret_t (*func_call_parser_on_param_t)(func_call_parser_t* parser, const char* name,
const char* value);
typedef ret_t (*func_call_parser_on_done_t)(func_call_parser_t* parser);
/**
* @class func_call_parser_t
*
* func_call => func_name '(' params ')'
* params => param ',' params
* param => name '=' value
* func_name => ID
* name = ID
* value = int | float | ID
*
* :move(x=10, y=20)
* :rename(old_name=aa, new_name=bb)
*/
struct _func_call_parser_t {
tokenizer_t tokenizer;
func_call_parser_on_name_t on_name;
func_call_parser_on_param_t on_param;
func_call_parser_on_done_t on_done;
};
/**
* @method func_call_parser_init
* parser对象
* @annotation ["constructor"]
* @param {func_call_parser_t*} parser parser对象
* @param {char*} str
* @param {uint32_t} size
*
* @return {func_call_parser_t*} parser对象本身
*/
func_call_parser_t* func_call_parser_init(func_call_parser_t* parser, const char* str,
uint32_t size);
/**
* @method func_call_parser_parse
*
* @param {func_call_parser_t*} parser parser对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t func_call_parser_parse(func_call_parser_t* parser);
/**
* @method func_call_parser_deinit
* parser
* @param {func_call_parser_t*} parser parser对象
*
* @return {ret_t} RET_OK表示成功
*/
ret_t func_call_parser_deinit(func_call_parser_t* parser);
END_C_DECLS
#endif /*TK_FUNC_CALL_PARSER_H*/

View File

@ -0,0 +1,60 @@
#include "base/utils.h"
#include "base/func_call_parser.h"
#include "gtest/gtest.h"
#include <math.h>
typedef struct _parser_t {
func_call_parser_t base;
char name[NAME_LEN + 1];
int x;
int y;
} parser_t;
static ret_t parser_on_name(func_call_parser_t* parser, const char* func_name) {
parser_t* p = (parser_t*)parser;
tk_strncpy(p->name, func_name, NAME_LEN);
return RET_OK;
}
static ret_t parser_on_param(func_call_parser_t* parser, const char* name, const char* value) {
parser_t* p = (parser_t*)parser;
if (tk_str_eq(name, "x")) {
p->x = tk_atoi(value);
} else if (tk_str_eq(name, "y")) {
p->y = tk_atoi(value);
}
return RET_OK;
}
static ret_t parser_on_done(func_call_parser_t* parser) {
return RET_OK;
}
static void parser_test(const char* str) {
parser_t parser;
memset(&parser, 0x00, sizeof(parser));
func_call_parser_init(&(parser.base), str, strlen(str));
parser.base.on_name = parser_on_name;
parser.base.on_param = parser_on_param;
parser.base.on_done = parser_on_done;
func_call_parser_parse(&(parser.base));
ASSERT_EQ(parser.x, 10);
ASSERT_EQ(parser.y, 20);
ASSERT_EQ(tk_str_eq(parser.name, "move"), true);
func_call_parser_deinit(&parser.base);
}
TEST(FuncCallParser, basic) {
parser_test("move(x=10, y=20)");
parser_test("move (x=10, y=20)");
parser_test("move(x = 10, y = 20 )");
parser_test(" move(x = 10, y = 20 )");
}