From 83727e2bcd915a0f15a0ff9d8ffd6bf37ca136bd Mon Sep 17 00:00:00 2001 From: soasme Date: Sun, 28 Mar 2021 16:52:53 +1300 Subject: [PATCH 1/3] get/set grammar rule name. --- peppapeg.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ peppapeg.h | 46 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/peppapeg.c b/peppapeg.c index 634a52de..3e7c4ae6 100644 --- a/peppapeg.c +++ b/peppapeg.c @@ -1294,6 +1294,7 @@ P4_CreateLiteral(const P4_String literal, bool sensitive) { expr->id = 0; expr->kind = P4_Literal; expr->flag = 0; + expr->name = NULL; expr->literal = strdup(literal); expr->sensitive = sensitive; return expr; @@ -1308,6 +1309,7 @@ P4_CreateRange(P4_Rune lower, P4_Rune upper, size_t stride) { expr->id = 0; expr->kind = P4_Range; expr->flag = 0; + expr->name = NULL; expr->lower = lower; expr->upper = upper; expr->stride = stride; @@ -1323,6 +1325,7 @@ P4_CreateReference(P4_RuleID id) { expr->id = 0; expr->kind = P4_Reference; expr->flag = 0; + expr->name = NULL; expr->ref_id = id; expr->ref_expr = NULL; return expr; @@ -1337,6 +1340,7 @@ P4_CreatePositive(P4_Expression* refexpr) { expr->id = 0; expr->kind = P4_Positive; expr->flag = 0; + expr->name = NULL; expr->ref_expr = refexpr; return expr; } @@ -1350,6 +1354,7 @@ P4_CreateNegative(P4_Expression* refexpr) { expr->id = 0; expr->kind = P4_Negative; expr->flag = 0; + expr->name = NULL; expr->ref_expr = refexpr; return expr; } @@ -1362,6 +1367,7 @@ P4_CreateContainer(size_t count) { P4_Expression* expr = malloc(sizeof(P4_Expression)); expr->id = 0; expr->flag = 0; + expr->name = NULL; expr->count = count; expr->members = malloc(sizeof(P4_Expression*) * count); return expr; @@ -1467,6 +1473,7 @@ P4_CreateRepeatMinMax(P4_Expression* repeat, size_t min, size_t max) { P4_Expression* expr = malloc(sizeof(P4_Expression)); expr->id = 0; expr->flag = 0; + expr->name = NULL; expr->kind = P4_Repeat; expr->repeat_expr = repeat; expr->repeat_min = min; @@ -1510,6 +1517,7 @@ P4_CreateBackReference(size_t index, bool sensitive) { expr->id = 0; expr->kind = P4_BackReference; expr->flag = 0; + expr->name = NULL; expr->backref_index = index; expr->sensitive = sensitive; return expr; @@ -1577,6 +1585,18 @@ P4_GetGrammarRule(P4_Grammar* grammar, P4_RuleID id) { return NULL; } +P4_PUBLIC P4_Expression* +P4_GetGrammarRuleByName(P4_Grammar* grammar, P4_String name) { + size_t i; + P4_Expression* rule = NULL; + for (i = 0; i < grammar->count; i++) { + rule = grammar->rules[i]; + if (rule && rule->name && strcmp(rule->name, name) == 0) + return rule; + } + return NULL; +} + P4_PUBLIC P4_Error P4_SetGrammarRuleFlag(P4_Grammar* grammar, P4_RuleID id, P4_ExpressionFlag flag) { P4_Expression* expr = P4_GetGrammarRule(grammar, id); @@ -1641,6 +1661,31 @@ P4_AddGrammarRule(P4_Grammar* grammar, P4_RuleID id, P4_Expression* expr) { return P4_Ok; } +P4_PUBLIC P4_Error +P4_SetGrammarRuleName(P4_Grammar* grammar, P4_RuleID id, P4_String name) { + P4_Expression* expr = P4_GetGrammarRule(grammar, id); + + if (expr == NULL) + return P4_NullError; + + if (expr->name != NULL) + free(expr->name); + + expr->name = strdup(name); + + return P4_Ok; +} + +P4_PUBLIC P4_String +P4_GetGrammarRuleName(P4_Grammar* grammar, P4_RuleID id) { + P4_Expression* expr = P4_GetGrammarRule(grammar, id); + + if (expr == NULL) + return NULL; + + return expr->name; +} + P4_PUBLIC P4_Source* P4_CreateSource(P4_String content, P4_RuleID rule_id) { P4_Source* source = malloc(sizeof(P4_Source)); diff --git a/peppapeg.h b/peppapeg.h index e7467cfa..559491c3 100644 --- a/peppapeg.h +++ b/peppapeg.h @@ -380,8 +380,8 @@ typedef struct P4_Source { * The grammar rule. */ typedef struct P4_Expression { - /* The name of expression (only for debugging). */ - /* P4_String name; */ + /* The name of expression. */ + P4_String name; /** The id of expression. */ P4_RuleID id; /** The kind of expression. */ @@ -1458,10 +1458,33 @@ void P4_DeleteGrammar(P4_Grammar*); */ P4_Error P4_AddGrammarRule(P4_Grammar*, P4_RuleID, P4_Expression*); +/** + * Set the name for a grammar rule. + * + * @param grammar The grammar. + * @param id The grammar rule id. + * @param name The grammar rule name. + * @return The error code. + * + * Example: + * + * P4_SetRuleName(grammar, ENTRY, "entry"); + */ +P4_Error P4_SetGrammarRuleName(P4_Grammar* grammar, P4_RuleID id, P4_String name); - - - +/** + * Get the name for a grammar rule. + * + * @param grammar The grammar. + * @param id The grammar rule id. + * @return The grammar rule name. + * + * Example: + * + * P4_String name = P4_GetRuleName(grammar, ENTRY); + * printf("%s\n", name); + */ +P4_String P4_GetGrammarRuleName(P4_Grammar* grammar, P4_RuleID id); /** * Delete a grammar rule. @@ -1487,6 +1510,19 @@ void P4_DeleteGrammarRule(P4_Grammar*, P4_RuleID); */ P4_Expression* P4_GetGrammarRule(P4_Grammar*, P4_RuleID); +/** + * Get a grammar rule by its name. + * + * @param grammar The grammar. + * @param name The grammar rule name. + * @return The grammar rule expression. Returns NULL if not found. + * + * P4_AddLiteral(grammar, 1, "a", true); + * P4_SetGrammarRuleName(grammar, 1, "rule_a"); + * P4_Expression* expr = P4_GetGrammarRule(grammar, "rule_a"); // The literal expression. + */ +P4_Expression* P4_GetGrammarRuleByName(P4_Grammar* grammar, P4_String name); + /** * @brief Set the flag of a grammar rule. * @param grammar The grammar. From 9af07d4c04d4a6ea90d2c4eb61f2fd04c8b90066 Mon Sep 17 00:00:00 2001 From: soasme Date: Sun, 28 Mar 2021 16:53:16 +1300 Subject: [PATCH 2/3] add a test case for grammar rule name. --- tests/test_misc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_misc.c b/tests/test_misc.c index ab25d33b..b42abe12 100644 --- a/tests/test_misc.c +++ b/tests/test_misc.c @@ -197,6 +197,21 @@ void test_lineno_offset(void) { } +void test_name(void) { + const int R1 = 1; + + P4_Grammar* grammar = P4_CreateGrammar(); + TEST_ASSERT_NOT_NULL(grammar); + TEST_ASSERT_EQUAL( P4_Ok, P4_AddLiteral(grammar, R1, "A", false)); + TEST_ASSERT_EQUAL( P4_Ok, P4_SetGrammarRuleName(grammar, R1, "R1")); + TEST_ASSERT_EQUAL_STRING( "R1", P4_GetGrammarRuleName(grammar, R1)); + P4_Expression* expr = P4_GetGrammarRule(grammar, R1); + TEST_ASSERT_EQUAL( expr, P4_GetGrammarRuleByName(grammar, "R1")); + TEST_ASSERT_EQUAL( NULL, P4_GetGrammarRuleByName(grammar, "R0")); + + P4_DeleteGrammar(grammar); +} + int main(void) { UNITY_BEGIN(); @@ -207,6 +222,7 @@ int main(void) { RUN_TEST(test_error_string); RUN_TEST(test_source_slice); RUN_TEST(test_lineno_offset); + RUN_TEST(test_name); return UNITY_END(); } From bb228ec2d672f893cbe3f62fce53bb2c1d5e8e6e Mon Sep 17 00:00:00 2001 From: soasme Date: Sun, 28 Mar 2021 16:55:23 +1300 Subject: [PATCH 3/3] free expr name on deleting an expression. --- peppapeg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/peppapeg.c b/peppapeg.c index 3e7c4ae6..f084720a 100644 --- a/peppapeg.c +++ b/peppapeg.c @@ -2174,6 +2174,9 @@ P4_DeleteExpression(P4_Expression* expr) { break; } + if (expr->name) + free(expr->name); + free(expr); }