Rework tree generation mode and API

Store tree nodes in congruent, compact arena array.
Define handle types to refer to tree nodes rather than pointers to
structure instances.
Free tree with context.
This commit is contained in:
josh committed 2026-07-27 20:57:44 -04:00
1 parent dddb1b5089
commit 5fc712c6ee
39 files changed
+1349 -811

No files matched your search

+43 -12
View File
@@ -751,7 +751,7 @@ EOF
it "executes user code associated with a parser rule in tree mode" do
case language
when "c", "cpp"
when "c"
write_grammar <<EOF
tree;
context_user_fields <<
@@ -769,18 +769,49 @@ ptype int;
token a << $$ = 11; >>
token b << $$ = 22; >>
Start -> A:ay B:bee C <<
${context.start_n_fields} = $$->n_fields;
${context.start_a_value} = $$->pA->pToken1->pvalue;
${context.a_value} = $1->pToken1->pvalue;
${context.b_value} = $2->pToken1->pvalue;
${context.b_token} = $2->pToken1->token;
${context.c_field_is_null} = ($$->pC == NULL) ? 1 : 0;
${context.alias_a_value} = ${ay}->pToken1->pvalue;
${context.alias_b_value} = ${bee}->pToken1->pvalue;
${context.start_n_fields} = p_node_n_fields($$);
${context.start_a_value} = p_tree_walk_Start($$, pA, pToken1, pvalue);
${context.a_value} = p_tree_walk_A($1, pToken1, pvalue);
${context.b_value} = p_tree_walk_B($2, pToken1, pvalue);
${context.b_token} = p_tree_walk_B($2, pToken1, token);
${context.c_field_is_null} = p_node_valid(p_Start_pC($$)) ? 0 : 1;
${context.alias_a_value} = p_tree_walk_A(${ay}, pToken1, pvalue);
${context.alias_b_value} = p_tree_walk_B(${bee}, pToken1, pvalue);
>>
A -> a;
B -> b;
C -> << ${context.c_is_null} = ($$ == NULL) ? 1 : 0; >>
C -> << ${context.c_is_null} = p_node_valid($$) ? 0 : 1; >>
EOF
when "cpp"
write_grammar <<EOF
tree;
context_user_fields <<
int start_n_fields;
int start_a_value;
int a_value;
int b_value;
p_token_t b_token;
int c_is_null;
int c_field_is_null;
int alias_a_value;
int alias_b_value;
>>
ptype int;
token a << $$ = 11; >>
token b << $$ = 22; >>
Start -> A:ay B:bee C <<
${context.start_n_fields} = $$.n_fields();
${context.start_a_value} = $$.pA().pToken1().pvalue();
${context.a_value} = $1.pToken1().pvalue();
${context.b_value} = $2.pToken1().pvalue();
${context.b_token} = $2.pToken1().token();
${context.c_field_is_null} = $$.pC().valid() ? 0 : 1;
${context.alias_a_value} = ${ay}.pToken1().pvalue();
${context.alias_b_value} = ${bee}.pToken1().pvalue();
>>
A -> a;
B -> b;
C -> << ${context.c_is_null} = $$.valid() ? 0 : 1; >>
EOF
when "d"
write_grammar <<EOF
@@ -805,13 +836,13 @@ Start -> A:ay B:bee C <<
${context.a_value} = $1.pToken1.pvalue;
${context.b_value} = $2.pToken1.pvalue;
${context.b_token} = $2.pToken1.token;
${context.c_field_is_null} = ($$.pC is null) ? 1 : 0;
${context.c_field_is_null} = ($$.pC.valid) ? 0 : 1;
${context.alias_a_value} = ${ay}.pToken1.pvalue;
${context.alias_b_value} = ${bee}.pToken1.pvalue;
>>
A -> a;
B -> b;
C -> << ${context.c_is_null} = ($$ is null) ? 1 : 0; >>
C -> << ${context.c_is_null} = ($$.valid) ? 0 : 1; >>
EOF
end
run_propane(language: language)
+20 -24
View File
@@ -9,46 +9,42 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start->a == NULL);
assert(start->pToken2 != NULL);
assert_eq(TOKEN_b, start->pToken2->token);
assert(start->pR3 == NULL);
assert(start->pR == NULL);
assert(start->r == NULL);
Start start = p_result(context);
assert(!p_node_valid(p_Start_a(start)));
assert(p_node_valid(p_Start_pToken2(start)));
assert_eq(TOKEN_b, p_tree_walk_Start(start, pToken2, token));
assert(!p_node_valid(p_Start_pR3(start)));
assert(!p_node_valid(p_Start_pR(start)));
assert(!p_node_valid(p_Start_r(start)));
p_tree_delete(start);
p_context_delete(context);
input = "abcd";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start->a != NULL);
assert_eq(TOKEN_a, start->pToken1->token);
assert(start->pToken2 != NULL);
assert(start->pR3 != NULL);
assert(start->pR != NULL);
assert(start->r != NULL);
assert(start->pR == start->pR3);
assert(start->pR == start->r);
assert_eq(TOKEN_c, start->pR->pToken1->token);
assert(p_node_valid(p_Start_a(start)));
assert_eq(TOKEN_a, p_tree_walk_Start(start, pToken1, token));
assert(p_node_valid(p_Start_pToken2(start)));
assert(p_node_valid(p_Start_pR3(start)));
assert(p_node_valid(p_Start_pR(start)));
assert(p_node_valid(p_Start_r(start)));
assert(p_node_id(p_Start_pR(start)) == p_node_id(p_Start_pR3(start)));
assert(p_node_id(p_Start_pR(start)) == p_node_id(p_Start_r(start)));
assert_eq(TOKEN_c, p_tree_walk_Start(start, pR, pToken1, token));
p_tree_delete(start);
p_context_delete(context);
input = "bdc";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start->a == NULL);
assert(start->pToken2 != NULL);
assert(start->r != NULL);
assert_eq(TOKEN_d, start->pR->pToken1->token);
assert(!p_node_valid(p_Start_a(start)));
assert(p_node_valid(p_Start_pToken2(start)));
assert(p_node_valid(p_Start_r(start)));
assert_eq(TOKEN_d, p_tree_walk_Start(start, pR, pToken1, token));
p_tree_delete(start);
p_context_delete(context);
return 0;
}
+17 -17
View File
@@ -12,40 +12,40 @@ unittest
string input = "b";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
Start start = p_result(context);
assert(!start.pToken1.valid);
assert(start.pToken2.valid);
assert_eq(TOKEN_b, start.pToken2.token);
assert(start.pR3 is null);
assert(start.pR is null);
assert(start.r is null);
assert(!start.pR3.valid);
assert(!start.pR.valid);
assert(!start.r.valid);
p_tree_delete(start);
p_context_delete(context);
input = "abcd";
context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start.pToken1 != null);
assert(start.pToken1.valid);
assert_eq(TOKEN_a, start.pToken1.token);
assert(start.pToken2 != null);
assert(start.pR3 != null);
assert(start.pR != null);
assert(start.r != null);
assert(start.pToken2.valid);
assert(start.pR3.valid);
assert(start.pR.valid);
assert(start.r.valid);
assert(start.pR == start.pR3);
assert(start.pR == start.r);
assert_eq(TOKEN_c, start.pR.pToken1.token);
p_tree_delete(start);
p_context_delete(context);
input = "bdc";
context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
assert(start.pR !is null);
assert(!start.pToken1.valid);
assert(start.pToken2.valid);
assert(start.pR.valid);
assert_eq(TOKEN_d, start.pR.pToken1.token);
p_tree_delete(start);
p_context_delete(context);
}
+17 -21
View File
@@ -9,43 +9,39 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start->pToken1 == NULL);
assert(start->pToken2 != NULL);
assert_eq(TOKEN_b, start->pToken2->token);
assert(start->pR3 == NULL);
assert(start->pR == NULL);
Start start = p_result(context);
assert(!p_node_valid(p_Start_pToken1(start)));
assert(p_node_valid(p_Start_pToken2(start)));
assert_eq(TOKEN_b, p_tree_walk_Start(start, pToken2, token));
assert(!p_node_valid(p_Start_pR3(start)));
assert(!p_node_valid(p_Start_pR(start)));
p_tree_delete(start);
p_context_delete(context);
input = "abcd";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start->pToken1 != NULL);
assert_eq(TOKEN_a, start->pToken1->token);
assert(start->pToken2 != NULL);
assert(start->pR3 != NULL);
assert(start->pR != NULL);
assert(start->pR == start->pR3);
assert_eq(TOKEN_c, start->pR->pToken1->token);
assert(p_node_valid(p_Start_pToken1(start)));
assert_eq(TOKEN_a, p_tree_walk_Start(start, pToken1, token));
assert(p_node_valid(p_Start_pToken2(start)));
assert(p_node_valid(p_Start_pR3(start)));
assert(p_node_valid(p_Start_pR(start)));
assert(p_node_id(p_Start_pR(start)) == p_node_id(p_Start_pR3(start)));
assert_eq(TOKEN_c, p_tree_walk_Start(start, pR, pToken1, token));
p_tree_delete(start);
p_context_delete(context);
input = "bdc";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start->pToken1 == NULL);
assert(start->pToken2 != NULL);
assert(start->pR != NULL);
assert_eq(TOKEN_d, start->pR->pToken1->token);
assert(!p_node_valid(p_Start_pToken1(start)));
assert(p_node_valid(p_Start_pToken2(start)));
assert(p_node_valid(p_Start_pR(start)));
assert_eq(TOKEN_d, p_tree_walk_Start(start, pR, pToken1, token));
p_tree_delete(start);
p_context_delete(context);
return 0;
}
+15 -15
View File
@@ -12,37 +12,37 @@ unittest
string input = "b";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
Start start = p_result(context);
assert(!start.pToken1.valid);
assert(start.pToken2.valid);
assert_eq(TOKEN_b, start.pToken2.token);
assert(start.pR3 is null);
assert(start.pR is null);
assert(!start.pR3.valid);
assert(!start.pR.valid);
p_tree_delete(start);
p_context_delete(context);
input = "abcd";
context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start.pToken1 != null);
assert(start.pToken1.valid);
assert_eq(TOKEN_a, start.pToken1.token);
assert(start.pToken2 != null);
assert(start.pR3 != null);
assert(start.pR != null);
assert(start.pToken2.valid);
assert(start.pR3.valid);
assert(start.pR.valid);
assert(start.pR == start.pR3);
assert_eq(TOKEN_c, start.pR.pToken1.token);
p_tree_delete(start);
p_context_delete(context);
input = "bdc";
context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
assert(start.pR !is null);
assert(!start.pToken1.valid);
assert(start.pToken2.valid);
assert(start.pR.valid);
assert_eq(TOKEN_d, start.pR.pToken1.token);
p_tree_delete(start);
p_context_delete(context);
}
+30 -43
View File
@@ -3,21 +3,8 @@
#include <string.h>
#include "testutils.h"
/* Grammar (tree generation mode; parentheses handled by the lex function):
* tree;
* lex_fn mylexfn;
* token lparen /\(/; token rparen /\)/; token plus /\+/; token num /\d+/;
* Start -> Expr;
* Expr -> num;
* Expr -> Expr plus num;
*
* The same lexer-driven nested parse as test_parse_inner_nested, but in tree
* generation mode. Each "( ... )" group is parsed by a reentrant
* p_parse_inner_Start() call from the lex function; the resulting subtree is
* discarded and a single synthesized num token is handed to the outer parse.
* The synthesized token's position is set to span the whole group ('(' start
* through ')' end), so this verifies that positions survive the nested-parse
* boundary and land correctly in the outer tree. */
/* Grammar: see the D variant / spec. Tree generation mode; parentheses handled
* by the lex function. Tree nodes live in the context arena. */
size_t mylexfn(p_context_t * context, p_token_info_t * out_token_info)
{
@@ -36,8 +23,8 @@ size_t mylexfn(p_context_t * context, p_token_info_t * out_token_info)
{
return inner_result;
}
Start * inner = p_result_Start(context);
assert_not_null(inner);
Start inner = p_result_Start(context);
assert(p_node_valid(inner));
/* p_parse_inner rewound the input so that ')' was not consumed; consume
* it now. */
p_token_info_t rparen_info;
@@ -45,10 +32,11 @@ size_t mylexfn(p_context_t * context, p_token_info_t * out_token_info)
assert(rparen_result == P_SUCCESS);
assert(rparen_info.token == TOKEN_rparen);
/* The subtree covers the region strictly between the parentheses. */
assert_eq((size_t)(start_position.col + 1u), (size_t)inner->position.col);
assert_eq((size_t)(rparen_info.position.col - 1u), (size_t)inner->end_position.col);
p_tree_delete_Start(inner);
/* Synthesize a num token spanning the entire "( ... )" group. */
assert_eq((size_t)(start_position.col + 1u), (size_t)p_node_position(inner).col);
assert_eq((size_t)(rparen_info.position.col - 1u), (size_t)p_node_end_position(inner).col);
/* The inner subtree is discarded (the lexer synthesizes a num token in
* its place), but its nodes remain in the shared context arena and are
* freed with the context. */
out_token_info->token = TOKEN_num;
out_token_info->position = start_position;
out_token_info->end_position = rparen_info.end_position;
@@ -64,40 +52,39 @@ int main()
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * tree = p_result(context);
assert_not_null(tree);
Start tree = p_result(context);
assert(p_node_valid(tree));
/* Start -> Expr, where the top Expr is "Expr plus num". */
Expr * top = tree->pExpr;
assert_not_null(top);
assert_not_null(top->pExpr);
assert_not_null(top->pToken2);
assert_not_null(top->pToken3);
Expr top = p_Start_pExpr(tree);
assert(p_node_valid(top));
assert(p_node_valid(p_Expr_pExpr(top)));
assert(p_node_valid(p_Expr_pToken2(top)));
assert(p_node_valid(p_Expr_pToken3(top)));
/* The '+' joining the two groups is at column 9. */
assert_eq(1u, (size_t)top->pToken2->position.row);
assert_eq(9u, (size_t)top->pToken2->position.col);
assert_eq(1u, (size_t)p_node_position(p_Expr_pToken2(top)).row);
assert_eq(9u, (size_t)p_node_position(p_Expr_pToken2(top)).col);
/* Right operand: synthesized num for "(5 + 6)", spanning columns 11..17. */
assert_eq(1u, (size_t)top->pToken3->position.row);
assert_eq(11u, (size_t)top->pToken3->position.col);
assert_eq(1u, (size_t)top->pToken3->end_position.row);
assert_eq(17u, (size_t)top->pToken3->end_position.col);
assert_eq(1u, (size_t)p_node_position(p_Expr_pToken3(top)).row);
assert_eq(11u, (size_t)p_node_position(p_Expr_pToken3(top)).col);
assert_eq(1u, (size_t)p_node_end_position(p_Expr_pToken3(top)).row);
assert_eq(17u, (size_t)p_node_end_position(p_Expr_pToken3(top)).col);
/* Left operand: Expr -> num, the synthesized num for "(3 + 4)", spanning
* columns 1..7. */
Expr * left = top->pExpr;
assert_not_null(left->pToken1);
assert_eq(1u, (size_t)left->pToken1->position.row);
assert_eq(1u, (size_t)left->pToken1->position.col);
assert_eq(1u, (size_t)left->pToken1->end_position.row);
assert_eq(7u, (size_t)left->pToken1->end_position.col);
Expr left = p_Expr_pExpr(top);
assert(p_node_valid(p_Expr_pToken1(left)));
assert_eq(1u, (size_t)p_node_position(p_Expr_pToken1(left)).row);
assert_eq(1u, (size_t)p_node_position(p_Expr_pToken1(left)).col);
assert_eq(1u, (size_t)p_node_end_position(p_Expr_pToken1(left)).row);
assert_eq(7u, (size_t)p_node_end_position(p_Expr_pToken1(left)).col);
/* The whole tree spans columns 1..17. */
assert_eq(1u, (size_t)tree->position.col);
assert_eq(17u, (size_t)tree->end_position.col);
assert_eq(1u, (size_t)p_node_position(tree).col);
assert_eq(17u, (size_t)p_node_end_position(tree).col);
p_tree_delete(tree);
p_context_delete(context);
return 0;
+14 -13
View File
@@ -20,8 +20,8 @@ size_t mylexfn(p_context_t * context, p_token_info_t * out_token_info)
{
return inner_result;
}
Start * inner = p_result_Start(context);
assert(inner !is null);
Start inner = p_result_Start(context);
assert(inner.valid);
/* p_parse_inner rewound the input so that ')' was not consumed; consume
* it now. */
p_token_info_t rparen_info;
@@ -31,7 +31,9 @@ size_t mylexfn(p_context_t * context, p_token_info_t * out_token_info)
/* The subtree covers the region strictly between the parentheses. */
assert_eq(start_position.col + 1u, inner.position.col);
assert_eq(rparen_info.position.col - 1u, inner.end_position.col);
p_tree_delete_Start(inner);
/* The inner subtree is discarded (the lexer synthesizes a num token in
* its place), but its nodes remain in the shared context arena and are
* freed with the context. */
/* Synthesize a num token spanning the entire "( ... )" group. */
out_token_info.token = TOKEN_num;
out_token_info.position = start_position;
@@ -53,15 +55,15 @@ unittest
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * tree = p_result(context);
assert(tree !is null);
Start tree = p_result(context);
assert(tree.valid);
/* Start -> Expr, where the top Expr is "Expr plus num". */
Expr * top = tree.pExpr;
assert(top !is null);
assert(top.pExpr !is null);
assert(top.pToken2 !is null);
assert(top.pToken3 !is null);
Expr top = tree.pExpr;
assert(top.valid);
assert(top.pExpr.valid);
assert(top.pToken2.valid);
assert(top.pToken3.valid);
/* The '+' joining the two groups is at column 9. */
assert_eq(1u, top.pToken2.position.row);
@@ -75,8 +77,8 @@ unittest
/* Left operand: Expr -> num, the synthesized num for "(3 + 4)", spanning
* columns 1..7. */
Expr * left = top.pExpr;
assert(left.pToken1 !is null);
Expr left = top.pExpr;
assert(left.pToken1.valid);
assert_eq(1u, left.pToken1.position.row);
assert_eq(1u, left.pToken1.position.col);
assert_eq(1u, left.pToken1.end_position.row);
@@ -86,6 +88,5 @@ unittest
assert_eq(1u, tree.position.col);
assert_eq(17u, tree.end_position.col);
p_tree_delete(tree);
p_context_delete(context);
}
+23 -44
View File
@@ -5,24 +5,8 @@
int main()
{
/* Grammar (tree generation mode, shared reduce state):
* tree;
* token a; token b;
* start Start;
* start R1;
* Start -> R1 a;
* Start -> R2 b;
* R1 -> a b;
* R2 -> a b;
*
* Exercises p_parse_inner_R1() with a non-EOF follow token in tree
* generation mode. Verifies:
* * The reduced tree for R1 is well-formed after a follow-token
* completion.
* * The follow token is not consumed and remains available for a
* subsequent p_lex() call.
* * p_tree_delete_R1() cleans up the returned tree without leaks
* (verified in CI via valgrind). */
/* See the D variant / grammar comments for details. In tree mode the tree
* nodes live in the context arena and are freed with p_context_delete(). */
/* Baseline: p_parse_R1 works on "ab" and the returned tree is
* well-formed. */
@@ -30,13 +14,12 @@ int main()
char const * input = "ab";
p_context_t * context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse_R1(context) == P_SUCCESS);
R1 * tree = p_result_R1(context);
assert_not_null(tree);
assert_not_null(tree->pToken1);
assert_eq((size_t)TOKEN_a, (size_t)tree->pToken1->token);
assert_not_null(tree->pToken2);
assert_eq((size_t)TOKEN_b, (size_t)tree->pToken2->token);
p_tree_delete_R1(tree);
R1 tree = p_result_R1(context);
assert(p_node_valid(tree));
assert(p_node_valid(p_R1_pToken1(tree)));
assert_eq((size_t)TOKEN_a, (size_t)p_tree_walk_R1(tree, pToken1, token));
assert(p_node_valid(p_R1_pToken2(tree)));
assert_eq((size_t)TOKEN_b, (size_t)p_tree_walk_R1(tree, pToken2, token));
p_context_delete(context);
}
@@ -50,23 +33,23 @@ int main()
assert(p_parse_inner_R1(context, follow_tokens, 1u) == P_SUCCESS);
/* Tree is well-formed. */
R1 * tree = p_result_R1(context);
assert_not_null(tree);
assert_not_null(tree->pToken1);
assert_eq((size_t)TOKEN_a, (size_t)tree->pToken1->token);
assert_eq(1u, (size_t)tree->pToken1->position.row);
assert_eq(1u, (size_t)tree->pToken1->position.col);
assert_not_null(tree->pToken2);
assert_eq((size_t)TOKEN_b, (size_t)tree->pToken2->token);
assert_eq(1u, (size_t)tree->pToken2->position.row);
assert_eq(2u, (size_t)tree->pToken2->position.col);
R1 tree = p_result_R1(context);
assert(p_node_valid(tree));
assert(p_node_valid(p_R1_pToken1(tree)));
assert_eq((size_t)TOKEN_a, (size_t)p_tree_walk_R1(tree, pToken1, token));
assert_eq(1u, (size_t)p_node_position(p_R1_pToken1(tree)).row);
assert_eq(1u, (size_t)p_node_position(p_R1_pToken1(tree)).col);
assert(p_node_valid(p_R1_pToken2(tree)));
assert_eq((size_t)TOKEN_b, (size_t)p_tree_walk_R1(tree, pToken2, token));
assert_eq(1u, (size_t)p_node_position(p_R1_pToken2(tree)).row);
assert_eq(2u, (size_t)p_node_position(p_R1_pToken2(tree)).col);
/* The R1 tree covers positions 1..2 — the third `b` at column 3 is
/* The R1 tree covers positions 1..2 - the third `b` at column 3 is
* the follow token and is not part of the tree. */
assert_eq(1u, (size_t)tree->position.row);
assert_eq(1u, (size_t)tree->position.col);
assert_eq(1u, (size_t)tree->end_position.row);
assert_eq(2u, (size_t)tree->end_position.col);
assert_eq(1u, (size_t)p_node_position(tree).row);
assert_eq(1u, (size_t)p_node_position(tree).col);
assert_eq(1u, (size_t)p_node_end_position(tree).row);
assert_eq(2u, (size_t)p_node_end_position(tree).col);
/* Follow token remains in the input. */
p_position_t pos = p_position(context);
@@ -78,10 +61,6 @@ int main()
assert_eq(1u, (size_t)token_info.position.row);
assert_eq(3u, (size_t)token_info.position.col);
/* p_tree_delete_R1 must free every node reachable from the tree
* without leaking anything. valgrind (invoked by the spec runner on
* Linux) will detect any missed frees. */
p_tree_delete_R1(tree);
p_context_delete(context);
}
+10 -10
View File
@@ -16,13 +16,13 @@ unittest
string input = "ab";
p_context_t * context = p_context_new(input);
assert(p_parse_R1(context) == P_SUCCESS);
R1 * tree = p_result_R1(context);
assert(tree !is null);
assert(tree.pToken1 !is null);
R1 tree = p_result_R1(context);
assert(tree.valid);
assert(tree.pToken1.valid);
assert(tree.pToken1.token == TOKEN_a);
assert(tree.pToken2 !is null);
assert(tree.pToken2.valid);
assert(tree.pToken2.token == TOKEN_b);
p_tree_delete_R1(tree);
p_context_delete(context);
}
/* Primary case: p_parse_inner_R1 with a non-EOF follow token completes
@@ -35,13 +35,13 @@ unittest
assert(p_parse_inner_R1(context, follow_tokens) == P_SUCCESS);
/* Tree is well-formed. */
R1 * tree = p_result_R1(context);
assert(tree !is null);
assert(tree.pToken1 !is null);
R1 tree = p_result_R1(context);
assert(tree.valid);
assert(tree.pToken1.valid);
assert(tree.pToken1.token == TOKEN_a);
assert(tree.pToken1.position.row == 1);
assert(tree.pToken1.position.col == 1);
assert(tree.pToken2 !is null);
assert(tree.pToken2.valid);
assert(tree.pToken2.token == TOKEN_b);
assert(tree.pToken2.position.row == 1);
assert(tree.pToken2.position.col == 2);
@@ -63,6 +63,6 @@ unittest
assert(token_info.position.row == 1);
assert(token_info.position.col == 3);
p_tree_delete_R1(tree);
p_context_delete(context);
}
}
+4 -5
View File
@@ -28,11 +28,10 @@ int main()
assert_eq(11, context->alias_a_value);
assert_eq(22, context->alias_b_value);
Start * start = p_result(context);
assert(start->pA != NULL);
assert(start->pB != NULL);
assert(start->pC == NULL);
p_tree_delete(start);
Start start = p_result(context);
assert(p_node_valid(p_Start_pA(start)));
assert(p_node_valid(p_Start_pB(start)));
assert(!p_node_valid(p_Start_pC(start)));
p_context_delete(context);
return 0;
+5 -5
View File
@@ -31,9 +31,9 @@ unittest
assert_eq(11, context.alias_a_value);
assert_eq(22, context.alias_b_value);
Start * start = p_result(context);
assert(start.pA !is null);
assert(start.pB !is null);
assert(start.pC is null);
p_tree_delete(start);
Start start = p_result(context);
assert(start.pA.valid);
assert(start.pB.valid);
assert(!start.pC.valid);
p_context_delete(context);
}
+3 -4
View File
@@ -9,11 +9,10 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
Top * top = p_result(context);
assert(top->pToken != NULL);
assert_eq(TOKEN_hi, top->pToken->token);
Top top = p_result(context);
assert(p_node_valid(p_Top_pToken(top)));
assert_eq(TOKEN_hi, p_tree_walk_Top(top, pToken, token));
p_tree_delete(top);
p_context_delete(context);
return 0;
+2 -2
View File
@@ -13,7 +13,7 @@ unittest
p_context_t * context;
context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
Top * top = p_result(context);
assert(top.pToken !is null);
Top top = p_result(context);
assert(top.pToken.valid);
assert_eq(TOKEN_hi, top.pToken.token);
}
+13 -16
View File
@@ -9,31 +9,28 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert_not_null(start->bs);
assert_not_null(start->bs->b);
assert_not_null(start->bs->bs->b);
assert_not_null(start->bs->bs->bs->b);
assert_not_null(start->bs->bs->bs->bs->b);
p_tree_delete(start);
Start start = p_result(context);
assert(p_node_valid(p_Start_bs(start)));
assert(p_node_valid(p_tree_walk_Start(start, bs, b)));
assert(p_node_valid(p_tree_walk_Start(start, bs, bs, b)));
assert(p_node_valid(p_tree_walk_Start(start, bs, bs, bs, b)));
assert(p_node_valid(p_tree_walk_Start(start, bs, bs, bs, bs, b)));
p_context_delete(context);
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse_Bs(context) == P_SUCCESS);
Bs * bs = p_result_Bs(context);
assert_not_null(bs->b);
assert_not_null(bs->bs->b);
assert_not_null(bs->bs->bs->b);
assert_not_null(bs->bs->bs->bs->b);
p_tree_delete_Bs(bs);
Bs bs = p_result_Bs(context);
assert(p_node_valid(p_Bs_b(bs)));
assert(p_node_valid(p_tree_walk_Bs(bs, bs, b)));
assert(p_node_valid(p_tree_walk_Bs(bs, bs, bs, b)));
assert(p_node_valid(p_tree_walk_Bs(bs, bs, bs, bs, b)));
p_context_delete(context);
input = "c";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse_R(context) == P_SUCCESS);
R * r = p_result_R(context);
assert_not_null(r->c);
p_tree_delete_R(r);
R r = p_result_R(context);
assert(p_node_valid(p_R_c(r)));
p_context_delete(context);
return 0;
+16 -16
View File
@@ -12,30 +12,30 @@ unittest
string input = "bbbb";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start.bs);
assert(start.bs.b);
assert(start.bs.bs.b);
assert(start.bs.bs.bs.b);
assert(start.bs.bs.bs.bs.b);
Start start = p_result(context);
assert(start.bs.valid);
assert(start.bs.b.valid);
assert(start.bs.bs.b.valid);
assert(start.bs.bs.bs.b.valid);
assert(start.bs.bs.bs.bs.b.valid);
p_tree_delete(start);
p_context_delete(context);
context = p_context_new(input);
assert(p_parse_Bs(context) == P_SUCCESS);
Bs * bs = p_result_Bs(context);
assert(bs.b);
assert(bs.bs.b);
assert(bs.bs.bs.b);
assert(bs.bs.bs.bs.b);
Bs bs = p_result_Bs(context);
assert(bs.b.valid);
assert(bs.bs.b.valid);
assert(bs.bs.bs.b.valid);
assert(bs.bs.bs.bs.b.valid);
p_tree_delete_Bs(bs);
p_context_delete(context);
input = "c";
context = p_context_new(input);
assert(p_parse_R(context) == P_SUCCESS);
R * r = p_result_R(context);
assert(r.c);
R r = p_result_R(context);
assert(r.c.valid);
p_tree_delete_R(r);
p_context_delete(context);
}
+13 -20
View File
@@ -18,29 +18,22 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start->pIDs);
assert(start->pIDs->id);
#ifdef __cplusplus
assert(start->pIDs->id->comments == "# c1\n# c2\n");
#else
assert(start->pIDs->id->comments);
assert(strcmp(start->pIDs->id->comments, "# c1\n# c2\n") == 0);
#endif
assert(start->pIDs->pIDs);
assert(start->pIDs->pIDs->id);
#ifdef __cplusplus
assert(start->pIDs->pIDs->id->comments == "# s1\n# s2\n");
#else
assert(start->pIDs->pIDs->id->comments);
assert(strcmp(start->pIDs->pIDs->id->comments, "# s1\n# s2\n") == 0);
#endif
Start start = p_result(context);
IDs ids = p_Start_pIDs(start);
assert(p_node_valid(ids));
Token id0 = p_IDs_id(ids);
assert(p_node_valid(id0));
assert(p_node_data(id0)->comments);
assert(strcmp(p_node_data(id0)->comments, "# c1\n# c2\n") == 0);
IDs ids2 = p_IDs_pIDs(ids);
assert(p_node_valid(ids2));
Token id1 = p_IDs_id(ids2);
assert(p_node_valid(id1));
assert(p_node_data(id1)->comments);
assert(strcmp(p_node_data(id1)->comments, "# s1\n# s2\n") == 0);
#ifndef __cplusplus
free(context->comments);
#endif
p_context_delete(context);
p_tree_delete(start);
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
#include "testparser.h"
#include <cassert>
#include <cstring>
#include <string>
int main()
{
char const * input =
"# c1\n"
"# c2\n"
"\n"
"first\n"
"\n \n \n"
" # s1\n"
" # s2\n"
"second\n";
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start start = p_result(context);
assert(start.pIDs().valid());
assert(start.pIDs().id().valid());
assert(start.pIDs().id().data()->comments == "# c1\n# c2\n");
assert(start.pIDs().pIDs().valid());
assert(start.pIDs().pIDs().id().valid());
assert(start.pIDs().pIDs().id().data()->comments == "# s1\n# s2\n");
p_context_delete(context);
return 0;
}
+6 -6
View File
@@ -19,13 +19,13 @@ unittest
"second\n";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
assert(start.pIDs);
assert(start.pIDs.id);
Start start = p_result(context);
assert(start.pIDs.valid);
assert(start.pIDs.id.valid);
assert(start.pIDs.id.comments == "# c1\n# c2\n");
assert(start.pIDs.pIDs);
assert(start.pIDs.pIDs.id);
assert(start.pIDs.pIDs.valid);
assert(start.pIDs.pIDs.id.valid);
assert(start.pIDs.pIDs.id.comments == "# s1\n# s2\n");
p_tree_delete(start);
p_context_delete(context);
}
+31 -34
View File
@@ -9,55 +9,52 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
Start * start = p_result(context);
assert(start->pItems1 != NULL);
assert(start->pItems != NULL);
Items * items = start->pItems;
assert(items->pItem != NULL);
assert(items->pItem->pToken1 != NULL);
assert_eq(TOKEN_a, items->pItem->pToken1->token);
assert_eq(11, items->pItem->pToken1->pvalue);
assert(items->pItemsMore != NULL);
ItemsMore * itemsmore = items->pItemsMore;
assert(itemsmore->pItem != NULL);
assert(itemsmore->pItem->pItem != NULL);
assert(itemsmore->pItem->pItem->pItem != NULL);
assert(itemsmore->pItem->pItem->pItem->pToken1 != NULL);
assert_eq(TOKEN_b, itemsmore->pItem->pItem->pItem->pToken1->token);
assert_eq(22, itemsmore->pItem->pItem->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore != NULL);
itemsmore = itemsmore->pItemsMore;
assert(itemsmore->pItem != NULL);
assert(itemsmore->pItem->pToken1 != NULL);
assert_eq(TOKEN_b, itemsmore->pItem->pToken1->token);
assert_eq(22, itemsmore->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore == NULL);
Start start = p_result(context);
assert(p_node_valid(p_Start_pItems1(start)));
assert(p_node_valid(p_Start_pItems(start)));
Items items = p_Start_pItems(start);
assert(p_node_valid(p_Items_pItem(items)));
assert(p_node_valid(p_tree_walk_Items(items, pItem, pToken1)));
assert_eq(TOKEN_a, p_tree_walk_Items(items, pItem, pToken1, token));
assert_eq(11, p_tree_walk_Items(items, pItem, pToken1, pvalue));
assert(p_node_valid(p_Items_pItemsMore(items)));
ItemsMore itemsmore = p_Items_pItemsMore(items);
assert(p_node_valid(p_ItemsMore_pItem(itemsmore)));
assert(p_node_valid(p_tree_walk_ItemsMore(itemsmore, pItem, pItem)));
assert(p_node_valid(p_tree_walk_ItemsMore(itemsmore, pItem, pItem, pItem)));
assert(p_node_valid(p_tree_walk_ItemsMore(itemsmore, pItem, pItem, pItem, pToken1)));
assert_eq(TOKEN_b, p_tree_walk_ItemsMore(itemsmore, pItem, pItem, pItem, pToken1, token));
assert_eq(22, p_tree_walk_ItemsMore(itemsmore, pItem, pItem, pItem, pToken1, pvalue));
assert(p_node_valid(p_ItemsMore_pItemsMore(itemsmore)));
itemsmore = p_ItemsMore_pItemsMore(itemsmore);
assert(p_node_valid(p_ItemsMore_pItem(itemsmore)));
assert(p_node_valid(p_tree_walk_ItemsMore(itemsmore, pItem, pToken1)));
assert_eq(TOKEN_b, p_tree_walk_ItemsMore(itemsmore, pItem, pToken1, token));
assert_eq(22, p_tree_walk_ItemsMore(itemsmore, pItem, pToken1, pvalue));
assert(!p_node_valid(p_ItemsMore_pItemsMore(itemsmore)));
p_tree_delete(start);
p_context_delete(context);
input = "";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start->pItems == NULL);
assert(!p_node_valid(p_Start_pItems(start)));
p_tree_delete(start);
p_context_delete(context);
input = "2 1";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start->pItems != NULL);
assert(start->pItems->pItem != NULL);
assert(start->pItems->pItem->pDual != NULL);
assert(start->pItems->pItem->pDual->pTwo1 != NULL);
assert(start->pItems->pItem->pDual->pOne2 != NULL);
assert(start->pItems->pItem->pDual->pTwo2 == NULL);
assert(start->pItems->pItem->pDual->pOne1 == NULL);
assert(p_node_valid(p_Start_pItems(start)));
assert(p_node_valid(p_tree_walk_Start(start, pItems, pItem)));
assert(p_node_valid(p_tree_walk_Start(start, pItems, pItem, pDual)));
assert(p_node_valid(p_tree_walk_Start(start, pItems, pItem, pDual, pTwo1)));
assert(p_node_valid(p_tree_walk_Start(start, pItems, pItem, pDual, pOne2)));
assert(!p_node_valid(p_tree_walk_Start(start, pItems, pItem, pDual, pTwo2)));
assert(!p_node_valid(p_tree_walk_Start(start, pItems, pItem, pDual, pOne1)));
p_tree_delete(start);
p_context_delete(context);
return 0;
+61
View File
@@ -0,0 +1,61 @@
#include "testparser.h"
#include <cassert>
#include <cstring>
#include "testutils.h"
int main()
{
char const * input = "a, ((b)), b";
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
Start start = p_result(context);
assert(start.pItems1().valid());
assert(start.pItems().valid());
Items items = start.pItems();
assert(items.pItem().valid());
assert(items.pItem().pToken1().valid());
assert_eq(TOKEN_a, items.pItem().pToken1().token());
assert_eq(11, items.pItem().pToken1().pvalue());
assert(items.pItemsMore().valid());
ItemsMore itemsmore = items.pItemsMore();
assert(itemsmore.pItem().valid());
assert(itemsmore.pItem().pItem().valid());
assert(itemsmore.pItem().pItem().pItem().valid());
assert(itemsmore.pItem().pItem().pItem().pToken1().valid());
assert_eq(TOKEN_b, itemsmore.pItem().pItem().pItem().pToken1().token());
assert_eq(22, itemsmore.pItem().pItem().pItem().pToken1().pvalue());
assert(itemsmore.pItemsMore().valid());
itemsmore = itemsmore.pItemsMore();
assert(itemsmore.pItem().valid());
assert(itemsmore.pItem().pToken1().valid());
assert_eq(TOKEN_b, itemsmore.pItem().pToken1().token());
assert_eq(22, itemsmore.pItem().pToken1().pvalue());
assert(!itemsmore.pItemsMore().valid());
p_context_delete(context);
input = "";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(!start.pItems().valid());
p_context_delete(context);
input = "2 1";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start.pItems().valid());
assert(start.pItems().pItem().valid());
assert(start.pItems().pItem().pDual().valid());
assert(start.pItems().pItem().pDual().pTwo1().valid());
assert(start.pItems().pItem().pDual().pOne2().valid());
assert(!start.pItems().pItem().pDual().pTwo2().valid());
assert(!start.pItems().pItem().pDual().pOne1().valid());
p_context_delete(context);
return 0;
}
+27 -27
View File
@@ -12,51 +12,51 @@ unittest
string input = "a, ((b)), b";
p_context_t * context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
Start * start = p_result(context);
assert(start.pItems1 !is null);
assert(start.pItems !is null);
Items * items = start.pItems;
assert(items.pItem !is null);
assert(items.pItem.pToken1 !is null);
Start start = p_result(context);
assert(start.pItems1.valid);
assert(start.pItems.valid);
Items items = start.pItems;
assert(items.pItem.valid);
assert(items.pItem.pToken1.valid);
assert_eq(TOKEN_a, items.pItem.pToken1.token);
assert_eq(11, items.pItem.pToken1.pvalue);
assert(items.pItemsMore !is null);
ItemsMore * itemsmore = items.pItemsMore;
assert(itemsmore.pItem !is null);
assert(itemsmore.pItem.pItem !is null);
assert(itemsmore.pItem.pItem.pItem !is null);
assert(itemsmore.pItem.pItem.pItem.pToken1 !is null);
assert(items.pItemsMore.valid);
ItemsMore itemsmore = items.pItemsMore;
assert(itemsmore.pItem.valid);
assert(itemsmore.pItem.pItem.valid);
assert(itemsmore.pItem.pItem.pItem.valid);
assert(itemsmore.pItem.pItem.pItem.pToken1.valid);
assert_eq(TOKEN_b, itemsmore.pItem.pItem.pItem.pToken1.token);
assert_eq(22, itemsmore.pItem.pItem.pItem.pToken1.pvalue);
assert(itemsmore.pItemsMore !is null);
assert(itemsmore.pItemsMore.valid);
itemsmore = itemsmore.pItemsMore;
assert(itemsmore.pItem !is null);
assert(itemsmore.pItem.pToken1 !is null);
assert(itemsmore.pItem.valid);
assert(itemsmore.pItem.pToken1.valid);
assert_eq(TOKEN_b, itemsmore.pItem.pToken1.token);
assert_eq(22, itemsmore.pItem.pToken1.pvalue);
assert(itemsmore.pItemsMore is null);
assert(!itemsmore.pItemsMore.valid);
p_tree_delete(start);
p_context_delete(context);
input = "";
context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start.pItems is null);
assert(!start.pItems.valid);
p_tree_delete(start);
p_context_delete(context);
input = "2 1";
context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start.pItems !is null);
assert(start.pItems.pItem !is null);
assert(start.pItems.pItem.pDual !is null);
assert(start.pItems.pItem.pDual.pTwo1 !is null);
assert(start.pItems.pItem.pDual.pOne2 !is null);
assert(start.pItems.pItem.pDual.pTwo2 is null);
assert(start.pItems.pItem.pDual.pOne1 is null);
assert(start.pItems.valid);
assert(start.pItems.pItem.valid);
assert(start.pItems.pItem.pDual.valid);
assert(start.pItems.pItem.pDual.pTwo1.valid);
assert(start.pItems.pItem.pDual.pOne2.valid);
assert(!start.pItems.pItem.pDual.pTwo2.valid);
assert(!start.pItems.pItem.pDual.pOne1.valid);
p_tree_delete(start);
p_context_delete(context);
}
+5 -6
View File
@@ -9,12 +9,11 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
Start * start = p_result(context);
assert(start->a != NULL);
assert(*start->a->pvalue == 1);
assert(start->b != NULL);
assert(*start->b->pvalue == 2);
Start start = p_result(context);
assert(p_node_valid(p_Start_a(start)));
assert(*p_tree_walk_Start(start, a, pvalue) == 1);
assert(p_node_valid(p_Start_b(start)));
assert(*p_tree_walk_Start(start, b, pvalue) == 2);
p_tree_delete(start);
p_context_delete(context);
}
+4 -5
View File
@@ -9,13 +9,12 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
assert_eq(TOKEN_a, start->first->pToken->token);
assert_eq(TOKEN_b, start->second->pToken->token);
assert_eq(TOKEN_c, start->third->pToken->token);
assert_eq(TOKEN_a, p_tree_walk_Start(start, first, pToken, token));
assert_eq(TOKEN_b, p_tree_walk_Start(start, second, pToken, token));
assert_eq(TOKEN_c, p_tree_walk_Start(start, third, pToken, token));
p_tree_delete(start);
p_context_delete(context);
return 0;
+2 -2
View File
@@ -12,11 +12,11 @@ unittest
string input = "\na\nb\nc";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
assert_eq(TOKEN_a, start.first.pToken.token);
assert_eq(TOKEN_b, start.second.pToken.token);
assert_eq(TOKEN_c, start.third.pToken.token);
p_tree_delete(start);
p_context_delete(context);
}
+77 -69
View File
@@ -9,105 +9,113 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
T t1 = p_Start_pT1(start);
Token k1 = p_T_pToken(t1);
A a1 = p_T_pA(t1);
assert_eq(2, start->pT1->pToken->position.row);
assert_eq(1, start->pT1->pToken->position.col);
assert_eq(2, start->pT1->pToken->end_position.row);
assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position));
assert_eq(3, start->pT1->pA->position.row);
assert_eq(3, start->pT1->pA->position.col);
assert_eq(3, start->pT1->pA->end_position.row);
assert_eq(8, start->pT1->pA->end_position.col);
assert_eq(2, start->pT1->position.row);
assert_eq(1, start->pT1->position.col);
assert_eq(3, start->pT1->end_position.row);
assert_eq(8, start->pT1->end_position.col);
assert_eq(2, p_node_position(k1).row);
assert_eq(1, p_node_position(k1).col);
assert_eq(2, p_node_end_position(k1).row);
assert_eq(1, p_node_end_position(k1).col);
assert(p_position_valid(p_node_position(a1)));
assert_eq(3, p_node_position(a1).row);
assert_eq(3, p_node_position(a1).col);
assert_eq(3, p_node_end_position(a1).row);
assert_eq(8, p_node_end_position(a1).col);
assert_eq(2, p_node_position(t1).row);
assert_eq(1, p_node_position(t1).col);
assert_eq(3, p_node_end_position(t1).row);
assert_eq(8, p_node_end_position(t1).col);
assert_eq(2, start->position.row);
assert_eq(1, start->position.col);
assert_eq(3, start->end_position.row);
assert_eq(8, start->end_position.col);
assert_eq(2, p_node_position(start).row);
assert_eq(1, p_node_position(start).col);
assert_eq(3, p_node_end_position(start).row);
assert_eq(8, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
input = "a\nbb";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
t1 = p_Start_pT1(start);
k1 = p_T_pToken(t1);
a1 = p_T_pA(t1);
assert_eq(1, start->pT1->pToken->position.row);
assert_eq(1, start->pT1->pToken->position.col);
assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position));
assert_eq(2, start->pT1->pA->position.row);
assert_eq(1, start->pT1->pA->position.col);
assert_eq(2, start->pT1->pA->end_position.row);
assert_eq(2, start->pT1->pA->end_position.col);
assert_eq(1, start->pT1->position.row);
assert_eq(1, start->pT1->position.col);
assert_eq(2, start->pT1->end_position.row);
assert_eq(2, start->pT1->end_position.col);
assert_eq(1, p_node_position(k1).row);
assert_eq(1, p_node_position(k1).col);
assert_eq(1, p_node_end_position(k1).row);
assert_eq(1, p_node_end_position(k1).col);
assert(p_position_valid(p_node_position(a1)));
assert_eq(2, p_node_position(a1).row);
assert_eq(1, p_node_position(a1).col);
assert_eq(2, p_node_end_position(a1).row);
assert_eq(2, p_node_end_position(a1).col);
assert_eq(1, p_node_position(t1).row);
assert_eq(1, p_node_position(t1).col);
assert_eq(2, p_node_end_position(t1).row);
assert_eq(2, p_node_end_position(t1).col);
assert_eq(1, start->position.row);
assert_eq(1, start->position.col);
assert_eq(2, start->end_position.row);
assert_eq(2, start->end_position.col);
assert_eq(1, p_node_position(start).row);
assert_eq(1, p_node_position(start).col);
assert_eq(2, p_node_end_position(start).row);
assert_eq(2, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
input = "a\nc\nc";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
t1 = p_Start_pT1(start);
k1 = p_T_pToken(t1);
a1 = p_T_pA(t1);
assert_eq(1, start->pT1->pToken->position.row);
assert_eq(1, start->pT1->pToken->position.col);
assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position));
assert_eq(2, start->pT1->pA->position.row);
assert_eq(1, start->pT1->pA->position.col);
assert_eq(3, start->pT1->pA->end_position.row);
assert_eq(1, start->pT1->pA->end_position.col);
assert_eq(1, start->pT1->position.row);
assert_eq(1, start->pT1->position.col);
assert_eq(3, start->pT1->end_position.row);
assert_eq(1, start->pT1->end_position.col);
assert_eq(1, p_node_position(k1).row);
assert_eq(1, p_node_position(k1).col);
assert_eq(1, p_node_end_position(k1).row);
assert_eq(1, p_node_end_position(k1).col);
assert(p_position_valid(p_node_position(a1)));
assert_eq(2, p_node_position(a1).row);
assert_eq(1, p_node_position(a1).col);
assert_eq(3, p_node_end_position(a1).row);
assert_eq(1, p_node_end_position(a1).col);
assert_eq(1, p_node_position(t1).row);
assert_eq(1, p_node_position(t1).col);
assert_eq(3, p_node_end_position(t1).row);
assert_eq(1, p_node_end_position(t1).col);
assert_eq(1, start->position.row);
assert_eq(1, start->position.col);
assert_eq(3, start->end_position.row);
assert_eq(1, start->end_position.col);
assert_eq(1, p_node_position(start).row);
assert_eq(1, p_node_position(start).col);
assert_eq(3, p_node_end_position(start).row);
assert_eq(1, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
input = "a";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
t1 = p_Start_pT1(start);
k1 = p_T_pToken(t1);
a1 = p_T_pA(t1);
assert_eq(1, start->pT1->pToken->position.row);
assert_eq(1, start->pT1->pToken->position.col);
assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(1, start->pT1->pToken->end_position.col);
assert(!p_position_valid(start->pT1->pA->position));
assert_eq(1, start->pT1->position.row);
assert_eq(1, start->pT1->position.col);
assert_eq(1, start->pT1->end_position.row);
assert_eq(1, start->pT1->end_position.col);
assert_eq(1, p_node_position(k1).row);
assert_eq(1, p_node_position(k1).col);
assert_eq(1, p_node_end_position(k1).row);
assert_eq(1, p_node_end_position(k1).col);
assert(!p_position_valid(p_node_position(a1)));
assert_eq(1, p_node_position(t1).row);
assert_eq(1, p_node_position(t1).col);
assert_eq(1, p_node_end_position(t1).row);
assert_eq(1, p_node_end_position(t1).col);
assert_eq(1, start->position.row);
assert_eq(1, start->position.col);
assert_eq(1, start->end_position.row);
assert_eq(1, start->end_position.col);
assert_eq(1, p_node_position(start).row);
assert_eq(1, p_node_position(start).col);
assert_eq(1, p_node_end_position(start).row);
assert_eq(1, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
return 0;
+5 -5
View File
@@ -12,7 +12,7 @@ unittest
string input = "\na\n bb ccc";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
assert_eq(2, start.pT1.pToken.position.row);
assert_eq(1, start.pT1.pToken.position.col);
@@ -33,7 +33,7 @@ unittest
assert_eq(3, start.end_position.row);
assert_eq(8, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
input = "a\nbb";
context = p_context_new(input);
@@ -59,7 +59,7 @@ unittest
assert_eq(2, start.end_position.row);
assert_eq(2, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
input = "a\nc\nc";
context = p_context_new(input);
@@ -85,7 +85,7 @@ unittest
assert_eq(3, start.end_position.row);
assert_eq(1, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
input = "a";
context = p_context_new(input);
@@ -107,5 +107,5 @@ unittest
assert_eq(1, start.end_position.row);
assert_eq(1, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
}
+17 -18
View File
@@ -373,46 +373,45 @@ int main(int argc, char * argv[])
context = p_context_new((const uint8_t *)input, strlen(input));
size_t result = p_parse(context);
assert_eq(P_SUCCESS, result);
PModule * pmod = p_result(context);
PModuleItems * pmis = pmod->pModuleItems;
PFunctionDefinition ** pfds;
PModule pmod = p_result(context);
PModuleItems pmis = p_PModule_pModuleItems(pmod);
PFunctionDefinition * pfds;
size_t n_pfds = 0u;
while (pmis != NULL)
while (p_node_valid(pmis))
{
PModuleItem * pmi = pmis->pModuleItem;
if (pmi->pFunctionDefinition != NULL)
PModuleItem pmi = p_PModuleItems_pModuleItem(pmis);
if (p_node_valid(p_PModuleItem_pFunctionDefinition(pmi)))
{
n_pfds++;
}
pmis = pmis->pModuleItems;
pmis = p_PModuleItems_pModuleItems(pmis);
}
pfds = (PFunctionDefinition **)malloc(n_pfds * sizeof(PModuleItems *));
pmis = pmod->pModuleItems;
pfds = (PFunctionDefinition *)malloc(n_pfds * sizeof(PFunctionDefinition));
pmis = p_PModule_pModuleItems(pmod);
size_t pfd_i = n_pfds;
while (pmis != NULL)
while (p_node_valid(pmis))
{
PModuleItem * pmi = pmis->pModuleItem;
PFunctionDefinition * pfd = pmi->pFunctionDefinition;
if (pfd != NULL)
PModuleItem pmi = p_PModuleItems_pModuleItem(pmis);
PFunctionDefinition pfd = p_PModuleItem_pFunctionDefinition(pmi);
if (p_node_valid(pfd))
{
pfd_i--;
assert(pfd_i < n_pfds);
pfds[pfd_i] = pfd;
}
pmis = pmis->pModuleItems;
pmis = p_PModuleItems_pModuleItems(pmis);
}
assert_eq(51, n_pfds);
for (size_t i = 0; i < n_pfds; i++)
{
if (strncmp(expected[i].name, (const char *)pfds[i]->name->pvalue.s, strlen(expected[i].name)) != 0 ||
(expected[i].token != pfds[i]->returntype->pType->pTypeBase->pToken1->token))
if (strncmp(expected[i].name, (const char *)p_node_data(p_PFunctionDefinition_name(pfds[i]))->pvalue.s, strlen(expected[i].name)) != 0 ||
(expected[i].token != p_tree_walk_PFunctionDefinition(pfds[i], returntype, pType, pTypeBase, pToken1, token)))
{
fprintf(stderr, "Index %lu: expected %s/%u, got %u\n", i, expected[i].name, expected[i].token, pfds[i]->returntype->pType->pTypeBase->pToken1->token);
fprintf(stderr, "Index %lu: expected %s/%u, got %u\n", i, expected[i].name, expected[i].token, p_tree_walk_PFunctionDefinition(pfds[i], returntype, pType, pTypeBase, pToken1, token));
}
}
free(pfds);
p_tree_delete(pmod);
p_context_delete(context);
return 0;
+9 -9
View File
@@ -378,19 +378,19 @@ def main() -> int
context = p_context_new(input);
size_t result = p_parse(context);
assert_eq(P_SUCCESS, result);
PModule * pmod = p_result(context);
PModuleItems * pmis = pmod.pModuleItems;
PFunctionDefinition *[] pfds;
while (pmis !is null)
PModule pmod = p_result(context);
PModuleItems pmis = pmod.pModuleItems;
PFunctionDefinition[] pfds;
while (pmis.valid)
{
PModuleItem * pmi = pmis.pModuleItem;
if (pmi is null)
PModuleItem pmi = pmis.pModuleItem;
if (!pmi.valid)
{
stderr.writeln("pmi is null!!!?");
assert(0);
}
PFunctionDefinition * pfd = pmi.pFunctionDefinition;
if (pfd !is null)
PFunctionDefinition pfd = pmi.pFunctionDefinition;
if (pfd.valid)
{
pfds = [pfd] ~ pfds;
}
@@ -405,5 +405,5 @@ def main() -> int
stderr.writeln("Index ", i, ": expected ", expected[i].name, "/", expected[i].token, ", got ", pfds[i].name.pvalue.s, "/", pfds[i].returntype.pType.pTypeBase.pToken1.token);
}
}
p_tree_delete(pmod);
p_context_delete(context);
}
+31 -34
View File
@@ -9,55 +9,52 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
PStartS * start = p_result(context);
assert(start->pItems1 != NULL);
assert(start->pItems != NULL);
PItemsS * items = start->pItems;
assert(items->pItem != NULL);
assert(items->pItem->pToken1 != NULL);
assert_eq(TOKEN_a, items->pItem->pToken1->token);
assert_eq(11, items->pItem->pToken1->pvalue);
assert(items->pItemsMore != NULL);
PItemsMoreS * itemsmore = items->pItemsMore;
assert(itemsmore->pItem != NULL);
assert(itemsmore->pItem->pItem != NULL);
assert(itemsmore->pItem->pItem->pItem != NULL);
assert(itemsmore->pItem->pItem->pItem->pToken1 != NULL);
assert_eq(TOKEN_b, itemsmore->pItem->pItem->pItem->pToken1->token);
assert_eq(22, itemsmore->pItem->pItem->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore != NULL);
itemsmore = itemsmore->pItemsMore;
assert(itemsmore->pItem != NULL);
assert(itemsmore->pItem->pToken1 != NULL);
assert_eq(TOKEN_b, itemsmore->pItem->pToken1->token);
assert_eq(22, itemsmore->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore == NULL);
PStartS start = p_result(context);
assert(p_node_valid(p_PStartS_pItems1(start)));
assert(p_node_valid(p_PStartS_pItems(start)));
PItemsS items = p_PStartS_pItems(start);
assert(p_node_valid(p_PItemsS_pItem(items)));
assert(p_node_valid(p_tree_walk_PItemsS(items, pItem, pToken1)));
assert_eq(TOKEN_a, p_tree_walk_PItemsS(items, pItem, pToken1, token));
assert_eq(11, p_tree_walk_PItemsS(items, pItem, pToken1, pvalue));
assert(p_node_valid(p_PItemsS_pItemsMore(items)));
PItemsMoreS itemsmore = p_PItemsS_pItemsMore(items);
assert(p_node_valid(p_PItemsMoreS_pItem(itemsmore)));
assert(p_node_valid(p_tree_walk_PItemsMoreS(itemsmore, pItem, pItem)));
assert(p_node_valid(p_tree_walk_PItemsMoreS(itemsmore, pItem, pItem, pItem)));
assert(p_node_valid(p_tree_walk_PItemsMoreS(itemsmore, pItem, pItem, pItem, pToken1)));
assert_eq(TOKEN_b, p_tree_walk_PItemsMoreS(itemsmore, pItem, pItem, pItem, pToken1, token));
assert_eq(22, p_tree_walk_PItemsMoreS(itemsmore, pItem, pItem, pItem, pToken1, pvalue));
assert(p_node_valid(p_PItemsMoreS_pItemsMore(itemsmore)));
itemsmore = p_PItemsMoreS_pItemsMore(itemsmore);
assert(p_node_valid(p_PItemsMoreS_pItem(itemsmore)));
assert(p_node_valid(p_tree_walk_PItemsMoreS(itemsmore, pItem, pToken1)));
assert_eq(TOKEN_b, p_tree_walk_PItemsMoreS(itemsmore, pItem, pToken1, token));
assert_eq(22, p_tree_walk_PItemsMoreS(itemsmore, pItem, pToken1, pvalue));
assert(!p_node_valid(p_PItemsMoreS_pItemsMore(itemsmore)));
p_tree_delete(start);
p_context_delete(context);
input = "";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start->pItems == NULL);
assert(!p_node_valid(p_PStartS_pItems(start)));
p_tree_delete(start);
p_context_delete(context);
input = "2 1";
context = p_context_new((uint8_t const *)input, strlen(input));
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start->pItems != NULL);
assert(start->pItems->pItem != NULL);
assert(start->pItems->pItem->pDual != NULL);
assert(start->pItems->pItem->pDual->pTwo1 != NULL);
assert(start->pItems->pItem->pDual->pOne2 != NULL);
assert(start->pItems->pItem->pDual->pTwo2 == NULL);
assert(start->pItems->pItem->pDual->pOne1 == NULL);
assert(p_node_valid(p_PStartS_pItems(start)));
assert(p_node_valid(p_tree_walk_PStartS(start, pItems, pItem)));
assert(p_node_valid(p_tree_walk_PStartS(start, pItems, pItem, pDual)));
assert(p_node_valid(p_tree_walk_PStartS(start, pItems, pItem, pDual, pTwo1)));
assert(p_node_valid(p_tree_walk_PStartS(start, pItems, pItem, pDual, pOne2)));
assert(!p_node_valid(p_tree_walk_PStartS(start, pItems, pItem, pDual, pTwo2)));
assert(!p_node_valid(p_tree_walk_PStartS(start, pItems, pItem, pDual, pOne1)));
p_tree_delete(start);
p_context_delete(context);
return 0;
+27 -27
View File
@@ -12,51 +12,51 @@ unittest
string input = "a, ((b)), b";
p_context_t * context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
PStartS * start = p_result(context);
assert(start.pItems1 !is null);
assert(start.pItems !is null);
PItemsS * items = start.pItems;
assert(items.pItem !is null);
assert(items.pItem.pToken1 !is null);
PStartS start = p_result(context);
assert(start.pItems1.valid);
assert(start.pItems.valid);
PItemsS items = start.pItems;
assert(items.pItem.valid);
assert(items.pItem.pToken1.valid);
assert_eq(TOKEN_a, items.pItem.pToken1.token);
assert_eq(11, items.pItem.pToken1.pvalue);
assert(items.pItemsMore !is null);
PItemsMoreS * itemsmore = items.pItemsMore;
assert(itemsmore.pItem !is null);
assert(itemsmore.pItem.pItem !is null);
assert(itemsmore.pItem.pItem.pItem !is null);
assert(itemsmore.pItem.pItem.pItem.pToken1 !is null);
assert(items.pItemsMore.valid);
PItemsMoreS itemsmore = items.pItemsMore;
assert(itemsmore.pItem.valid);
assert(itemsmore.pItem.pItem.valid);
assert(itemsmore.pItem.pItem.pItem.valid);
assert(itemsmore.pItem.pItem.pItem.pToken1.valid);
assert_eq(TOKEN_b, itemsmore.pItem.pItem.pItem.pToken1.token);
assert_eq(22, itemsmore.pItem.pItem.pItem.pToken1.pvalue);
assert(itemsmore.pItemsMore !is null);
assert(itemsmore.pItemsMore.valid);
itemsmore = itemsmore.pItemsMore;
assert(itemsmore.pItem !is null);
assert(itemsmore.pItem.pToken1 !is null);
assert(itemsmore.pItem.valid);
assert(itemsmore.pItem.pToken1.valid);
assert_eq(TOKEN_b, itemsmore.pItem.pToken1.token);
assert_eq(22, itemsmore.pItem.pToken1.pvalue);
assert(itemsmore.pItemsMore is null);
assert(!itemsmore.pItemsMore.valid);
p_tree_delete(start);
p_context_delete(context);
input = "";
context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start.pItems is null);
assert(!start.pItems.valid);
p_tree_delete(start);
p_context_delete(context);
input = "2 1";
context = p_context_new(input);
assert_eq(P_SUCCESS, p_parse(context));
start = p_result(context);
assert(start.pItems !is null);
assert(start.pItems.pItem !is null);
assert(start.pItems.pItem.pDual !is null);
assert(start.pItems.pItem.pDual.pTwo1 !is null);
assert(start.pItems.pItem.pDual.pOne2 !is null);
assert(start.pItems.pItem.pDual.pTwo2 is null);
assert(start.pItems.pItem.pDual.pOne1 is null);
assert(start.pItems.valid);
assert(start.pItems.pItem.valid);
assert(start.pItems.pItem.pDual.valid);
assert(start.pItems.pItem.pDual.pTwo1.valid);
assert(start.pItems.pItem.pDual.pOne2.valid);
assert(!start.pItems.pItem.pDual.pTwo2.valid);
assert(!start.pItems.pItem.pDual.pOne1.valid);
p_tree_delete(start);
p_context_delete(context);
}
+69 -59
View File
@@ -9,81 +9,91 @@ int main()
p_context_t * context;
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
T t1 = p_Start_pT1(start);
T t2 = p_Start_pT2(start);
T t3 = p_Start_pT3(start);
Token k1 = p_T_pToken(t1);
Token k2 = p_T_pToken(t2);
Token k3 = p_T_pToken(t3);
assert_eq(1, start->pT1->pToken->position.row);
assert_eq(1, start->pT1->pToken->position.col);
assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(1, start->pT1->pToken->end_position.col);
assert_eq(1, start->pT1->position.row);
assert_eq(1, start->pT1->position.col);
assert_eq(1, start->pT1->end_position.row);
assert_eq(1, start->pT1->end_position.col);
assert_eq(1, p_node_position(k1).row);
assert_eq(1, p_node_position(k1).col);
assert_eq(1, p_node_end_position(k1).row);
assert_eq(1, p_node_end_position(k1).col);
assert_eq(1, p_node_position(t1).row);
assert_eq(1, p_node_position(t1).col);
assert_eq(1, p_node_end_position(t1).row);
assert_eq(1, p_node_end_position(t1).col);
assert_eq(1, start->pT2->pToken->position.row);
assert_eq(2, start->pT2->pToken->position.col);
assert_eq(1, start->pT2->pToken->end_position.row);
assert_eq(3, start->pT2->pToken->end_position.col);
assert_eq(1, start->pT2->position.row);
assert_eq(2, start->pT2->position.col);
assert_eq(1, start->pT2->end_position.row);
assert_eq(3, start->pT2->end_position.col);
assert_eq(1, p_node_position(k2).row);
assert_eq(2, p_node_position(k2).col);
assert_eq(1, p_node_end_position(k2).row);
assert_eq(3, p_node_end_position(k2).col);
assert_eq(1, p_node_position(t2).row);
assert_eq(2, p_node_position(t2).col);
assert_eq(1, p_node_end_position(t2).row);
assert_eq(3, p_node_end_position(t2).col);
assert_eq(1, start->pT3->pToken->position.row);
assert_eq(4, start->pT3->pToken->position.col);
assert_eq(1, start->pT3->pToken->end_position.row);
assert_eq(6, start->pT3->pToken->end_position.col);
assert_eq(1, start->pT3->position.row);
assert_eq(4, start->pT3->position.col);
assert_eq(1, start->pT3->end_position.row);
assert_eq(6, start->pT3->end_position.col);
assert_eq(1, p_node_position(k3).row);
assert_eq(4, p_node_position(k3).col);
assert_eq(1, p_node_end_position(k3).row);
assert_eq(6, p_node_end_position(k3).col);
assert_eq(1, p_node_position(t3).row);
assert_eq(4, p_node_position(t3).col);
assert_eq(1, p_node_end_position(t3).row);
assert_eq(6, p_node_end_position(t3).col);
assert_eq(1, start->position.row);
assert_eq(1, start->position.col);
assert_eq(1, start->end_position.row);
assert_eq(6, start->end_position.col);
assert_eq(1, p_node_position(start).row);
assert_eq(1, p_node_position(start).col);
assert_eq(1, p_node_end_position(start).row);
assert_eq(6, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
input = "\n\n bb\nc\ncc\n\n a";
context = p_context_new((uint8_t const *)input, strlen(input));
assert(p_parse(context) == P_SUCCESS);
start = p_result(context);
t1 = p_Start_pT1(start);
t2 = p_Start_pT2(start);
t3 = p_Start_pT3(start);
k1 = p_T_pToken(t1);
k2 = p_T_pToken(t2);
k3 = p_T_pToken(t3);
assert_eq(3, start->pT1->pToken->position.row);
assert_eq(3, start->pT1->pToken->position.col);
assert_eq(3, start->pT1->pToken->end_position.row);
assert_eq(4, start->pT1->pToken->end_position.col);
assert_eq(3, start->pT1->position.row);
assert_eq(3, start->pT1->position.col);
assert_eq(3, start->pT1->end_position.row);
assert_eq(4, start->pT1->end_position.col);
assert_eq(3, p_node_position(k1).row);
assert_eq(3, p_node_position(k1).col);
assert_eq(3, p_node_end_position(k1).row);
assert_eq(4, p_node_end_position(k1).col);
assert_eq(3, p_node_position(t1).row);
assert_eq(3, p_node_position(t1).col);
assert_eq(3, p_node_end_position(t1).row);
assert_eq(4, p_node_end_position(t1).col);
assert_eq(4, start->pT2->pToken->position.row);
assert_eq(1, start->pT2->pToken->position.col);
assert_eq(5, start->pT2->pToken->end_position.row);
assert_eq(2, start->pT2->pToken->end_position.col);
assert_eq(4, start->pT2->position.row);
assert_eq(1, start->pT2->position.col);
assert_eq(5, start->pT2->end_position.row);
assert_eq(2, start->pT2->end_position.col);
assert_eq(4, p_node_position(k2).row);
assert_eq(1, p_node_position(k2).col);
assert_eq(5, p_node_end_position(k2).row);
assert_eq(2, p_node_end_position(k2).col);
assert_eq(4, p_node_position(t2).row);
assert_eq(1, p_node_position(t2).col);
assert_eq(5, p_node_end_position(t2).row);
assert_eq(2, p_node_end_position(t2).col);
assert_eq(7, start->pT3->pToken->position.row);
assert_eq(6, start->pT3->pToken->position.col);
assert_eq(7, start->pT3->pToken->end_position.row);
assert_eq(6, start->pT3->pToken->end_position.col);
assert_eq(7, start->pT3->position.row);
assert_eq(6, start->pT3->position.col);
assert_eq(7, start->pT3->end_position.row);
assert_eq(6, start->pT3->end_position.col);
assert_eq(7, p_node_position(k3).row);
assert_eq(6, p_node_position(k3).col);
assert_eq(7, p_node_end_position(k3).row);
assert_eq(6, p_node_end_position(k3).col);
assert_eq(7, p_node_position(t3).row);
assert_eq(6, p_node_position(t3).col);
assert_eq(7, p_node_end_position(t3).row);
assert_eq(6, p_node_end_position(t3).col);
assert_eq(3, start->position.row);
assert_eq(3, start->position.col);
assert_eq(7, start->end_position.row);
assert_eq(6, start->end_position.col);
assert_eq(3, p_node_position(start).row);
assert_eq(3, p_node_position(start).col);
assert_eq(7, p_node_end_position(start).row);
assert_eq(6, p_node_end_position(start).col);
p_tree_delete(start);
p_context_delete(context);
return 0;
+3 -3
View File
@@ -12,7 +12,7 @@ unittest
string input = "abbccc";
p_context_t * context = p_context_new(input);
assert(p_parse(context) == P_SUCCESS);
Start * start = p_result(context);
Start start = p_result(context);
assert_eq(1, start.pT1.pToken.position.row);
assert_eq(1, start.pT1.pToken.position.col);
@@ -46,7 +46,7 @@ unittest
assert_eq(1, start.end_position.row);
assert_eq(6, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
input = "\n\n bb\nc\ncc\n\n a";
context = p_context_new(input);
@@ -85,5 +85,5 @@ unittest
assert_eq(7, start.end_position.row);
assert_eq(6, start.end_position.col);
p_tree_delete(start);
p_context_delete(context);
}