Allow parser user code blocks in tree mode
This commit is contained in:
1 parent
b04c0ad205
commit
98390429a8
9 files changed
+281
-31
No files matched your search
@@ -745,6 +745,78 @@ EOF
|
||||
])
|
||||
end
|
||||
|
||||
it "executes user code associated with a parser rule in tree mode" do
|
||||
case language
|
||||
when "c", "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 == NULL) ? 1 : 0;
|
||||
${context.alias_a_value} = ${ay}->pToken1->pvalue;
|
||||
${context.alias_b_value} = ${bee}->pToken1->pvalue;
|
||||
>>
|
||||
A -> a;
|
||||
B -> b;
|
||||
C -> << ${context.c_is_null} = ($$ == NULL) ? 1 : 0; >>
|
||||
EOF
|
||||
when "d"
|
||||
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 is null) ? 1 : 0;
|
||||
${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; >>
|
||||
EOF
|
||||
end
|
||||
run_propane(language: language)
|
||||
compile("spec/test_parser_user_code_tree.#{language}", language: language)
|
||||
results = run_test(language: language)
|
||||
expect(results.stderr).to eq ""
|
||||
expect(results.status).to eq 0
|
||||
end
|
||||
|
||||
it "parses lists" do
|
||||
write_grammar <<EOF
|
||||
ptype #{language == "d" ? "uint" : "uint32_t"};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "testparser.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "testutils.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
char const * input = "ab";
|
||||
p_context_t * context;
|
||||
context = p_context_new((uint8_t const *)input, strlen(input));
|
||||
assert_eq(P_SUCCESS, p_parse(context));
|
||||
|
||||
/* The parser user code recorded values accessed via $$, $1, and $2 while
|
||||
* the tree node for the Start rule was being formed. */
|
||||
assert_eq(3, context->start_n_fields);
|
||||
assert_eq(11, context->start_a_value);
|
||||
assert_eq(11, context->a_value);
|
||||
assert_eq(22, context->b_value);
|
||||
assert_eq(TOKEN_b, context->b_token);
|
||||
|
||||
/* The empty-matched rule C has a null $$ tree node, and its field in the
|
||||
* Start node is null as well. */
|
||||
assert_eq(1, context->c_is_null);
|
||||
assert_eq(1, context->c_field_is_null);
|
||||
|
||||
/* Field aliases reference the same component tree nodes as the positional
|
||||
* references. */
|
||||
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);
|
||||
p_context_delete(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import testparser;
|
||||
import std.stdio;
|
||||
import testutils;
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
string input = "ab";
|
||||
p_context_t * context = p_context_new(input);
|
||||
assert_eq(P_SUCCESS, p_parse(context));
|
||||
|
||||
/* The parser user code recorded values accessed via $$, $1, and $2 while
|
||||
* the tree node for the Start rule was being formed. */
|
||||
assert_eq(3, context.start_n_fields);
|
||||
assert_eq(11, context.start_a_value);
|
||||
assert_eq(11, context.a_value);
|
||||
assert_eq(22, context.b_value);
|
||||
assert_eq(TOKEN_b, context.b_token);
|
||||
|
||||
/* The empty-matched rule C has a null $$ tree node, and its field in the
|
||||
* Start node is null as well. */
|
||||
assert_eq(1, context.c_is_null);
|
||||
assert_eq(1, context.c_field_is_null);
|
||||
|
||||
/* Field aliases reference the same component tree nodes as the positional
|
||||
* references. */
|
||||
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);
|
||||
}
|
||||
Reference in new issue
Block a user