Skip to content

Commit

Permalink
Merge pull request #57 from soasme/jsonify-need-grammar
Browse files Browse the repository at this point in the history
Jsonify need grammar
  • Loading branch information
soasme committed Apr 8, 2021
2 parents b495cb8 + 708d3f4 commit 5f34929
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 27 deletions.
28 changes: 19 additions & 9 deletions docs/build.rst
@@ -1,13 +1,28 @@
Build
=====

Build Peppa PEG
---------------

Assume you have cmake and gcc installed.

.. code-block:: console
$ cmake -E make_directory ./build
$ cd build
$ cmake ..
$ make
Development
------------

If you have a difficulty having a complete development environment for Peppa PEG, try Docker:

.. code-block:: console
$ docker run --rm -v `pwd`:/app -it ubuntu:latest bash
# apt-get install git gcc gdb valgrind make cmake python3 python3-venv python3-pip doxygen
# // yes, you have all the dev-dependencies.
# // you have all the dev-dependencies now.
Testing Peppa PEG requires downloading the test framework `Unity`:

Expand All @@ -16,14 +31,6 @@ Testing Peppa PEG requires downloading the test framework `Unity`:
$ git submodule init
$ git submodule update
Assume you have cmake and gcc installed.

.. code-block:: console
$ cmake -E make_directory ./build
$ cd build
$ cmake ..
If you have Valgrind installed, you can enable `ENABLE_VALGRIND`.

.. code-block:: console
Expand All @@ -48,6 +55,9 @@ To build docs,
$ cmake --build . --target docs
GitHub Actions
--------------

Peppa PEG uses GitHub Actions building docs whenever a change is pushed to the main branch.

The docs site is pushed to gh-pages branch and published to <https://www.soasme.com/PeppaPEG/>.
87 changes: 81 additions & 6 deletions peppapeg.c
Expand Up @@ -1340,15 +1340,21 @@ P4_MatchBackReference(P4_Source* s, P4_Expression* e, P4_Slice* backrefs, P4_Exp
}

void
P4_JsonifySourceAst(FILE* stream, P4_Token* token, P4_KindToName namefunc) {
fprintf(stream, "[");
P4_JsonifySourceAst(P4_Grammar* grammar, FILE* stream, P4_Token* token) {
P4_Token* tmp = token;
P4_Expression* expr = NULL;

fprintf(stream, "[");
while (tmp != NULL) {
fprintf(stream, "{\"slice\":[%lu,%lu]", tmp->slice.start.pos, tmp->slice.stop.pos);
fprintf(stream, ",\"type\":\"%s\"", namefunc(tmp->rule_id));
expr = P4_GetGrammarRule(grammar, tmp->rule_id);
if (expr->name)
fprintf(stream, ",\"type\":\"%s\"", expr->name);
else
fprintf(stream, ",\"type\":\"R%lu\"", tmp->rule_id);
if (tmp->head != NULL) {
fprintf(stream, ",\"children\":");
P4_JsonifySourceAst(stream, tmp->head, namefunc);
P4_JsonifySourceAst(grammar, stream, tmp->head);
}
fprintf(stream, "}");
if (tmp->next != NULL) fprintf(stream, ",");
Expand Down Expand Up @@ -2576,6 +2582,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleNumber, "number"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleNumber, P4_FLAG_SQUASHED | P4_FLAG_TIGHT))
goto finalize;

Expand Down Expand Up @@ -2611,6 +2620,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleChar, "char"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleChar, P4_FLAG_SQUASHED | P4_FLAG_TIGHT))
goto finalize;

Expand All @@ -2621,6 +2633,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleLiteral, "literal"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleLiteral, P4_FLAG_SQUASHED | P4_FLAG_TIGHT))
goto finalize;

