Fixed folding of single child asts with tags
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
Micro Parser Combinators
|
||||
========================
|
||||
|
||||
Version 0.8.7
|
||||
Version 0.8.8
|
||||
|
||||
|
||||
About
|
||||
|
20
mpc.c
20
mpc.c
@@ -2730,6 +2730,14 @@ mpc_ast_t *mpc_ast_add_tag(mpc_ast_t *a, const char *t) {
|
||||
return a;
|
||||
}
|
||||
|
||||
mpc_ast_t *mpc_ast_add_root_tag(mpc_ast_t *a, const char *t) {
|
||||
if (a == NULL) { return a; }
|
||||
a->tag = realloc(a->tag, (strlen(t)-1) + strlen(a->tag) + 1);
|
||||
memmove(a->tag + (strlen(t)-1), a->tag, strlen(a->tag)+1);
|
||||
memmove(a->tag, t, (strlen(t)-1));
|
||||
return a;
|
||||
}
|
||||
|
||||
mpc_ast_t *mpc_ast_tag(mpc_ast_t *a, const char *t) {
|
||||
a->tag = realloc(a->tag, strlen(t) + 1);
|
||||
strcpy(a->tag, t);
|
||||
@@ -2961,16 +2969,16 @@ mpc_val_t *mpcf_fold_ast(int n, mpc_val_t **xs) {
|
||||
|
||||
if (as[i] == NULL) { continue; }
|
||||
|
||||
if (as[i] && as[i]->children_num > 0) {
|
||||
|
||||
if (as[i] && as[i]->children_num == 0) {
|
||||
mpc_ast_add_child(r, as[i]);
|
||||
} else if (as[i] && as[i]->children_num == 1) {
|
||||
mpc_ast_add_child(r, mpc_ast_add_root_tag(as[i]->children[0], as[i]->tag));
|
||||
mpc_ast_delete_no_children(as[i]);
|
||||
} else if (as[i] && as[i]->children_num >= 2) {
|
||||
for (j = 0; j < as[i]->children_num; j++) {
|
||||
mpc_ast_add_child(r, as[i]->children[j]);
|
||||
}
|
||||
|
||||
mpc_ast_delete_no_children(as[i]);
|
||||
|
||||
} else if (as[i] && as[i]->children_num == 0) {
|
||||
mpc_ast_add_child(r, as[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
1
mpc.h
1
mpc.h
@@ -269,6 +269,7 @@ mpc_ast_t *mpc_ast_build(int n, const char *tag, ...);
|
||||
mpc_ast_t *mpc_ast_add_root(mpc_ast_t *a);
|
||||
mpc_ast_t *mpc_ast_add_child(mpc_ast_t *r, mpc_ast_t *a);
|
||||
mpc_ast_t *mpc_ast_add_tag(mpc_ast_t *a, const char *t);
|
||||
mpc_ast_t *mpc_ast_add_root_tag(mpc_ast_t *a, const char *t);
|
||||
mpc_ast_t *mpc_ast_tag(mpc_ast_t *a, const char *t);
|
||||
mpc_ast_t *mpc_ast_state(mpc_ast_t *a, mpc_state_t s);
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mpc",
|
||||
"version": "0.8.7",
|
||||
"version": "0.8.8",
|
||||
"repo": "orangeduck/mpc",
|
||||
"description": "A Parser Combinator library for C",
|
||||
"keywords": ["parser", "combinator", "library", "c", "mpc"],
|
||||
|
@@ -25,7 +25,7 @@ void test_grammar(void) {
|
||||
|
||||
t2 = mpc_ast_build(3, ">",
|
||||
|
||||
mpc_ast_build(3, "value|>",
|
||||
mpc_ast_build(3, "product|value|>",
|
||||
mpc_ast_new("char", "("),
|
||||
mpc_ast_build(3, "expression|>",
|
||||
|
||||
@@ -167,10 +167,98 @@ void test_partial(void) {
|
||||
|
||||
}
|
||||
|
||||
void test_qscript(void) {
|
||||
|
||||
mpc_ast_t *t0;
|
||||
mpc_parser_t *Qscript = mpc_new("qscript");
|
||||
mpc_parser_t *Comment = mpc_new("comment");
|
||||
mpc_parser_t *Resource = mpc_new("resource");
|
||||
mpc_parser_t *Rtype = mpc_new("rtype");
|
||||
mpc_parser_t *Rname = mpc_new("rname");
|
||||
mpc_parser_t *InnerBlock = mpc_new("inner_block");
|
||||
mpc_parser_t *Statement = mpc_new("statement");
|
||||
mpc_parser_t *Function = mpc_new("function");
|
||||
mpc_parser_t *Parameter = mpc_new("parameter");
|
||||
mpc_parser_t *Literal = mpc_new("literal");
|
||||
mpc_parser_t *Block = mpc_new("block");
|
||||
mpc_parser_t *Seperator = mpc_new("seperator");
|
||||
mpc_parser_t *Qstring = mpc_new("qstring");
|
||||
mpc_parser_t *SimpleStr = mpc_new("simplestr");
|
||||
mpc_parser_t *ComplexStr = mpc_new("complexstr");
|
||||
mpc_parser_t *Number = mpc_new("number");
|
||||
mpc_parser_t *Float = mpc_new("float");
|
||||
mpc_parser_t *Int = mpc_new("int");
|
||||
|
||||
mpc_err_t *err = mpca_lang(0,
|
||||
" qscript : /^/ (<comment> | <resource>)* /$/ ;\n"
|
||||
" comment : '#' /[^\\n]*/ ;\n"
|
||||
"resource : '[' (<rtype> <rname>) ']' <inner_block> ;\n"
|
||||
" rtype : /[*]*/ ;\n"
|
||||
" rname : <qstring> ;\n"
|
||||
"\n"
|
||||
"inner_block : (<comment> | <statement>)* ;\n"
|
||||
" statement : <function> '(' (<comment> | <parameter> | <block>)* ')' <seperator> ;\n"
|
||||
" function : <qstring> ;\n"
|
||||
" parameter : (<statement> | <literal>) ;\n"
|
||||
" literal : (<number> | <qstring>) <seperator> ;\n"
|
||||
" block : '{' <inner_block> '}' ;\n"
|
||||
" seperator : ',' | \"\" ;\n"
|
||||
"\n"
|
||||
"qstring : (<complexstr> | <simplestr>) <qstring>* ;\n"
|
||||
" simplestr : /[a-zA-Z0-9_!@#$%^&\\*_+\\-\\.=\\/<>]+/ ;\n"
|
||||
" complexstr : (/\"[^\"]*\"/ | /'[^']*'/) ;\n"
|
||||
"\n"
|
||||
"number : (<float> | <int>) ;\n"
|
||||
" float : /[-+]?[0-9]+\\.[0-9]+/ ;\n"
|
||||
" int : /[-+]?[0-9]+/ ;\n",
|
||||
Qscript, Comment, Resource, Rtype, Rname, InnerBlock, Statement, Function,
|
||||
Parameter, Literal, Block, Seperator, Qstring, SimpleStr, ComplexStr, Number,
|
||||
Float, Int, NULL);
|
||||
|
||||
PT_ASSERT(err == NULL);
|
||||
|
||||
t0 = mpc_ast_build(3, ">",
|
||||
mpc_ast_new("regex", ""),
|
||||
mpc_ast_build(5, "resource|>",
|
||||
mpc_ast_new("char", "["),
|
||||
mpc_ast_new("rtype|regex", ""),
|
||||
mpc_ast_new("rname|qstring|simplestr|regex", "my_func"),
|
||||
mpc_ast_new("char", "]"),
|
||||
mpc_ast_build(5, "inner_block|statement|>",
|
||||
mpc_ast_new("function|qstring|simplestr|regex", "echo"),
|
||||
mpc_ast_new("char", "("),
|
||||
mpc_ast_build(2, "parameter|literal|>",
|
||||
mpc_ast_build(2, "qstring|>",
|
||||
mpc_ast_new("simplestr|regex", "a"),
|
||||
mpc_ast_build(2, "qstring|>",
|
||||
mpc_ast_new("simplestr|regex", "b"),
|
||||
mpc_ast_new("qstring|simplestr|regex", "c")
|
||||
)
|
||||
),
|
||||
mpc_ast_new("seperator|string", "")
|
||||
),
|
||||
mpc_ast_new("char", ")"),
|
||||
mpc_ast_new("seperator|string", "")
|
||||
)
|
||||
),
|
||||
mpc_ast_new("regex", ""));
|
||||
|
||||
PT_ASSERT(mpc_test_pass(Qscript, "[my_func]\n echo (a b c)\n", t0,
|
||||
(int(*)(const void*,const void*))mpc_ast_eq,
|
||||
(mpc_dtor_t)mpc_ast_delete,
|
||||
(void(*)(const void*))mpc_ast_print));
|
||||
|
||||
mpc_cleanup(18, Qscript, Comment, Resource, Rtype, Rname, InnerBlock,
|
||||
Statement, Function, Parameter, Literal, Block, Seperator, Qstring,
|
||||
SimpleStr, ComplexStr, Number, Float, Int);
|
||||
|
||||
}
|
||||
|
||||
void suite_grammar(void) {
|
||||
pt_add_test(test_grammar, "Test Grammar", "Suite Grammar");
|
||||
pt_add_test(test_language, "Test Language", "Suite Grammar");
|
||||
pt_add_test(test_language_file, "Test Language File", "Suite Grammar");
|
||||
pt_add_test(test_doge, "Test Doge", "Suite Grammar");
|
||||
pt_add_test(test_partial, "Test Partial", "Suite Grammar");
|
||||
pt_add_test(test_qscript, "Test QScript", "Suite Grammar");
|
||||
}
|
||||
|
Reference in New Issue
Block a user