Expand All @@ -2637,6 +2652,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRange, "range"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleReference, 2,
P4_CreateChoiceWithMembers(3,
P4_CreateRange('a', 'z', 1),
Expand All @@ -2654,6 +2672,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleReference, "reference"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleReference, P4_FLAG_SQUASHED | P4_FLAG_TIGHT))
goto finalize;

Expand All @@ -2663,21 +2684,36 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRulePositive, "positive"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleNegative, 2,
P4_CreateLiteral("!", true),
P4_CreateReference(P4_PegRulePrimary)
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleNegative, "negative"))
goto finalize;

if (P4_Ok != P4_AddLiteral(grammar, P4_PegRuleRepeatOnceOrMore, "+", true))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatOnceOrMore, "onceormore"))
goto finalize;

if (P4_Ok != P4_AddLiteral(grammar, P4_PegRuleRepeatZeroOrMore, "*", true))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatZeroOrMore, "zeroormore"))
goto finalize;

if (P4_Ok != P4_AddLiteral(grammar, P4_PegRuleRepeatZeroOrOnce, "?", true))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatZeroOrOnce, "zerooronce"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRepeatMin, 4,
P4_CreateLiteral("{", true),
P4_CreateReference(P4_PegRuleNumber),
Expand All @@ -2686,6 +2722,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatMin, "repeatmin"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRepeatMax, 4,
P4_CreateLiteral("{", true),
P4_CreateLiteral(",", true),
Expand All @@ -2694,6 +2733,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatMax, "repeatmax"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRepeatMinMax, 5,
P4_CreateLiteral("{", true),
P4_CreateReference(P4_PegRuleNumber),
Expand All @@ -2703,13 +2745,19 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatMinMax, "repeatminmax"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRepeatExact, 3,
P4_CreateLiteral("{", true),
P4_CreateReference(P4_PegRuleNumber),
P4_CreateLiteral("}", true)
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeatExact, "repeatexact"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRepeat, 2,
P4_CreateReference(P4_PegRulePrimary),
P4_CreateZeroOrOnce(
Expand All @@ -2726,6 +2774,9 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRepeat, "repeat"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleRepeat, P4_FLAG_NON_TERMINAL))
goto finalize;

Expand All @@ -2747,28 +2798,37 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRulePrimary, P4_FLAG_LIFTED))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleInsensitiveLiteral, 2,
P4_CreateLiteral("i", true),
P4_CreateReference(P4_PegRuleLiteral)
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleInsensitiveLiteral, P4_FLAG_TIGHT))
if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleInsensitiveLiteral, "insensitive"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRulePrimary, P4_FLAG_LIFTED))
if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleInsensitiveLiteral, P4_FLAG_TIGHT))
goto finalize;

if (P4_Ok != P4_AddJoin(grammar, P4_PegRuleChoice, "/", P4_PegRuleSequence))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleChoice, "choice"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleChoice, P4_FLAG_NON_TERMINAL))
goto finalize;

if (P4_Ok != P4_AddOnceOrMore(grammar, P4_PegRuleSequence,
P4_CreateReference(P4_PegRuleRepeat)))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleSequence, "sequence"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleSequence, P4_FLAG_NON_TERMINAL))
goto finalize;

Expand All @@ -2781,6 +2841,9 @@ P4_Grammar* P4_CreatePegGrammar () {
if (P4_Ok != P4_AddReference(grammar, P4_PegRuleRuleName, P4_PegRuleReference))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRuleName, "name"))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleFlag(grammar, P4_PegRuleRuleName, P4_FLAG_SQUASHED))
goto finalize;

Expand All @@ -2797,11 +2860,17 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleDecorator, "decorator"))
goto finalize;

if (P4_Ok != P4_AddZeroOrMore(grammar, P4_PegRuleRuleDecorators,
P4_CreateReference(P4_PegRuleDecorator)
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRuleDecorators, "decorators"))
goto finalize;

if (P4_Ok != P4_AddSequenceWithMembers(grammar, P4_PegRuleRule, 5,
P4_CreateReference(P4_PegRuleRuleDecorators),
P4_CreateReference(P4_PegRuleRuleName),
Expand All @@ -2811,9 +2880,15 @@ P4_Grammar* P4_CreatePegGrammar () {
))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegRuleRule, "rule"))
goto finalize;

if (P4_Ok != P4_AddOnceOrMore(grammar, P4_PegGrammar, P4_CreateReference(P4_PegRuleRule)))
goto finalize;

if (P4_Ok != P4_SetGrammarRuleName(grammar, P4_PegGrammar, "grammar"))
goto finalize;

if (P4_Ok != P4_AddChoiceWithMembers(grammar, P4_PegRuleWhitespace, 4,
P4_CreateLiteral(" ", true),
P4_CreateLiteral("\t", true),
Expand Down
6 changes: 2 additions & 4 deletions peppapeg.h
Expand Up @@ -1697,13 +1697,11 @@ P4_Token* P4_GetSourceAst(P4_Source*);
*/
size_t P4_GetSourcePosition(P4_Source*);

typedef P4_String (*P4_KindToName)(P4_RuleID id);

/**
* @brief Print the token tree.
* @param grammar The grammar.
* @param stream The output stream.
* @param token The token.
* @param namefunc A function to convert id to a name.
*
* Example:
*
Expand All @@ -1718,7 +1716,7 @@ typedef P4_String (*P4_KindToName)(P4_RuleID id);
* P4_Token* root = P4_GetSourceAst(source);
* P4_JsonifySourceAst(stdout, root, MyIdToName);
*/
void P4_JsonifySourceAst(FILE* stream, P4_Token* token, P4_KindToName namefunc);
void P4_JsonifySourceAst(P4_Grammar* grammar, FILE* stream, P4_Token* token);

/**
* @brief Parse the source given a grammar.
Expand Down
10 changes: 2 additions & 8 deletions tests/test_peg.c
Expand Up @@ -8,7 +8,7 @@
TEST_ASSERT_EQUAL_MESSAGE((code), P4_Parse(grammar, source), "unexpected parse grammar return code"); \
P4_Token* root = P4_GetSourceAst(source); \
FILE *f = fopen("check.json","w"); \
P4_JsonifySourceAst(f, root, P4_StringifyPegGrammarRuleID); \
P4_JsonifySourceAst(grammar, f, root); \
fclose(f); \
P4_String s = read_file("check.json"); \
TEST_ASSERT_EQUAL_STRING((output), s); \
Expand Down Expand Up @@ -440,12 +440,6 @@ void test_eval_reference(void) {
ASSERT_EVAL_REFERENCE(P4_PegRuleReference, "CONST", SIZE_MAX);
}

P4_String test_grammar_rule_to_name(P4_RuleID id) {
static char name[5] = "00000";
sprintf(name, "R%lu", (unsigned long)id);
return name;
}

#define ASSERT_EVAL_GRAMMAR(peg_rules, entry_name, source_code, parse_code, ast) do { \
P4_Grammar* grammar = P4_LoadGrammar((peg_rules)); \
TEST_ASSERT_NOT_NULL_MESSAGE(grammar, "peg rule should be valid peg code."); \
Expand All @@ -457,7 +451,7 @@ P4_String test_grammar_rule_to_name(P4_RuleID id) {
"source code should be correctly parsed"); \
P4_Token* ast_token = P4_GetSourceAst(source); \
FILE *f = fopen("check.json","w"); \
P4_JsonifySourceAst(f, ast_token, test_grammar_rule_to_name); \
P4_JsonifySourceAst(grammar, f, ast_token); \
fclose(f); \
P4_String s = read_file("check.json"); TEST_ASSERT_EQUAL_STRING((ast), s); free(s); \
P4_DeleteSource(source); \
Expand Down

0 comments on commit 5f34929

Please sign in to comment.