Skip to content

Instantly share code, notes, and snippets.

@soasme
Last active February 17, 2021 19:38
Show Gist options
  • Save soasme/f31ea5f78420304a1b12b434a4a808e9 to your computer and use it in GitHub Desktop.
Save soasme/f31ea5f78420304a1b12b434a4a808e9 to your computer and use it in GitHub Desktop.
--------------------------------------------------------------------------------
Profile data file 'callgrind.out.10362' (creator: callgrind-3.16.0)
--------------------------------------------------------------------------------
I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 7341727
Trigger: Program termination
Profiled target: ./a.out (PID 10362, part 1)
Events recorded: Ir
Events shown: Ir
Event sort order: Ir
Thresholds: 99
Include dirs:
User annotated:
Auto-annotation: on
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
33,636,429 (100.0%) PROGRAM TOTALS
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
99,112,138,501 (294657.1%) peppapeg.c:P4_Match'2 [/app/a.out]
99,106,085,639 (294639.1%) peppapeg.c:P4_Expression_dispatch'2 [/app/a.out]
33,006,260,274 (98126.5%) peppapeg.c:P4_MatchChoice'2 [/app/a.out]
33,002,902,792 (98116.5%) peppapeg.c:P4_MatchSequence'2 [/app/a.out]
32,993,043,406 (98087.2%) peppapeg.c:P4_MatchReference'2 [/app/a.out]
75,662,592 (224.9%) peppapeg.c:P4_DeleteTokenChildren'2 [/app/a.out]
33,636,429 (100.0%) ???:0x0000000000001080 [/usr/lib64/ld-2.28.so]
33,530,007 (99.68%) ???:_start [/app/a.out]
33,529,995 (99.68%) ???:(below main) [/usr/lib64/libc-2.28.so]
33,527,965 (99.68%) /app/examples/json.c:main
33,527,965 (99.68%) examples/json.c:main [/app/a.out]
32,997,975 (98.10%) /app/peppapeg.c:P4_Parse
32,997,975 (98.10%) peppapeg.c:P4_Parse [/app/a.out]
32,997,625 (98.10%) peppapeg.c:P4_Match [/app/a.out]
32,996,195 (98.10%) peppapeg.c:P4_Expression_dispatch [/app/a.out]
32,996,172 (98.10%) peppapeg.c:P4_MatchSequence [/app/a.out]
32,992,905 (98.09%) peppapeg.c:P4_MatchReference [/app/a.out]
32,992,403 (98.09%) peppapeg.c:P4_MatchChoice [/app/a.out]
26,325,867 (78.27%) peppapeg.c:P4_MatchRepeat [/app/a.out]
18,443,545 (54.83%) peppapeg.c:P4_MatchSpacedExpressions [/app/a.out]
10,049,100 (29.88%) peppapeg.c:P4_MatchLiteral [/app/a.out]
8,401,018 (24.98%) peppapeg.c:P4_RaiseError [/app/a.out]
7,337,745 (21.81%) ???:free [/usr/lib64/ld-2.28.so]
7,150,621 (21.26%) ???:strdup [/usr/lib64/ld-2.28.so]
6,491,739 (19.30%) peppapeg.c:P4_RescueError [/app/a.out]
5,259,159 (15.64%) ???:_int_free [/usr/lib64/libc-2.28.so]
4,805,845 (14.29%) ???:malloc [/usr/lib64/ld-2.28.so]
3,452,695 (10.26%) ???:0x0000000004c4e760 [???]
1,929,020 ( 5.73%) ???:__strlen_avx2 [/usr/lib64/libc-2.28.so]
1,767,802 ( 5.26%) peppapeg.c:P4_PushFrame [/app/a.out]
1,509,032 ( 4.49%) ???:0x0000000004c4e820 [???]
1,143,902 ( 3.40%) ???:0x0000000004c4e880 [???]
1,141,047 ( 3.39%) peppapeg.c:P4_PopFrame [/app/a.out]
1,003,802 ( 2.98%) ???:__memcpy_avx_unaligned_erms [/usr/lib64/libc-2.28.so]
959,792 ( 2.85%) ???:_int_malloc [/usr/lib64/libc-2.28.so]
823,266 ( 2.45%) peppapeg.c:P4_DeleteToken [/app/a.out]
791,322 ( 2.35%) peppapeg.c:P4_GetPosition [/app/a.out]
526,680 ( 1.57%) peppapeg.c:cleanup_freep [/app/a.out]
440,200 ( 1.31%) peppapeg.c:P4_SetPosition [/app/a.out]
410,080 ( 1.22%) peppapeg.c:P4_RemainingText [/app/a.out]
297,087 ( 0.88%) ???:__memcmp_avx2_movbe [/usr/lib64/libc-2.28.so]
--------------------------------------------------------------------------------
-- Auto-annotated source: peppapeg.c
--------------------------------------------------------------------------------
Ir
-- line 42 ----------------------------------------
. # define NEED_SPACE(s) ((s)->frame_stack ? (s)->frame_stack->space : false)
. # define NO_ERROR(s) ((s)->err == P4_Ok)
. # define NO_MATCH(s) ((s)->err == P4_MatchError)
.
. # define autofree __attribute__ ((cleanup (cleanup_freep)))
.
. P4_PRIVATE(void)
. cleanup_freep (void *p)
20,032 ( 0.06%) {
10,016 ( 0.03%) void **pp = (void **) p;
20,032 ( 0.06%) if (*pp)
25,040 ( 0.07%) free (*pp);
436,536 ( 1.30%) => ???:free (5,008x)
15,024 ( 0.04%) }
.
. # define P4_AdoptToken(head, tail, list) do { \
. if ((list) != NULL) {\
. if ((head) == NULL) (head) = (list); \
. if ((tail) == NULL) (tail) = (list); \
. else (tail)->next = (list); \
. if ((tail) != NULL) {\
. while ((tail)->next != NULL) \
-- line 62 ----------------------------------------
-- line 138 ----------------------------------------
. *
. * > uint32_t c = 0x0
. * > P4_ReadRune("你好", &c)
. * 3
. * > printf("%p %d\n", c, c)
. * 0x4f60 20320
. */
. P4_PRIVATE(size_t)
4 ( 0.00%) P4_ReadRune(P4_String s, P4_Rune* c) {
2 ( 0.00%) *c = 0;
.
4 ( 0.00%) if ((s[0] & 0b10000000) == 0) { // 1 byte code point, ASCII
7 ( 0.00%) *c = (s[0] & 0b01111111);
2 ( 0.00%) return 1;
. } else if ((s[0] & 0b11100000) == 0b11000000) { // 2 byte code point
. *c = (s[0] & 0b00011111) << 6 | (s[1] & 0b00111111);
. return 2;
. } else if ((s[0] & 0b11110000) == 0b11100000) { // 3 byte code point
. *c = (s[0] & 0b00001111) << 12 | (s[1] & 0b00111111) << 6 | (s[2] & 0b00111111);
. return 3;
. } else if ((s[0] & 0b11111000) == 0b11110000) { // 4 byte code point
. *c = (s[0] & 0b00000111) << 18 | (s[1] & 0b00111111) << 12 | (s[2] & 0b00111111) << 6 | (s[3] & 0b00111111);
. return 4;
. } else {
. *c = 0x0;
. return 0;
. }
2 ( 0.00%) }
.
. /*
. * Compare case-insensitive string src v/s dest.
. *
. * Like strcmp, but works for a case insensitive UTF-8 string.
. */
. P4_PRIVATE(int)
. P4_CaseCmpInsensitive(P4_String src, P4_String dst, size_t len) {
-- line 173 ----------------------------------------
-- line 196 ----------------------------------------
. * Determine if the corresponding token to `e` should be ignored.
. *
. * 1. Intermediate expr.
. * 2. Bareness expr.
. * 3. Hollowed expr.
. *
. */
. P4_PRIVATE(bool)
32,000 ( 0.10%) P4_NeedLift(P4_Source* s, P4_Expression* e) {
74,000 ( 0.22%) return !IS_RULE(e) || IS_LIFTED(e) || NEED_SILENT(s);
16,000 ( 0.05%) }
.
.
. /*
. * Raise an error.
. *
. * Set err and errmsg to state.
. */
. P4_PRIVATE(void)
234,054 ( 0.70%) P4_RaiseError(P4_Source* s, P4_Error err, P4_String errmsg) {
117,027 ( 0.35%) s->err = err;
.
156,036 ( 0.46%) if (s->errmsg != NULL)
195,040 ( 0.58%) free(s->errmsg);
3,237,664 ( 9.63%) => ???:free (39,008x)
.
273,063 ( 0.81%) s->errmsg = strdup(errmsg);
4,071,107 (12.10%) => ???:strdup (39,009x)
117,027 ( 0.35%) }
.
.
. /*
. * Clear an error.
. *
. * It allows the parser to keep parsing the text.
. */
. P4_PRIVATE(void)
124,024 ( 0.37%) P4_RescueError(P4_Source* s) {
62,012 ( 0.18%) s->err = P4_Ok;
124,024 ( 0.37%) if (s->errmsg != NULL) {
155,034 ( 0.46%) free(s->errmsg);
2,615,308 ( 7.78%) => ???:free (31,005x)
677 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
62,012 ( 0.18%) s->errmsg = NULL;
186,036 ( 0.55%) s->errmsg = strdup("");
3,069,594 ( 9.13%) => ???:strdup (31,006x)
. }
93,018 ( 0.28%) }
.
.
. /*
. * Initialize a token.
. */
. P4_Token*
. P4_CreateToken (const P4_String str,
. size_t slice_i,
. size_t slice_j,
7,000 ( 0.02%) P4_Expression* expr) {
. P4_Token* token;
.
6,000 ( 0.02%) if ((token=malloc(sizeof(P4_Token))) == NULL)
45,000 ( 0.13%) => ???:malloc (1,000x)
. return NULL;
.
3,000 ( 0.01%) token->text = str;
3,000 ( 0.01%) token->slice.i = slice_i;
3,000 ( 0.01%) token->slice.j = slice_j;
3,000 ( 0.01%) token->expr = expr;
2,000 ( 0.01%) token->next = NULL;
2,000 ( 0.01%) token->head = NULL;
2,000 ( 0.01%) token->tail = NULL;
.
1,000 ( 0.00%) return token;
2,000 ( 0.01%) }
.
.
. /*
. * Free the token.
. *
. * Danger: if free the token only without cleaning next & head & tail,
. * they're in risk of being dangled.
. */
. P4_PRIVATE(void)
4,000 ( 0.01%) P4_DeleteTokenNode(P4_Token* token) {
2,000 ( 0.01%) assert(token != NULL);
2,000 ( 0.01%) if (token)
4,000 ( 0.01%) free(token);
103,893 ( 0.31%) => ???:free (1,000x)
3,000 ( 0.01%) }
.
.
. /*
. * Free all of the children tokens of the token.
. */
. P4_PRIVATE(void)
3,996 ( 0.01%) P4_DeleteTokenChildren(P4_Token* token) {
1,998 ( 0.01%) assert(token != NULL);
2,997 ( 0.01%) P4_Token* child = token->head;
999 ( 0.00%) P4_Token* tmp = NULL;
.
4,995 ( 0.01%) while (child) {
2,997 ( 0.01%) tmp = child->next;
3,996 ( 0.01%) if (child->head)
2,994 ( 0.01%) P4_DeleteTokenChildren(child);
151,586 ( 0.45%) => peppapeg.c:P4_DeleteTokenChildren'2 (1x)
2,997 ( 0.01%) P4_DeleteTokenNode(child);
119 ( 0.00%) => peppapeg.c:P4_DeleteTokenNode (1x)
1,998 ( 0.01%) child = tmp;
. }
2,997 ( 0.01%) }
.
.
. /*
. * Free the token list and all the children nodes of each
. * node in the token list.
. */
. P4_PUBLIC(void)
244,144 ( 0.73%) P4_DeleteToken(P4_Token* token) {
61,036 ( 0.18%) P4_Token* tmp = NULL;
183,110 ( 0.54%) while (token) {
3 ( 0.00%) tmp = token->next;
3 ( 0.00%) P4_DeleteTokenChildren(token);
151,738 ( 0.45%) => peppapeg.c:P4_DeleteTokenChildren (1x)
3 ( 0.00%) P4_DeleteTokenNode(token);
119 ( 0.00%) => peppapeg.c:P4_DeleteTokenNode (1x)
2 ( 0.00%) token = tmp;
. }
183,108 ( 0.54%) }
.
. /*
. * Push e into s->frame_stack.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.15%) P4_PushFrame(P4_Source* s, P4_Expression* e) {
70,063 ( 0.21%) if (s->frame_stack_size > (s->grammar->depth)) {
. return P4_StackError;
. }
.
40,036 ( 0.12%) P4_Frame* frame = malloc(sizeof(P4_Frame));
820,960 ( 2.44%) => ???:malloc (10,009x)
.
20,018 ( 0.06%) if (frame == NULL) {
. return P4_MemoryError;
. }
.
30,027 ( 0.09%) P4_Frame* top = s->frame_stack;
.
. /* Set silent */
20,018 ( 0.06%) frame->silent = false;
.
50,045 ( 0.15%) if (!IS_SCOPED(e)) {
20,018 ( 0.06%) if (
60,048 ( 0.18%) (top && IS_SQUASHED(top->expr))
60,050 ( 0.18%) || (top && top->silent)
. )
. frame->silent = true;
. }
.
. /* Set space */
20,018 ( 0.06%) frame->space = false;
.
60,054 ( 0.18%) if (P4_GetWhitespaces(s->grammar) != NULL
141,052 ( 0.42%) => peppapeg.c:P4_GetWhitespaces (10,009x)
50,045 ( 0.15%) && !s->whitespacing) {
25,050 ( 0.07%) if (IS_SCOPED(e)) {
. frame->space = true;
10,020 ( 0.03%) } else if (top) {
25,045 ( 0.07%) if (!IS_TIGHT(e)) {
25,030 ( 0.07%) frame->space = top->space;
. }
5 ( 0.00%) } else if (!IS_TIGHT(e)) {
2 ( 0.00%) frame->space = true;
. }
. }
.
. /* Set expr & next */
30,027 ( 0.09%) frame->expr = e;
30,027 ( 0.09%) frame->next = top;
.
. /* Push stack */
50,045 ( 0.15%) s->frame_stack_size++;
30,027 ( 0.09%) s->frame_stack = frame;
.
10,009 ( 0.03%) return P4_Ok;
20,018 ( 0.06%) }
.
.
. /*
. * Pop top from s->frames.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.15%) P4_PopFrame(P4_Source* s, P4_Frame* f) {
40,036 ( 0.12%) if (s->frame_stack == NULL)
. return P4_MemoryError;
.
30,027 ( 0.09%) P4_Frame* oldtop = s->frame_stack;
50,045 ( 0.15%) s->frame_stack = s->frame_stack->next;
60,054 ( 0.18%) if (oldtop) free(oldtop);
830,768 ( 2.47%) => ???:free (10,009x)
50,045 ( 0.15%) s->frame_stack_size--;
.
10,009 ( 0.03%) return P4_Ok;
20,018 ( 0.06%) }
.
.
. P4_PRIVATE(P4_Token*)
165,030 ( 0.49%) P4_MatchLiteral(P4_Source* s, P4_Expression* e) {
132,024 ( 0.39%) assert(NO_ERROR(s));
.
132,024 ( 0.39%) P4_String str = P4_RemainingText(s);
330,060 ( 0.98%) => peppapeg.c:P4_RemainingText (33,006x)
.
. # define EOT(s) (*(s) == 0x0)
.
132,024 ( 0.39%) if (EOT(str)) {
. P4_RaiseError(s, P4_MatchError, "eof");
. return NULL;
. }
.
198,040 ( 0.59%) size_t len = strlen(e->literal);
560,088 ( 1.67%) => ???:__strlen_avx2 (33,005x)
633 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
.
132,024 ( 0.39%) P4_MarkPosition(s, startpos);
231,042 ( 0.69%) => peppapeg.c:P4_GetPosition (33,006x)
165,030 ( 0.49%) if ((!e->sensitive && P4_CaseCmpInsensitive(e->literal, str, len) != 0)
462,088 ( 1.37%) || (e->sensitive && memcmp(e->literal, str, len) != 0)) {
297,087 ( 0.88%) => ???:__memcmp_avx2_movbe (33,005x)
627 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
155,025 ( 0.46%) P4_RaiseError(s, P4_MatchError, "expect literal");
6,728,182 (20.00%) => peppapeg.c:P4_RaiseError (31,005x)
62,010 ( 0.18%) return NULL;
. }
14,007 ( 0.04%) P4_SetPosition(s, startpos+len);
20,010 ( 0.06%) => peppapeg.c:P4_SetPosition (2,001x)
8,004 ( 0.02%) P4_MarkPosition(s, endpos);
14,007 ( 0.04%) => peppapeg.c:P4_GetPosition (2,001x)
.
14,007 ( 0.04%) if (P4_NeedLift(s, e))
26,013 ( 0.08%) => peppapeg.c:P4_NeedLift (2,001x)
4,002 ( 0.01%) return NULL;
.
. P4_Token* result = NULL;
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "");
. return NULL;
. }
.
. return result;
66,012 ( 0.20%) }
.
. P4_PRIVATE(P4_Token*)
5 ( 0.00%) P4_MatchRange(P4_Source* s, P4_Expression* e) {
4 ( 0.00%) assert(NO_ERROR(s));
.
4 ( 0.00%) P4_String str = P4_RemainingText(s);
10 ( 0.00%) => peppapeg.c:P4_RemainingText (1x)
4 ( 0.00%) if (*str == '\0') {
. P4_RaiseError(s, P4_MatchError, "eof");
. return NULL;
. }
.
4 ( 0.00%) P4_MarkPosition(s, startpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
1 ( 0.00%) uint32_t rune = 0x0;
6 ( 0.00%) size_t size = P4_ReadRune(str, &rune);
21 ( 0.00%) => peppapeg.c:P4_ReadRune (1x)
.
. #define IN_RANGE(e, c) ((c)>=(e)->range[0] && (c)<=(e)->range[1])
.
10 ( 0.00%) if (!IN_RANGE(e, rune)) {
5 ( 0.00%) P4_RaiseError(s, P4_MatchError, "not in range");
209 ( 0.00%) => peppapeg.c:P4_RaiseError (1x)
2 ( 0.00%) return NULL;
. }
.
. P4_SetPosition(s, startpos+size);
. P4_MarkPosition(s, endpos);
.
. if (P4_NeedLift(s, e))
. return NULL;
.
. P4_Token* result = NULL;
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. return result;
2 ( 0.00%) }
.
. P4_PRIVATE(P4_Expression*)
70,020 ( 0.21%) P4_GetReference(P4_Source* s, P4_Expression* e) {
56,016 ( 0.17%) if (e->ref_expr != NULL)
42,003 ( 0.12%) return e->ref_expr;
.
12 ( 0.00%) if (e->ref_id != 0) {
30 ( 0.00%) e->ref_expr = P4_GetGrammarRule(s->grammar, e->ref_id);
695 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (3x)
. }
.
6 ( 0.00%) return e->ref_expr;
28,008 ( 0.08%) }
.
. P4_PRIVATE(P4_Token*)
50,040 ( 0.15%) P4_MatchReference(P4_Source* s, P4_Expression* e) {
40,032 ( 0.12%) assert(NO_ERROR(s));
.
40,068 ( 0.12%) if (e->ref_expr == NULL && e->ref_id != 0) {
90 ( 0.00%) e->ref_expr = P4_GetGrammarRule(s->grammar, e->ref_id);
552 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (2x)
. }
.
40,032 ( 0.12%) if (e->ref_expr == NULL) {
. P4_RaiseError(s, P4_NameError, "");
. return NULL;
. }
.
40,032 ( 0.12%) P4_MarkPosition(s, startpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
70,056 ( 0.21%) P4_Token* reftok = P4_Match(s, e->ref_expr);
32,992,089 (98.08%) => peppapeg.c:P4_Match'2 (4x)
40,032 ( 0.12%) P4_MarkPosition(s, endpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
.
. // Ref matching is terminated when error occurred.
40,032 ( 0.12%) if (!NO_ERROR(s))
16,018 ( 0.05%) return NULL;
.
. // The referenced token is returned when silenced.
13,993 ( 0.04%) if (P4_NeedLift(s, e))
13 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
3,998 ( 0.01%) return reftok;
.
. // A single reference expr can be a rule: `e = { ref }`
. // In such a case, a token for `e` with single child `ref` is created.
. //
. P4_Token* result = NULL;
.
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. P4_AdoptToken(result->head, result->tail, reftok);
. return result;
20,016 ( 0.06%) }
.
. P4_PRIVATE(P4_Token*)
30,048 ( 0.09%) P4_MatchSequence(P4_Source* s, P4_Expression* e) {
20,032 ( 0.06%) assert(NO_ERROR(s));
.
5,008 ( 0.01%) P4_Expression *member = NULL;
5,008 ( 0.01%) P4_Token *head = NULL,
5,008 ( 0.01%) *tail = NULL,
5,008 ( 0.01%) *tok = NULL,
5,008 ( 0.01%) *whitespace = NULL;
.
55,088 ( 0.16%) autofree P4_Slice* backrefs = malloc(sizeof(P4_Slice) * e->count);
230 ( 0.00%) => ???:malloc (1x)
101 ( 0.00%) => peppapeg.c:cleanup_freep (1x)
15,024 ( 0.04%) if (backrefs == NULL) {
. P4_RaiseError(s, P4_MemoryError, "OOM");
. return NULL;
. }
.
65,101 ( 0.19%) bool need_space = NEED_SPACE(s);
.
20,032 ( 0.06%) P4_MarkPosition(s, startpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
89,071 ( 0.26%) for (int i = 0; i < e->count; i++) {
80,072 ( 0.24%) member = e->members[i];
.
. // Optional `WHITESPACE` and `COMMENT` are inserted between every member.
40,028 ( 0.12%) if (need_space && i > 0) {
25,000 ( 0.07%) whitespace = P4_MatchSpacedExpressions(s, NULL);
3,940 ( 0.01%) => peppapeg.c:P4_MatchSpacedExpressions (2x)
20,000 ( 0.06%) if (!NO_ERROR(s)) goto finalize;
10,000 ( 0.03%) P4_AdoptToken(head, tail, whitespace);
. }
.
40,036 ( 0.12%) P4_MarkPosition(s, member_startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
.
40,036 ( 0.12%) if (member->kind == P4_BackReference) {
. tok = P4_MatchBackReference(s, e, backrefs, member->backref_index);
. if (!NO_ERROR(s)) goto finalize;
. } else {
60,054 ( 0.18%) tok = P4_Match(s, member);
32,991,564 (98.08%) => peppapeg.c:P4_Match'2 (3x)
. }
.
. // If any of the sequence members fails, the entire sequence fails.
. // Puke the eaten text and free all created tokens.
40,036 ( 0.12%) if (!NO_ERROR(s)) {
3,008 ( 0.01%) goto finalize;
. }
.
45,986 ( 0.14%) P4_AdoptToken(head, tail, tok);
49,007 ( 0.15%) backrefs[i].i = member_startpos;
63,009 ( 0.19%) backrefs[i].j = P4_GetPosition(s);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
. }
.
14,000 ( 0.04%) if (P4_NeedLift(s, e))
18 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
4,000 ( 0.01%) return head;
.
. P4_Token* ret = P4_CreateToken (s->content, startpos, P4_GetPosition(s), e);
. if (ret == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. ret->head = head;
. ret->tail = tail;
. return ret;
.
. finalize:
15,040 ( 0.04%) P4_SetPosition(s, startpos);
30,080 ( 0.09%) => peppapeg.c:P4_SetPosition (3,008x)
9,024 ( 0.03%) P4_DeleteToken(head);
33,088 ( 0.10%) => peppapeg.c:P4_DeleteToken (3,008x)
3,008 ( 0.01%) return NULL;
20,032 ( 0.06%) }
.
. P4_PRIVATE(P4_Token*)
50,015 ( 0.15%) P4_MatchChoice(P4_Source* s, P4_Expression* e) {
10,003 ( 0.03%) P4_Token* tok = NULL;
10,003 ( 0.03%) P4_Expression* member = NULL;
.
. // A member is attempted if previous yields no match.
. // The oneof match matches successfully immediately if any match passes.
40,012 ( 0.12%) P4_MarkPosition(s, startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
241,073 ( 0.72%) for (int i = 0; i < e->count; i++) {
264,080 ( 0.79%) member = e->members[i];
198,060 ( 0.59%) tok = P4_Match(s, member);
32,989,276 (98.08%) => peppapeg.c:P4_Match'2 (10x)
134,040 ( 0.40%) if (NO_ERROR(s)) break;
124,040 ( 0.37%) if (NO_MATCH(s)) {
. // retry until the last one.
217,070 ( 0.65%) if (i < e->count-1) {
69,021 ( 0.21%) P4_RescueError(s);
2,054 ( 0.01%) => peppapeg.c:P4_RescueError (7x)
138,042 ( 0.41%) P4_SetPosition(s, startpos);
70 ( 0.00%) => peppapeg.c:P4_SetPosition (7x)
. // fail when the last one is a no-match.
. } else {
40,015 ( 0.12%) P4_RaiseError(s, P4_MatchError, "no match");
418 ( 0.00%) => peppapeg.c:P4_RaiseError (2x)
8,003 ( 0.02%) goto finalize;
. }
. }
. }
8,000 ( 0.02%) P4_MarkPosition(s, endpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
14,000 ( 0.04%) if (P4_NeedLift(s, e))
13 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
2,000 ( 0.01%) return tok;
.
8,000 ( 0.02%) P4_Token* oneof = P4_CreateToken (s->content, startpos, endpos, e);
79,000 ( 0.23%) => peppapeg.c:P4_CreateToken (1,000x)
2,000 ( 0.01%) if (oneof == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. goto finalize;
. }
.
26,975 ( 0.08%) P4_AdoptToken(oneof->head, oneof->tail, tok);
2,000 ( 0.01%) return oneof;
.
. finalize:
40,015 ( 0.12%) P4_SetPosition(s, startpos);
20 ( 0.00%) => peppapeg.c:P4_SetPosition (2x)
32,012 ( 0.10%) free(tok);
24 ( 0.00%) => ???:free (2x)
8,003 ( 0.02%) return NULL;
20,006 ( 0.06%) }
.
. /*
. * Repetition matcher function.
. *
. * Returns a token in a greedy fashion.
. *
. * There are seven repetition mode: zeroormore, zerooronce,
. */
. P4_PRIVATE(P4_Token*)
40,005 ( 0.12%) P4_MatchRepeat(P4_Source* s, P4_Expression* e) {
24,003 ( 0.07%) size_t min = -1, max = -1, repeated = 0;
.
32,004 ( 0.10%) assert(e->repeat_min != min || e->repeat_max != max); // need at least one of min/max.
32,004 ( 0.10%) assert(e->repeat_expr != NULL); // need repeat expression.
32,004 ( 0.10%) assert(NO_ERROR(s));
.
. # define IS_REF(e) ((e)->kind == P4_Reference)
. # define IS_PROGRESSING(k) ((k)==P4_Positive \
. || (k)==P4_Negative)
.
. // when expression inside repetition is non-progressing, it repeats indefinitely.
. // we know negative/positive definitely not progressing,
. // and so does a reference to a negative/positive rule.
. // Question: we may never list all the cases in this way. How to deal with it better?
96,012 ( 0.29%) if (IS_PROGRESSING(e->repeat_expr->kind) ||
24,003 ( 0.07%) (IS_REF(e->repeat_expr)
126,036 ( 0.37%) && IS_PROGRESSING(P4_GetReference(s, e->repeat_expr)->kind))) {
196,790 ( 0.59%) => peppapeg.c:P4_GetReference (14,004x)
. P4_RaiseError(s, P4_AdvanceError, "no progressing in repetition");
. return NULL;
. }
.
24,003 ( 0.07%) min = e->repeat_min;
24,003 ( 0.07%) max = e->repeat_max;
.
104,012 ( 0.31%) bool need_space = NEED_SPACE(s);
32,004 ( 0.10%) P4_Position startpos = P4_GetPosition(s);
56,007 ( 0.17%) => peppapeg.c:P4_GetPosition (8,001x)
32,004 ( 0.10%) P4_Token *head = NULL, *tail = NULL, *tok = NULL, *whitespace = NULL;
.
56,007 ( 0.17%) while (*P4_RemainingText(s) != '\0') {
80,010 ( 0.24%) => peppapeg.c:P4_RemainingText (8,001x)
31,996 ( 0.10%) P4_MarkPosition(s, before_implicit);
55,993 ( 0.17%) => peppapeg.c:P4_GetPosition (7,999x)
.
. // SPACED rule expressions are inserted between every repetition.
31,994 ( 0.10%) if (need_space && repeated > 0 ) {
. whitespace = P4_MatchSpacedExpressions(s, NULL);
. if (!NO_ERROR(s)) goto finalize;
. P4_AdoptToken(head, tail, whitespace);
. }
.
55,993 ( 0.17%) tok = P4_Match(s, e->repeat_expr);
22,833,257 (67.88%) => peppapeg.c:P4_Match'2 (7,999x)
.
31,996 ( 0.10%) if (NO_MATCH(s)) {
15,998 ( 0.05%) assert(tok == NULL);
.
. // considering the case: MATCH WHITESPACE MATCH WHITESPACE NO_MATCH
31,994 ( 0.10%) if (need_space && repeated > 0)// ^ ^ we are here
. P4_SetPosition(s, before_implicit); // ^ puke extra whitespace
. // ^ now we are here
.
39,995 ( 0.12%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. } else { // sufficient repetitions.
23,997 ( 0.07%) P4_RescueError(s);
1,705,685 ( 5.07%) => peppapeg.c:P4_RescueError (7,999x)
7,999 ( 0.02%) break;
. }
. }
.
. if (!NO_ERROR(s))
. goto finalize;
.
. if (P4_GetPosition(s) == before_implicit) {
. P4_RaiseError(s, P4_AdvanceError, "Repeated expression consumes no input");
-- line 694 ----------------------------------------
-- line 701 ----------------------------------------
. if (max != -1 && repeated == max) { // enough attempts
. P4_RescueError(s);
. break;
. }
.
. }
.
. // there should be no error when repetition is successful.
32,004 ( 0.10%) assert(NO_ERROR(s));
.
. // fails when attempts are excessive, e.g. repeated > max.
16,005 ( 0.05%) if (max != -1 && repeated > max) {
. P4_RaiseError(s, P4_MatchError, "excessive repetitions");
. goto finalize;
. }
.
40,005 ( 0.12%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. }
.
40,005 ( 0.12%) if (P4_GetPosition(s) == startpos) // success but no token is produced.
56,007 ( 0.17%) => peppapeg.c:P4_GetPosition (8,001x)
8,001 ( 0.02%) goto finalize;
.
.
. if (P4_NeedLift(s, e))
. return head;
.
. P4_Token* repetition = P4_CreateToken (s->content, startpos, P4_GetPosition(s), e);
. if (repetition == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
-- line 731 ----------------------------------------
-- line 733 ----------------------------------------
. }
.
. P4_AdoptToken(repetition->head, repetition->tail, head);
. return repetition;
.
. // cleanup before returning NULL.
. // tokens between head..tail should be freed.
. finalize:
40,005 ( 0.12%) P4_SetPosition(s, startpos);
80,010 ( 0.24%) => peppapeg.c:P4_SetPosition (8,001x)
24,003 ( 0.07%) P4_DeleteToken(head);
88,011 ( 0.26%) => peppapeg.c:P4_DeleteToken (8,001x)
8,001 ( 0.02%) return NULL;
16,002 ( 0.05%) }
.
. P4_PRIVATE(P4_Token*)
. P4_MatchPositive(P4_Source* s, P4_Expression* e) {
. assert(NO_ERROR(s) && e->ref_expr != NULL);
.
. P4_MarkPosition(s, startpos);
.
. P4_Token* token = P4_Match(s, e->ref_expr);
-- line 752 ----------------------------------------
-- line 772 ----------------------------------------
. } else if (s->err == P4_MatchError) {
. P4_RescueError(s);
. }
.
. return NULL;
. }
.
. P4_Token*
330,135 ( 0.98%) P4_Expression_dispatch(P4_Source* s, P4_Expression* e) {
66,027 ( 0.20%) P4_Token* result = NULL;
.
462,189 ( 1.37%) switch (e->kind) {
. case P4_Literal:
198,036 ( 0.59%) result = P4_MatchLiteral(s, e);
10,049,100 (29.88%) => peppapeg.c:P4_MatchLiteral (33,006x)
33,006 ( 0.10%) break;
. case P4_Range:
6 ( 0.00%) result = P4_MatchRange(s, e);
294 ( 0.00%) => peppapeg.c:P4_MatchRange (1x)
1 ( 0.00%) break;
. case P4_Reference:
60,048 ( 0.18%) result = P4_MatchReference(s, e);
32,993,043,406 (98087.2%) => peppapeg.c:P4_MatchReference'2 (10,004x)
32,992,905 (98.09%) => peppapeg.c:P4_MatchReference (4x)
10,008 ( 0.03%) break;
. case P4_Sequence:
30,048 ( 0.09%) result = P4_MatchSequence(s, e);
32,996,172 (98.10%) => peppapeg.c:P4_MatchSequence (1x)
5,008 ( 0.01%) break;
. case P4_Choice:
60,018 ( 0.18%) result = P4_MatchChoice(s, e);
33,006,260,274 (98126.5%) => peppapeg.c:P4_MatchChoice'2 (10,000x)
32,992,403 (98.09%) => peppapeg.c:P4_MatchChoice (3x)
10,003 ( 0.03%) break;
. case P4_Positive:
. result = P4_MatchPositive(s, e);
. break;
. case P4_Negative:
. result = P4_MatchNegative(s, e);
. break;
. case P4_Repeat:
48,006 ( 0.14%) result = P4_MatchRepeat(s, e);
26,325,867 (78.27%) => peppapeg.c:P4_MatchRepeat (8,001x)
8,001 ( 0.02%) break;
. case P4_BackReference:
. P4_RaiseError(s, P4_ValueError, "BackReference only works in Sequence.");
. result = NULL;
. break;
. default:
. P4_RaiseError(s, P4_ValueError, "no such kind");
. result = NULL;
. break;
. }
.
66,027 ( 0.20%) return result;
132,054 ( 0.39%) }
.
. /*
. * The match function updates the state given an expression.
. *
. * It returns a token linked list, NULL if no token is generated.
. * State pos will advance if needed.
. * Not-advancing pos / NULL returning token list do not indicate a failed match.
. * It fails when state err/errmsg are set.
. * It propagate the failed match up to the top level.
. */
. P4_Token*
330,135 ( 0.98%) P4_Match(P4_Source* s, P4_Expression* e) {
132,054 ( 0.39%) assert(e != NULL);
.
264,108 ( 0.79%) if (s->err != P4_Ok) {
. return NULL;
. }
.
66,027 ( 0.20%) P4_Error err = P4_Ok;
66,027 ( 0.20%) P4_Token* result = NULL;
.
344,180 ( 1.02%) if (IS_RULE(e) && (err = P4_PushFrame(s, e)) != P4_Ok) {
1,246 ( 0.00%) => peppapeg.c:P4_PushFrame (1x)
. P4_RaiseError(s, err, "failed to push frame");
. return NULL;
. }
.
396,162 ( 1.18%) result = P4_Expression_dispatch(s, e);
32,996,195 (98.10%) => peppapeg.c:P4_Expression_dispatch (1x)
.
334,171 ( 0.99%) if (IS_RULE(e) && (err = P4_PopFrame(s, NULL)) != P4_Ok) {
135 ( 0.00%) => peppapeg.c:P4_PopFrame (1x)
. P4_RaiseError(s, err, "failed to pop frame");
. P4_DeleteToken(result);
. return NULL;
. }
.
264,108 ( 0.79%) if (s->err != P4_Ok) {
150,078 ( 0.45%) P4_DeleteToken(result);
550,286 ( 1.64%) => peppapeg.c:P4_DeleteToken (50,026x)
100,052 ( 0.30%) return NULL;
. }
.
16,001 ( 0.05%) return result;
132,054 ( 0.39%) }
.
. P4_Token*
. P4_Match_any(P4_Source* s, P4_Expression* e) {
. P4_String str = P4_RemainingText(s);
.
. # define UTF8_CHARLEN(b) (( 0xe5000000 >> (( (b) >> 3 ) & 0x1e )) & 3 ) + 1
.
. P4_MarkPosition(s, startpos);
. size_t len = UTF8_CHARLEN(*str);
. P4_SetPosition(s, startpos+len);
.
. return NULL;
. }
.
. P4_PRIVATE(P4_Token*)
25,000 ( 0.07%) P4_MatchSpacedExpressions(P4_Source* s, P4_Expression* e) {
. // implicit whitespace is guaranteed to be an unnamed rule.
. // state flag is guaranteed to be none.
20,000 ( 0.06%) assert(NO_ERROR(s));
.
20,000 ( 0.06%) if (s->grammar == NULL)
. return NULL;
.
25,000 ( 0.07%) P4_Expression* implicit_whitespace = P4_GetWhitespaces(s->grammar);
70,000 ( 0.21%) => peppapeg.c:P4_GetWhitespaces (5,000x)
10,000 ( 0.03%) assert(implicit_whitespace != NULL);
.
. // (1) Temporarily set implicit whitespace to empty.
10,000 ( 0.03%) s->whitespacing = true;
.
. // (2) Perform implicit whitespace checks.
. // We won't do implicit whitespace inside an implicit whitespace expr.
30,000 ( 0.09%) P4_Token* result = P4_Match(s, implicit_whitespace);
18,188,545 (54.07%) => peppapeg.c:P4_Match'2 (5,000x)
20,000 ( 0.06%) if (NO_MATCH(s))
. P4_RescueError(s);
.
. // (3) Set implicit whitespace back.
10,000 ( 0.03%) s->whitespacing = false;
.
5,000 ( 0.01%) return result;
10,000 ( 0.03%) }
.
. P4_PRIVATE(P4_Token*)
. P4_MatchBackReference(P4_Source* s, P4_Expression* e, P4_Slice* backrefs, size_t index) {
. if (backrefs == NULL) {
. P4_RaiseError(s, P4_NullError, "");
. return NULL;
. }
.
-- line 908 ----------------------------------------
-- line 1001 ----------------------------------------
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->kind = P4_Numeric;
. expr->num = num;
. return expr;
. }
. */
.
. P4_PUBLIC(P4_Expression*)
210 ( 0.00%) P4_CreateLiteral(const P4_String literal, bool sensitive) {
140 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
8,050 ( 0.02%) => ???:malloc (35x)
70 ( 0.00%) expr->id = 0;
70 ( 0.00%) expr->kind = P4_Literal;
70 ( 0.00%) expr->flag = 0;
249 ( 0.00%) expr->literal = strdup(literal);
9,742 ( 0.03%) => ???:strdup (34x)
942 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
105 ( 0.00%) expr->sensitive = sensitive;
35 ( 0.00%) return expr;
70 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
45 ( 0.00%) P4_CreateRange(P4_Rune lower, P4_Rune upper) {
36 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
2,070 ( 0.01%) => ???:malloc (9x)
18 ( 0.00%) expr->id = 0;
18 ( 0.00%) expr->kind = P4_Range;
18 ( 0.00%) expr->flag = 0;
27 ( 0.00%) expr->range[0] = lower;
27 ( 0.00%) expr->range[1] = upper;
9 ( 0.00%) return expr;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
96 ( 0.00%) P4_CreateReference(P4_RuleID id) {
96 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
5,520 ( 0.02%) => ???:malloc (24x)
48 ( 0.00%) expr->id = 0;
48 ( 0.00%) expr->kind = P4_Reference;
48 ( 0.00%) expr->flag = 0;
72 ( 0.00%) expr->ref_id = id;
48 ( 0.00%) expr->ref_expr = NULL;
24 ( 0.00%) return expr;
48 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreatePositive(P4_Expression* refexpr) {
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->id = 0;
. expr->kind = P4_Positive;
. expr->flag = 0;
. expr->ref_expr = refexpr;
-- line 1047 ----------------------------------------
-- line 1054 ----------------------------------------
. expr->id = 0;
. expr->kind = P4_Negative;
. expr->flag = 0;
. expr->ref_expr = refexpr;
. return expr;
. }
.
. P4_PRIVATE(P4_Expression*)
96 ( 0.00%) P4_CreateContainer(size_t count) {
96 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
5,520 ( 0.02%) => ???:malloc (24x)
48 ( 0.00%) expr->id = 0;
48 ( 0.00%) expr->flag = 0;
72 ( 0.00%) expr->count = count;
192 ( 0.00%) expr->members = malloc(sizeof(P4_Expression*) * count);
5,520 ( 0.02%) => ???:malloc (24x)
24 ( 0.00%) return expr;
48 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
60 ( 0.00%) P4_CreateSequence(size_t count) {
60 ( 0.00%) P4_Expression* expr = P4_CreateContainer(count);
7,290 ( 0.02%) => peppapeg.c:P4_CreateContainer (15x)
.
30 ( 0.00%) if (expr == NULL)
. return NULL;
.
30 ( 0.00%) expr->kind = P4_Sequence;
.
15 ( 0.00%) return expr;
30 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
36 ( 0.00%) P4_CreateChoice(size_t count) {
36 ( 0.00%) P4_Expression* expr = P4_CreateContainer(count);
4,374 ( 0.01%) => peppapeg.c:P4_CreateContainer (9x)
.
18 ( 0.00%) if (expr == NULL)
. return NULL;
.
18 ( 0.00%) expr->kind = P4_Choice;
.
9 ( 0.00%) return expr;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
77 ( 0.00%) P4_CreateSequenceWithMembers(size_t count, ...) {
28 ( 0.00%) P4_Expression* expr = P4_CreateSequence(count);
3,507 ( 0.01%) => peppapeg.c:P4_CreateSequence (7x)
.
14 ( 0.00%) if (expr == NULL)
. return NULL;
.
. va_list members;
42 ( 0.00%) va_start (members, count);
.
132 ( 0.00%) for (int i = 0; i < count; i++) {
342 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
162 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
14 ( 0.00%) return expr;
.
. finalize:
. P4_DeleteExpression(expr);
. return NULL;
14 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
55 ( 0.00%) P4_CreateChoiceWithMembers(size_t count, ...) {
20 ( 0.00%) P4_Expression* expr = P4_CreateChoice(count);
2,505 ( 0.01%) => peppapeg.c:P4_CreateChoice (5x)
.
10 ( 0.00%) if (expr == NULL)
. return NULL;
.
. va_list members;
30 ( 0.00%) va_start (members, count);
.
150 ( 0.00%) for (int i = 0; i < count; i++) {
426 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
216 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
10 ( 0.00%) return expr;
.
. finalize:
. P4_DeleteExpression(expr);
. return NULL;
10 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
84 ( 0.00%) P4_CreateRepeatMinMax(P4_Expression* repeat, size_t min, size_t max) {
56 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
3,220 ( 0.01%) => ???:malloc (14x)
28 ( 0.00%) expr->id = 0;
28 ( 0.00%) expr->flag = 0;
28 ( 0.00%) expr->kind = P4_Repeat;
42 ( 0.00%) expr->repeat_expr = repeat;
42 ( 0.00%) expr->repeat_min = min;
42 ( 0.00%) expr->repeat_max = max;
14 ( 0.00%) return expr;
28 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateRepeatMin(P4_Expression* repeat, size_t min) {
. return P4_CreateRepeatMinMax(repeat, min, -1);
. }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateRepeatMax(P4_Expression* repeat, size_t max) {
. return P4_CreateRepeatMinMax(repeat, -1, max);
. }
.
. P4_PUBLIC(P4_Expression*)
5 ( 0.00%) P4_CreateRepeatExact(P4_Expression* repeat, size_t minmax) {
6 ( 0.00%) return P4_CreateRepeatMinMax(repeat, minmax, minmax);
258 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (1x)
2 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
16 ( 0.00%) P4_CreateZeroOrOnce(P4_Expression* repeat) {
20 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 0, 1);
1,032 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (4x)
8 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
28 ( 0.00%) P4_CreateZeroOrMore(P4_Expression* repeat) {
35 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 0, -1);
1,806 ( 0.01%) => peppapeg.c:P4_CreateRepeatMinMax (7x)
14 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
8 ( 0.00%) P4_CreateOnceOrMore(P4_Expression* repeat) {
10 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 1, -1);
516 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (2x)
4 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateBackReference(size_t index) {
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->id = 0;
. expr->kind = P4_BackReference;
. expr->flag = 0;
. expr->backref_index = index;
-- line 1197 ----------------------------------------
-- line 1213 ----------------------------------------
. P4_PUBLIC(bool)
. P4_IsRule(P4_Expression* e) {
. if (e == NULL)
. return false;
.
. return e->id != 0;
. }
.
3 ( 0.00%) P4_PUBLIC(P4_Grammar*) P4_CreateGrammar(void) {
4 ( 0.00%) P4_Grammar* grammar = malloc(sizeof(P4_Grammar));
230 ( 0.00%) => ???:malloc (1x)
2 ( 0.00%) grammar->rules = NULL;
2 ( 0.00%) grammar->count = 0;
2 ( 0.00%) grammar->cap = 0;
2 ( 0.00%) grammar->spaced_count = -1;
2 ( 0.00%) grammar->spaced_rules = NULL;
2 ( 0.00%) grammar->depth = 1024*8;
1 ( 0.00%) return grammar;
2 ( 0.00%) }
.
. P4_PUBLIC(void)
4 ( 0.00%) P4_DeleteGrammar(P4_Grammar* grammar) {
2 ( 0.00%) if (grammar) {
91 ( 0.00%) for (int i = 0; i < grammar->count; i++) {
153 ( 0.00%) if (grammar->rules[i])
153 ( 0.00%) P4_DeleteExpression(grammar->rules[i]);
22,268 ( 0.07%) => peppapeg.c:P4_DeleteExpression (17x)
119 ( 0.00%) grammar->rules[i] = NULL;
. }
4 ( 0.00%) if (grammar->spaced_rules)
4 ( 0.00%) P4_DeleteExpression(grammar->spaced_rules);
260 ( 0.00%) => peppapeg.c:P4_DeleteExpression (1x)
5 ( 0.00%) free(grammar->rules);
83 ( 0.00%) => ???:free (1x)
4 ( 0.00%) free(grammar);
104 ( 0.00%) => ???:free (1x)
. }
3 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
136 ( 0.00%) P4_GetGrammarRule(P4_Grammar* grammar, P4_RuleID id) {
34 ( 0.00%) P4_Expression* rule = NULL;
1,779 ( 0.01%) for (int i = 0; i < grammar->count; i++) {
2,792 ( 0.01%) rule = grammar->rules[i];
2,094 ( 0.01%) if (rule && rule->id == id)
68 ( 0.00%) return rule;
. }
. return NULL;
68 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
54 ( 0.00%) P4_SetGrammarRuleFlag(P4_Grammar* grammar, P4_RuleID id, P4_ExpressionFlag flag) {
54 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
1,667 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (9x)
18 ( 0.00%) if (expr == NULL)
. return P4_NameError;
.
45 ( 0.00%) P4_SetExpressionFlag(expr, flag);
144 ( 0.00%) => peppapeg.c:P4_SetExpressionFlag (9x)
.
9 ( 0.00%) return P4_Ok;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
102 ( 0.00%) P4_AddGrammarRule(P4_Grammar* grammar, P4_RuleID id, P4_Expression* expr) {
68 ( 0.00%) size_t cap = grammar->cap;
51 ( 0.00%) P4_Expression** rules = grammar->rules;
.
102 ( 0.00%) if (grammar == NULL || id == 0 || expr == NULL)
. return P4_NullError;
.
34 ( 0.00%) if (cap == 0) {
1 ( 0.00%) cap = 32;
7 ( 0.00%) rules = malloc(sizeof(P4_Expression*) * cap);
227 ( 0.00%) => ???:malloc (1x)
80 ( 0.00%) } else if (grammar->count >= cap) {
. cap <<= 1;
. rules = realloc(rules, sizeof(P4_Expression*) * cap);
. }
.
34 ( 0.00%) if (rules == NULL)
. return P4_MemoryError;
.
51 ( 0.00%) expr->id = id;
.
68 ( 0.00%) grammar->cap = cap;
51 ( 0.00%) grammar->rules = rules;
204 ( 0.00%) grammar->rules[grammar->count++] = expr;
.
17 ( 0.00%) return P4_Ok;
34 ( 0.00%) }
.
. P4_PUBLIC(P4_Source*)
5 ( 0.00%) P4_CreateSource(P4_String content, P4_RuleID rule_id) {
4 ( 0.00%) P4_Source* source = malloc(sizeof(P4_Source));
230 ( 0.00%) => ???:malloc (1x)
3 ( 0.00%) source->content = content;
3 ( 0.00%) source->rule_id = rule_id;
2 ( 0.00%) source->pos = 0;
2 ( 0.00%) source->err = P4_Ok;
2 ( 0.00%) source->errmsg = NULL;
2 ( 0.00%) source->root = NULL;
2 ( 0.00%) source->frame_stack = NULL;
2 ( 0.00%) source->frame_stack_size = 0;
2 ( 0.00%) source->whitespacing = false;
1 ( 0.00%) return source;
2 ( 0.00%) }
.
. P4_PUBLIC(void)
4 ( 0.00%) P4_DeleteSource(P4_Source* source) {
2 ( 0.00%) if (source == NULL)
. return;
.
3 ( 0.00%) P4_Frame* tmp = source->frame_stack;
5 ( 0.00%) while(source->frame_stack) {
. tmp = source->frame_stack->next;
. free(source->frame_stack);
. source->frame_stack = tmp;
. }
.
4 ( 0.00%) if (source->errmsg)
5 ( 0.00%) free(source->errmsg);
102 ( 0.00%) => ???:free (1x)
.
4 ( 0.00%) if (source->root)
4 ( 0.00%) P4_DeleteToken(source->root);
151,881 ( 0.45%) => peppapeg.c:P4_DeleteToken (1x)
.
5 ( 0.00%) free(source);
83 ( 0.00%) => ???:free (1x)
2 ( 0.00%) }
.
. P4_PUBLIC(P4_Token*)
. P4_GetSourceAst(P4_Source* source) {
. return source == NULL ? NULL : source->root;
. }
.
. P4_PUBLIC(P4_Position)
. P4_GetSourcePosition(P4_Source* source) {
. return source == NULL ? 0 : source->pos;
. }
.
. P4_PUBLIC(P4_Error)
5 ( 0.00%) P4_Parse(P4_Grammar* grammar, P4_Source* source) {
4 ( 0.00%) if (source->err != P4_Ok)
. return source->err;
.
4 ( 0.00%) if (source->root != NULL)
. return P4_Ok;
.
3 ( 0.00%) source->grammar = grammar;
.
7 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, source->rule_id);
314 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (1x)
6 ( 0.00%) P4_Token* tok = P4_Match(source, expr);
32,997,625 (98.10%) => peppapeg.c:P4_Match (1x)
.
3 ( 0.00%) source->root = tok;
.
2 ( 0.00%) return source->err;
2 ( 0.00%) }
.
.
. P4_PUBLIC(bool)
. P4_HasError(P4_Source* src) {
. if (src == NULL)
. return false;
.
. return src->err != P4_Ok;
-- line 1367 ----------------------------------------
-- line 1379 ----------------------------------------
. P4_GetErrorMessage(P4_Source* source) {
. if (source == NULL || source->errmsg == NULL)
. return NULL;
.
. return strdup(source->errmsg);
. }
.
. P4_PRIVATE(P4_Error)
4 ( 0.00%) P4_SetWhitespaces(P4_Grammar* grammar) {
1 ( 0.00%) size_t count = 0;
2 ( 0.00%) P4_RuleID ids[2] = {0};
2 ( 0.00%) P4_Expression* rules[2] = {0};
1 ( 0.00%) P4_Expression* repeat = NULL;
1 ( 0.00%) P4_Expression* rule = NULL;
.
92 ( 0.00%) for (int i = 0; i < grammar->count; i++) {
136 ( 0.00%) rule = grammar->rules[i];
.
85 ( 0.00%) if (IS_SPACED(rule)) {
4 ( 0.00%) ids[count] = rule->id;
7 ( 0.00%) rules[count] = P4_CreateReference(rule->id);
252 ( 0.00%) => peppapeg.c:P4_CreateReference (1x)
.
4 ( 0.00%) if (rules[count] == NULL)
. goto end;
.
4 ( 0.00%) rules[count]->ref_expr = rule;
.
1 ( 0.00%) count++;
. }
.
34 ( 0.00%) if (count > 1)
. break;
. }
.
2 ( 0.00%) if (count == 0) {
. return P4_Ok;
.
2 ( 0.00%) } else if (count == 1) {
3 ( 0.00%) repeat = rules[0];
.
. } else if (count == 2) {
. repeat = P4_CreateChoice(2);
. if (repeat == NULL)
. goto end;
. if (P4_SetMember(repeat, 0, rules[0]) != P4_Ok)
. goto end;
. if (P4_SetMember(repeat, 1, rules[1]) != P4_Ok)
. goto end;
. }
.
10 ( 0.00%) if ((grammar->spaced_rules = P4_CreateZeroOrMore(repeat))== NULL)
269 ( 0.00%) => peppapeg.c:P4_CreateZeroOrMore (1x)
. goto end;
.
3 ( 0.00%) grammar->spaced_count = count;
.
2 ( 0.00%) return P4_Ok;
.
. end:
. if (rules[0] != NULL)
. P4_DeleteExpression(rules[0]);
.
. if (rules[1] != NULL)
. P4_DeleteExpression(rules[1]);
.
-- line 1442 ----------------------------------------
-- line 1443 ----------------------------------------
. if (grammar->spaced_rules != NULL) {
. P4_DeleteExpression(grammar->spaced_rules);
. grammar->spaced_rules = NULL;
. }
.
. grammar->spaced_count = -1;
.
. return P4_MemoryError;
2 ( 0.00%) }
.
. P4_PRIVATE(P4_Expression*)
60,036 ( 0.18%) P4_GetWhitespaces(P4_Grammar* g) {
30,018 ( 0.09%) if (g == NULL)
. return NULL;
.
60,036 ( 0.18%) if (g->spaced_count == -1)
3 ( 0.00%) P4_SetWhitespaces(g);
923 ( 0.00%) => peppapeg.c:P4_SetWhitespaces (1x)
.
30,018 ( 0.09%) return g->spaced_rules;
30,018 ( 0.09%) }
.
. P4_PUBLIC(void)
45 ( 0.00%) P4_SetExpressionFlag(P4_Expression* e, P4_ExpressionFlag f) {
18 ( 0.00%) assert(e != NULL);
54 ( 0.00%) e->flag |= f;
27 ( 0.00%) }
.
. P4_PRIVATE(P4_Position)
339,138 ( 1.01%) P4_GetPosition(P4_Source* s) {
226,092 ( 0.67%) return s->pos;
226,092 ( 0.67%) }
.
. P4_PRIVATE(void)
176,080 ( 0.52%) P4_SetPosition(P4_Source* s, P4_Position pos) {
132,060 ( 0.39%) s->pos = pos;
132,060 ( 0.39%) }
.
. /*
. * Get the remaining text.
. */
. P4_PRIVATE(P4_String)
123,024 ( 0.37%) P4_RemainingText(P4_Source* s) {
205,040 ( 0.61%) return s->content + s->pos;
82,016 ( 0.24%) }
.
. P4_PUBLIC(P4_Error)
40 ( 0.00%) P4_AddLiteral(P4_Grammar* grammar, P4_RuleID id, const P4_String literal, bool sensitive) {
145 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateLiteral(literal, sensitive));
3,371 ( 0.01%) => peppapeg.c:P4_CreateLiteral (5x)
495 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (5x)
5 ( 0.00%) return P4_Ok;
10 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddRange(P4_Grammar* grammar, P4_RuleID id, P4_Rune lower, P4_Rune upper) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateRange(lower, upper));
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
-- line 1500 ----------------------------------------
-- line 1516 ----------------------------------------
. P4_PUBLIC(P4_Error)
. P4_AddSequence(P4_Grammar* grammar, P4_RuleID id, size_t size) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateContainer(size));
. P4_GetGrammarRule(grammar, id)->kind = P4_Sequence;
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
88 ( 0.00%) P4_AddSequenceWithMembers(P4_Grammar* grammar, P4_RuleID id, size_t count, ...) {
216 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateSequence(count));
4,008 ( 0.01%) => peppapeg.c:P4_CreateSequence (8x)
424 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (8x)
48 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
1,562 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (8x)
.
. va_list members;
48 ( 0.00%) va_start (members, count);
.
158 ( 0.00%) for (int i = 0; i < count; i++) {
413 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
198 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
16 ( 0.00%) return P4_Ok;
.
. finalize:
. P4_DeleteExpression(expr);
.
. return P4_MemoryError;
16 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddChoice(P4_Grammar* grammar, P4_RuleID id, size_t size) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateContainer(size));
. P4_GetGrammarRule(grammar, id)->kind = P4_Choice;
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
44 ( 0.00%) P4_AddChoiceWithMembers(P4_Grammar* grammar, P4_RuleID id, size_t count, ...) {
108 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateChoice(count));
2,004 ( 0.01%) => peppapeg.c:P4_CreateChoice (4x)
212 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (4x)
24 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
952 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (4x)
.
. va_list members;
24 ( 0.00%) va_start (members, count);
.
74 ( 0.00%) for (int i = 0; i < count; i++) {
185 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
90 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
8 ( 0.00%) return P4_Ok;
.
. finalize:
. P4_DeleteExpression(expr);
.
. return P4_MemoryError;
8 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_SetMember(P4_Expression* expr, size_t offset, P4_Expression* member) {
. if (expr == NULL
. || member == NULL
. || expr->members == NULL
. || expr->count == 0) {
. return P4_NullError;
-- line 1588 ----------------------------------------
-- line 1645 ----------------------------------------
. || offset >= expr->count) {
. return NULL;
. }
.
. return expr->members[offset];
. }
.
. P4_PUBLIC(void)
424 ( 0.00%) P4_DeleteExpression(P4_Expression* expr) {
212 ( 0.00%) if (expr == NULL)
. return;
.
742 ( 0.00%) switch (expr->kind) {
. case P4_Literal:
140 ( 0.00%) if (expr->literal)
175 ( 0.00%) free(expr->literal);
520 ( 0.00%) => ???:free (5x)
105 ( 0.00%) break;
. // case P4_Reference is quite special - it is not the owner of ref_expr.
. case P4_Positive:
. case P4_Negative:
. if (expr->ref_expr)
. P4_DeleteExpression(expr->ref_expr);
. break;
. case P4_Sequence:
. case P4_Choice:
710 ( 0.00%) for (int i = 0; i < expr->count; i++) {
666 ( 0.00%) if (expr->members[i])
666 ( 0.00%) P4_DeleteExpression(expr->members[i]);
17,158 ( 0.05%) => peppapeg.c:P4_DeleteExpression'2 (32x)
518 ( 0.00%) expr->members[i] = NULL;
. }
120 ( 0.00%) free(expr->members);
1,248 ( 0.00%) => ???:free (12x)
48 ( 0.00%) expr->members = NULL;
24 ( 0.00%) break;
. case P4_Repeat:
56 ( 0.00%) if (expr->repeat_expr)
56 ( 0.00%) P4_DeleteExpression(expr->repeat_expr);
126 ( 0.00%) => peppapeg.c:P4_DeleteExpression'2 (1x)
28 ( 0.00%) break;
. default:
66 ( 0.00%) break;
. }
.
530 ( 0.00%) free(expr);
1,830 ( 0.01%) => ???:free (18x)
212 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddReference(P4_Grammar* grammar, P4_RuleID id, P4_RuleID ref) {
. if (ref == 0) {
. return P4_NullError;
. }
.
. P4_AddSomeGrammarRule(grammar, id, P4_CreateReference(ref));
-- line 1695 ----------------------------------------
--------------------------------------------------------------------------------
-- Auto-annotated source: /app/examples/json.c
--------------------------------------------------------------------------------
No information has been collected for /app/examples/json.c
--------------------------------------------------------------------------------
-- Auto-annotated source: /app/peppapeg.c
--------------------------------------------------------------------------------
No information has been collected for /app/peppapeg.c
--------------------------------------------------------------------------------
-- Auto-annotated source: examples/json.c
--------------------------------------------------------------------------------
Ir
. #include <stdio.h>
. #include <stdlib.h>
. #include "../peppapeg.h"
. #include "json.h"
.
. # define NESTING_DEPTH 1000
.
5 ( 0.00%) int main(int argc, char* argv[]) {
8 ( 0.00%) char* input = malloc(sizeof(char) * (NESTING_DEPTH*2 + 1));
69,173 ( 0.21%) => ???:_dl_runtime_resolve_xsave (1x)
. int i;
.
3,004 ( 0.01%) for (i = 0; i < NESTING_DEPTH; i++) {
5,000 ( 0.01%) input[i] = '[';
6,000 ( 0.02%) input[NESTING_DEPTH+i] = ']';
. }
3 ( 0.00%) input[NESTING_DEPTH*2] = '\0';
.
3 ( 0.00%) P4_Grammar* grammar = P4_CreateJSONGrammar();
53,571 ( 0.16%) => /app/examples/json.h:P4_CreateJSONGrammar (1x)
5 ( 0.00%) P4_Source* source = P4_CreateSource(input, P4_JSONEntry);
262 ( 0.00%) => /app/peppapeg.c:P4_CreateSource (1x)
.
14 ( 0.00%) printf("%u\n", P4_Parse(grammar, source));
32,997,975 (98.10%) => /app/peppapeg.c:P4_Parse (1x)
217,440 ( 0.65%) => ???:_dl_runtime_resolve_xsave (1x)
.
4 ( 0.00%) free(input);
128 ( 0.00%) => ???:free (1x)
3 ( 0.00%) P4_DeleteSource(source);
152,104 ( 0.45%) => /app/peppapeg.c:P4_DeleteSource (1x)
3 ( 0.00%) P4_DeleteGrammar(grammar);
23,257 ( 0.07%) => /app/peppapeg.c:P4_DeleteGrammar (1x)
.
1 ( 0.00%) return 0;
2 ( 0.00%) }
.
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
16,399,707 (48.76%) events annotated
--------------------------------------------------------------------------------
Profile data file 'callgrind.out.10362' (creator: callgrind-3.16.0)
--------------------------------------------------------------------------------
I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 7341727
Trigger: Program termination
Profiled target: ./a.out (PID 10362, part 1)
Events recorded: Ir
Events shown: Ir
Event sort order: Ir
Thresholds: 99
Include dirs:
User annotated:
Auto-annotation: on
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
33,636,429 (100.0%) PROGRAM TOTALS
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
5,259,159 (15.64%) ???:_int_free [/usr/lib64/libc-2.28.so]
3,846,607 (11.44%) ???:malloc [/usr/lib64/ld-2.28.so]
2,595,108 ( 7.72%) peppapeg.c:P4_Match'2 [/app/a.out]
2,078,669 ( 6.18%) ???:free [/usr/lib64/ld-2.28.so]
1,929,040 ( 5.73%) ???:__strlen_avx2 [/usr/lib64/libc-2.28.so]
1,841,351 ( 5.47%) peppapeg.c:P4_MatchLiteral [/app/a.out]
1,705,988 ( 5.07%) peppapeg.c:P4_MatchChoice'2 [/app/a.out]
1,518,598 ( 4.51%) peppapeg.c:P4_Expression_dispatch'2 [/app/a.out]
1,260,936 ( 3.75%) ???:strdup [/usr/lib64/ld-2.28.so]
1,174,097 ( 3.49%) peppapeg.c:P4_MatchRepeat [/app/a.out]
1,092,247 ( 3.25%) peppapeg.c:P4_RaiseError [/app/a.out]
1,003,802 ( 2.98%) ???:__memcpy_avx_unaligned_erms [/usr/lib64/libc-2.28.so]
900,542 ( 2.68%) peppapeg.c:P4_MatchSequence'2 [/app/a.out]
806,160 ( 2.40%) peppapeg.c:P4_RescueError [/app/a.out]
805,790 ( 2.40%) peppapeg.c:P4_PushFrame [/app/a.out]
802,954 ( 2.39%) ???:_int_malloc [/usr/lib64/libc-2.28.so]
791,322 ( 2.35%) peppapeg.c:P4_GetPosition [/app/a.out]
671,409 ( 2.00%) peppapeg.c:P4_DeleteToken [/app/a.out]
440,200 ( 1.31%) peppapeg.c:P4_SetPosition [/app/a.out]
414,244 ( 1.23%) peppapeg.c:P4_MatchReference'2 [/app/a.out]
410,080 ( 1.22%) peppapeg.c:P4_RemainingText [/app/a.out]
310,279 ( 0.92%) peppapeg.c:P4_PopFrame [/app/a.out]
297,096 ( 0.88%) ???:__memcmp_avx2_movbe [/usr/lib64/libc-2.28.so]
210,129 ( 0.62%) peppapeg.c:P4_GetWhitespaces [/app/a.out]
196,095 ( 0.58%) peppapeg.c:P4_GetReference [/app/a.out]
185,000 ( 0.55%) peppapeg.c:P4_MatchSpacedExpressions [/app/a.out]
140,102 ( 0.42%) ???:0x0000000004c4e760 [???]
140,100 ( 0.42%) ???:0x0000000004c4e820 [???]
140,100 ( 0.42%) ???:0x0000000004c4e880 [???]
122,000 ( 0.36%) peppapeg.c:P4_NeedLift [/app/a.out]
120,639 ( 0.36%) ???:malloc_consolidate [/usr/lib64/libc-2.28.so]
90,144 ( 0.27%) peppapeg.c:cleanup_freep [/app/a.out]
66,680 ( 0.20%) ???:_dl_addr [/usr/lib64/libc-2.28.so]
--------------------------------------------------------------------------------
-- Auto-annotated source: peppapeg.c
--------------------------------------------------------------------------------
Ir
-- line 42 ----------------------------------------
. # define NEED_SPACE(s) ((s)->frame_stack ? (s)->frame_stack->space : false)
. # define NO_ERROR(s) ((s)->err == P4_Ok)
. # define NO_MATCH(s) ((s)->err == P4_MatchError)
.
. # define autofree __attribute__ ((cleanup (cleanup_freep)))
.
. P4_PRIVATE(void)
. cleanup_freep (void *p)
20,032 ( 0.06%) {
10,016 ( 0.03%) void **pp = (void **) p;
20,032 ( 0.06%) if (*pp)
25,040 ( 0.07%) free (*pp);
436,536 ( 1.30%) => ???:free (5,008x)
15,024 ( 0.04%) }
.
. # define P4_AdoptToken(head, tail, list) do { \
. if ((list) != NULL) {\
. if ((head) == NULL) (head) = (list); \
. if ((tail) == NULL) (tail) = (list); \
. else (tail)->next = (list); \
. if ((tail) != NULL) {\
. while ((tail)->next != NULL) \
-- line 62 ----------------------------------------
-- line 138 ----------------------------------------
. *
. * > uint32_t c = 0x0
. * > P4_ReadRune("你好", &c)
. * 3
. * > printf("%p %d\n", c, c)
. * 0x4f60 20320
. */
. P4_PRIVATE(size_t)
4 ( 0.00%) P4_ReadRune(P4_String s, P4_Rune* c) {
2 ( 0.00%) *c = 0;
.
4 ( 0.00%) if ((s[0] & 0b10000000) == 0) { // 1 byte code point, ASCII
7 ( 0.00%) *c = (s[0] & 0b01111111);
2 ( 0.00%) return 1;
. } else if ((s[0] & 0b11100000) == 0b11000000) { // 2 byte code point
. *c = (s[0] & 0b00011111) << 6 | (s[1] & 0b00111111);
. return 2;
. } else if ((s[0] & 0b11110000) == 0b11100000) { // 3 byte code point
. *c = (s[0] & 0b00001111) << 12 | (s[1] & 0b00111111) << 6 | (s[2] & 0b00111111);
. return 3;
. } else if ((s[0] & 0b11111000) == 0b11110000) { // 4 byte code point
. *c = (s[0] & 0b00000111) << 18 | (s[1] & 0b00111111) << 12 | (s[2] & 0b00111111) << 6 | (s[3] & 0b00111111);
. return 4;
. } else {
. *c = 0x0;
. return 0;
. }
2 ( 0.00%) }
.
. /*
. * Compare case-insensitive string src v/s dest.
. *
. * Like strcmp, but works for a case insensitive UTF-8 string.
. */
. P4_PRIVATE(int)
. P4_CaseCmpInsensitive(P4_String src, P4_String dst, size_t len) {
-- line 173 ----------------------------------------
-- line 196 ----------------------------------------
. * Determine if the corresponding token to `e` should be ignored.
. *
. * 1. Intermediate expr.
. * 2. Bareness expr.
. * 3. Hollowed expr.
. *
. */
. P4_PRIVATE(bool)
32,000 ( 0.10%) P4_NeedLift(P4_Source* s, P4_Expression* e) {
74,000 ( 0.22%) return !IS_RULE(e) || IS_LIFTED(e) || NEED_SILENT(s);
16,000 ( 0.05%) }
.
.
. /*
. * Raise an error.
. *
. * Set err and errmsg to state.
. */
. P4_PRIVATE(void)
234,054 ( 0.70%) P4_RaiseError(P4_Source* s, P4_Error err, P4_String errmsg) {
117,027 ( 0.35%) s->err = err;
.
156,036 ( 0.46%) if (s->errmsg != NULL)
195,040 ( 0.58%) free(s->errmsg);
3,237,664 ( 9.63%) => ???:free (39,008x)
.
273,063 ( 0.81%) s->errmsg = strdup(errmsg);
4,071,107 (12.10%) => ???:strdup (39,009x)
117,027 ( 0.35%) }
.
.
. /*
. * Clear an error.
. *
. * It allows the parser to keep parsing the text.
. */
. P4_PRIVATE(void)
124,024 ( 0.37%) P4_RescueError(P4_Source* s) {
62,012 ( 0.18%) s->err = P4_Ok;
124,024 ( 0.37%) if (s->errmsg != NULL) {
155,034 ( 0.46%) free(s->errmsg);
2,615,308 ( 7.78%) => ???:free (31,005x)
677 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
62,012 ( 0.18%) s->errmsg = NULL;
186,036 ( 0.55%) s->errmsg = strdup("");
3,069,594 ( 9.13%) => ???:strdup (31,006x)
. }
93,018 ( 0.28%) }
.
.
. /*
. * Initialize a token.
. */
. P4_Token*
. P4_CreateToken (const P4_String str,
. size_t slice_i,
. size_t slice_j,
7,000 ( 0.02%) P4_Expression* expr) {
. P4_Token* token;
.
6,000 ( 0.02%) if ((token=malloc(sizeof(P4_Token))) == NULL)
45,000 ( 0.13%) => ???:malloc (1,000x)
. return NULL;
.
3,000 ( 0.01%) token->text = str;
3,000 ( 0.01%) token->slice.i = slice_i;
3,000 ( 0.01%) token->slice.j = slice_j;
3,000 ( 0.01%) token->expr = expr;
2,000 ( 0.01%) token->next = NULL;
2,000 ( 0.01%) token->head = NULL;
2,000 ( 0.01%) token->tail = NULL;
.
1,000 ( 0.00%) return token;
2,000 ( 0.01%) }
.
.
. /*
. * Free the token.
. *
. * Danger: if free the token only without cleaning next & head & tail,
. * they're in risk of being dangled.
. */
. P4_PRIVATE(void)
4,000 ( 0.01%) P4_DeleteTokenNode(P4_Token* token) {
2,000 ( 0.01%) assert(token != NULL);
2,000 ( 0.01%) if (token)
4,000 ( 0.01%) free(token);
103,893 ( 0.31%) => ???:free (1,000x)
3,000 ( 0.01%) }
.
.
. /*
. * Free all of the children tokens of the token.
. */
. P4_PRIVATE(void)
3,996 ( 0.01%) P4_DeleteTokenChildren(P4_Token* token) {
1,998 ( 0.01%) assert(token != NULL);
2,997 ( 0.01%) P4_Token* child = token->head;
999 ( 0.00%) P4_Token* tmp = NULL;
.
4,995 ( 0.01%) while (child) {
2,997 ( 0.01%) tmp = child->next;
3,996 ( 0.01%) if (child->head)
2,994 ( 0.01%) P4_DeleteTokenChildren(child);
151,586 ( 0.45%) => peppapeg.c:P4_DeleteTokenChildren'2 (1x)
2,997 ( 0.01%) P4_DeleteTokenNode(child);
119 ( 0.00%) => peppapeg.c:P4_DeleteTokenNode (1x)
1,998 ( 0.01%) child = tmp;
. }
2,997 ( 0.01%) }
.
.
. /*
. * Free the token list and all the children nodes of each
. * node in the token list.
. */
. P4_PUBLIC(void)
244,144 ( 0.73%) P4_DeleteToken(P4_Token* token) {
61,036 ( 0.18%) P4_Token* tmp = NULL;
183,110 ( 0.54%) while (token) {
3 ( 0.00%) tmp = token->next;
3 ( 0.00%) P4_DeleteTokenChildren(token);
151,738 ( 0.45%) => peppapeg.c:P4_DeleteTokenChildren (1x)
3 ( 0.00%) P4_DeleteTokenNode(token);
119 ( 0.00%) => peppapeg.c:P4_DeleteTokenNode (1x)
2 ( 0.00%) token = tmp;
. }
183,108 ( 0.54%) }
.
. /*
. * Push e into s->frame_stack.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.15%) P4_PushFrame(P4_Source* s, P4_Expression* e) {
70,063 ( 0.21%) if (s->frame_stack_size > (s->grammar->depth)) {
. return P4_StackError;
. }
.
40,036 ( 0.12%) P4_Frame* frame = malloc(sizeof(P4_Frame));
820,960 ( 2.44%) => ???:malloc (10,009x)
.
20,018 ( 0.06%) if (frame == NULL) {
. return P4_MemoryError;
. }
.
30,027 ( 0.09%) P4_Frame* top = s->frame_stack;
.
. /* Set silent */
20,018 ( 0.06%) frame->silent = false;
.
50,045 ( 0.15%) if (!IS_SCOPED(e)) {
20,018 ( 0.06%) if (
60,048 ( 0.18%) (top && IS_SQUASHED(top->expr))
60,050 ( 0.18%) || (top && top->silent)
. )
. frame->silent = true;
. }
.
. /* Set space */
20,018 ( 0.06%) frame->space = false;
.
60,054 ( 0.18%) if (P4_GetWhitespaces(s->grammar) != NULL
141,052 ( 0.42%) => peppapeg.c:P4_GetWhitespaces (10,009x)
50,045 ( 0.15%) && !s->whitespacing) {
25,050 ( 0.07%) if (IS_SCOPED(e)) {
. frame->space = true;
10,020 ( 0.03%) } else if (top) {
25,045 ( 0.07%) if (!IS_TIGHT(e)) {
25,030 ( 0.07%) frame->space = top->space;
. }
5 ( 0.00%) } else if (!IS_TIGHT(e)) {
2 ( 0.00%) frame->space = true;
. }
. }
.
. /* Set expr & next */
30,027 ( 0.09%) frame->expr = e;
30,027 ( 0.09%) frame->next = top;
.
. /* Push stack */
50,045 ( 0.15%) s->frame_stack_size++;
30,027 ( 0.09%) s->frame_stack = frame;
.
10,009 ( 0.03%) return P4_Ok;
20,018 ( 0.06%) }
.
.
. /*
. * Pop top from s->frames.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.15%) P4_PopFrame(P4_Source* s, P4_Frame* f) {
40,036 ( 0.12%) if (s->frame_stack == NULL)
. return P4_MemoryError;
.
30,027 ( 0.09%) P4_Frame* oldtop = s->frame_stack;
50,045 ( 0.15%) s->frame_stack = s->frame_stack->next;
60,054 ( 0.18%) if (oldtop) free(oldtop);
830,768 ( 2.47%) => ???:free (10,009x)
50,045 ( 0.15%) s->frame_stack_size--;
.
10,009 ( 0.03%) return P4_Ok;
20,018 ( 0.06%) }
.
.
. P4_PRIVATE(P4_Token*)
165,030 ( 0.49%) P4_MatchLiteral(P4_Source* s, P4_Expression* e) {
132,024 ( 0.39%) assert(NO_ERROR(s));
.
132,024 ( 0.39%) P4_String str = P4_RemainingText(s);
330,060 ( 0.98%) => peppapeg.c:P4_RemainingText (33,006x)
.
. # define EOT(s) (*(s) == 0x0)
.
132,024 ( 0.39%) if (EOT(str)) {
. P4_RaiseError(s, P4_MatchError, "eof");
. return NULL;
. }
.
198,040 ( 0.59%) size_t len = strlen(e->literal);
560,088 ( 1.67%) => ???:__strlen_avx2 (33,005x)
633 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
.
132,024 ( 0.39%) P4_MarkPosition(s, startpos);
231,042 ( 0.69%) => peppapeg.c:P4_GetPosition (33,006x)
165,030 ( 0.49%) if ((!e->sensitive && P4_CaseCmpInsensitive(e->literal, str, len) != 0)
462,088 ( 1.37%) || (e->sensitive && memcmp(e->literal, str, len) != 0)) {
297,087 ( 0.88%) => ???:__memcmp_avx2_movbe (33,005x)
627 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
155,025 ( 0.46%) P4_RaiseError(s, P4_MatchError, "expect literal");
6,728,182 (20.00%) => peppapeg.c:P4_RaiseError (31,005x)
62,010 ( 0.18%) return NULL;
. }
14,007 ( 0.04%) P4_SetPosition(s, startpos+len);
20,010 ( 0.06%) => peppapeg.c:P4_SetPosition (2,001x)
8,004 ( 0.02%) P4_MarkPosition(s, endpos);
14,007 ( 0.04%) => peppapeg.c:P4_GetPosition (2,001x)
.
14,007 ( 0.04%) if (P4_NeedLift(s, e))
26,013 ( 0.08%) => peppapeg.c:P4_NeedLift (2,001x)
4,002 ( 0.01%) return NULL;
.
. P4_Token* result = NULL;
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "");
. return NULL;
. }
.
. return result;
66,012 ( 0.20%) }
.
. P4_PRIVATE(P4_Token*)
5 ( 0.00%) P4_MatchRange(P4_Source* s, P4_Expression* e) {
4 ( 0.00%) assert(NO_ERROR(s));
.
4 ( 0.00%) P4_String str = P4_RemainingText(s);
10 ( 0.00%) => peppapeg.c:P4_RemainingText (1x)
4 ( 0.00%) if (*str == '\0') {
. P4_RaiseError(s, P4_MatchError, "eof");
. return NULL;
. }
.
4 ( 0.00%) P4_MarkPosition(s, startpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
1 ( 0.00%) uint32_t rune = 0x0;
6 ( 0.00%) size_t size = P4_ReadRune(str, &rune);
21 ( 0.00%) => peppapeg.c:P4_ReadRune (1x)
.
. #define IN_RANGE(e, c) ((c)>=(e)->range[0] && (c)<=(e)->range[1])
.
10 ( 0.00%) if (!IN_RANGE(e, rune)) {
5 ( 0.00%) P4_RaiseError(s, P4_MatchError, "not in range");
209 ( 0.00%) => peppapeg.c:P4_RaiseError (1x)
2 ( 0.00%) return NULL;
. }
.
. P4_SetPosition(s, startpos+size);
. P4_MarkPosition(s, endpos);
.
. if (P4_NeedLift(s, e))
. return NULL;
.
. P4_Token* result = NULL;
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. return result;
2 ( 0.00%) }
.
. P4_PRIVATE(P4_Expression*)
70,020 ( 0.21%) P4_GetReference(P4_Source* s, P4_Expression* e) {
56,016 ( 0.17%) if (e->ref_expr != NULL)
42,003 ( 0.12%) return e->ref_expr;
.
12 ( 0.00%) if (e->ref_id != 0) {
30 ( 0.00%) e->ref_expr = P4_GetGrammarRule(s->grammar, e->ref_id);
695 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (3x)
. }
.
6 ( 0.00%) return e->ref_expr;
28,008 ( 0.08%) }
.
. P4_PRIVATE(P4_Token*)
50,040 ( 0.15%) P4_MatchReference(P4_Source* s, P4_Expression* e) {
40,032 ( 0.12%) assert(NO_ERROR(s));
.
40,068 ( 0.12%) if (e->ref_expr == NULL && e->ref_id != 0) {
90 ( 0.00%) e->ref_expr = P4_GetGrammarRule(s->grammar, e->ref_id);
552 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (2x)
. }
.
40,032 ( 0.12%) if (e->ref_expr == NULL) {
. P4_RaiseError(s, P4_NameError, "");
. return NULL;
. }
.
40,032 ( 0.12%) P4_MarkPosition(s, startpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
70,056 ( 0.21%) P4_Token* reftok = P4_Match(s, e->ref_expr);
32,992,089 (98.08%) => peppapeg.c:P4_Match'2 (4x)
40,032 ( 0.12%) P4_MarkPosition(s, endpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
.
. // Ref matching is terminated when error occurred.
40,032 ( 0.12%) if (!NO_ERROR(s))
16,018 ( 0.05%) return NULL;
.
. // The referenced token is returned when silenced.
13,993 ( 0.04%) if (P4_NeedLift(s, e))
13 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
3,998 ( 0.01%) return reftok;
.
. // A single reference expr can be a rule: `e = { ref }`
. // In such a case, a token for `e` with single child `ref` is created.
. //
. P4_Token* result = NULL;
.
. if ((result=P4_CreateToken (s->content, startpos, endpos, e)) == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. P4_AdoptToken(result->head, result->tail, reftok);
. return result;
20,016 ( 0.06%) }
.
. P4_PRIVATE(P4_Token*)
30,048 ( 0.09%) P4_MatchSequence(P4_Source* s, P4_Expression* e) {
20,032 ( 0.06%) assert(NO_ERROR(s));
.
5,008 ( 0.01%) P4_Expression *member = NULL;
5,008 ( 0.01%) P4_Token *head = NULL,
5,008 ( 0.01%) *tail = NULL,
5,008 ( 0.01%) *tok = NULL,
5,008 ( 0.01%) *whitespace = NULL;
.
55,088 ( 0.16%) autofree P4_Slice* backrefs = malloc(sizeof(P4_Slice) * e->count);
230 ( 0.00%) => ???:malloc (1x)
101 ( 0.00%) => peppapeg.c:cleanup_freep (1x)
15,024 ( 0.04%) if (backrefs == NULL) {
. P4_RaiseError(s, P4_MemoryError, "OOM");
. return NULL;
. }
.
65,101 ( 0.19%) bool need_space = NEED_SPACE(s);
.
20,032 ( 0.06%) P4_MarkPosition(s, startpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
89,071 ( 0.26%) for (int i = 0; i < e->count; i++) {
80,072 ( 0.24%) member = e->members[i];
.
. // Optional `WHITESPACE` and `COMMENT` are inserted between every member.
40,028 ( 0.12%) if (need_space && i > 0) {
25,000 ( 0.07%) whitespace = P4_MatchSpacedExpressions(s, NULL);
3,940 ( 0.01%) => peppapeg.c:P4_MatchSpacedExpressions (2x)
20,000 ( 0.06%) if (!NO_ERROR(s)) goto finalize;
10,000 ( 0.03%) P4_AdoptToken(head, tail, whitespace);
. }
.
40,036 ( 0.12%) P4_MarkPosition(s, member_startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
.
40,036 ( 0.12%) if (member->kind == P4_BackReference) {
. tok = P4_MatchBackReference(s, e, backrefs, member->backref_index);
. if (!NO_ERROR(s)) goto finalize;
. } else {
60,054 ( 0.18%) tok = P4_Match(s, member);
32,991,564 (98.08%) => peppapeg.c:P4_Match'2 (3x)
. }
.
. // If any of the sequence members fails, the entire sequence fails.
. // Puke the eaten text and free all created tokens.
40,036 ( 0.12%) if (!NO_ERROR(s)) {
3,008 ( 0.01%) goto finalize;
. }
.
45,986 ( 0.14%) P4_AdoptToken(head, tail, tok);
49,007 ( 0.15%) backrefs[i].i = member_startpos;
63,009 ( 0.19%) backrefs[i].j = P4_GetPosition(s);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
. }
.
14,000 ( 0.04%) if (P4_NeedLift(s, e))
18 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
4,000 ( 0.01%) return head;
.
. P4_Token* ret = P4_CreateToken (s->content, startpos, P4_GetPosition(s), e);
. if (ret == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. return NULL;
. }
.
. ret->head = head;
. ret->tail = tail;
. return ret;
.
. finalize:
15,040 ( 0.04%) P4_SetPosition(s, startpos);
30,080 ( 0.09%) => peppapeg.c:P4_SetPosition (3,008x)
9,024 ( 0.03%) P4_DeleteToken(head);
33,088 ( 0.10%) => peppapeg.c:P4_DeleteToken (3,008x)
3,008 ( 0.01%) return NULL;
20,032 ( 0.06%) }
.
. P4_PRIVATE(P4_Token*)
50,015 ( 0.15%) P4_MatchChoice(P4_Source* s, P4_Expression* e) {
10,003 ( 0.03%) P4_Token* tok = NULL;
10,003 ( 0.03%) P4_Expression* member = NULL;
.
. // A member is attempted if previous yields no match.
. // The oneof match matches successfully immediately if any match passes.
40,012 ( 0.12%) P4_MarkPosition(s, startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
241,073 ( 0.72%) for (int i = 0; i < e->count; i++) {
264,080 ( 0.79%) member = e->members[i];
198,060 ( 0.59%) tok = P4_Match(s, member);
32,989,276 (98.08%) => peppapeg.c:P4_Match'2 (10x)
134,040 ( 0.40%) if (NO_ERROR(s)) break;
124,040 ( 0.37%) if (NO_MATCH(s)) {
. // retry until the last one.
217,070 ( 0.65%) if (i < e->count-1) {
69,021 ( 0.21%) P4_RescueError(s);
2,054 ( 0.01%) => peppapeg.c:P4_RescueError (7x)
138,042 ( 0.41%) P4_SetPosition(s, startpos);
70 ( 0.00%) => peppapeg.c:P4_SetPosition (7x)
. // fail when the last one is a no-match.
. } else {
40,015 ( 0.12%) P4_RaiseError(s, P4_MatchError, "no match");
418 ( 0.00%) => peppapeg.c:P4_RaiseError (2x)
8,003 ( 0.02%) goto finalize;
. }
. }
. }
8,000 ( 0.02%) P4_MarkPosition(s, endpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
14,000 ( 0.04%) if (P4_NeedLift(s, e))
13 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
2,000 ( 0.01%) return tok;
.
8,000 ( 0.02%) P4_Token* oneof = P4_CreateToken (s->content, startpos, endpos, e);
79,000 ( 0.23%) => peppapeg.c:P4_CreateToken (1,000x)
2,000 ( 0.01%) if (oneof == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. goto finalize;
. }
.
26,975 ( 0.08%) P4_AdoptToken(oneof->head, oneof->tail, tok);
2,000 ( 0.01%) return oneof;
.
. finalize:
40,015 ( 0.12%) P4_SetPosition(s, startpos);
20 ( 0.00%) => peppapeg.c:P4_SetPosition (2x)
32,012 ( 0.10%) free(tok);
24 ( 0.00%) => ???:free (2x)
8,003 ( 0.02%) return NULL;
20,006 ( 0.06%) }
.
. /*
. * Repetition matcher function.
. *
. * Returns a token in a greedy fashion.
. *
. * There are seven repetition mode: zeroormore, zerooronce,
. */
. P4_PRIVATE(P4_Token*)
40,005 ( 0.12%) P4_MatchRepeat(P4_Source* s, P4_Expression* e) {
24,003 ( 0.07%) size_t min = -1, max = -1, repeated = 0;
.
32,004 ( 0.10%) assert(e->repeat_min != min || e->repeat_max != max); // need at least one of min/max.
32,004 ( 0.10%) assert(e->repeat_expr != NULL); // need repeat expression.
32,004 ( 0.10%) assert(NO_ERROR(s));
.
. # define IS_REF(e) ((e)->kind == P4_Reference)
. # define IS_PROGRESSING(k) ((k)==P4_Positive \
. || (k)==P4_Negative)
.
. // when expression inside repetition is non-progressing, it repeats indefinitely.
. // we know negative/positive definitely not progressing,
. // and so does a reference to a negative/positive rule.
. // Question: we may never list all the cases in this way. How to deal with it better?
96,012 ( 0.29%) if (IS_PROGRESSING(e->repeat_expr->kind) ||
24,003 ( 0.07%) (IS_REF(e->repeat_expr)
126,036 ( 0.37%) && IS_PROGRESSING(P4_GetReference(s, e->repeat_expr)->kind))) {
196,790 ( 0.59%) => peppapeg.c:P4_GetReference (14,004x)
. P4_RaiseError(s, P4_AdvanceError, "no progressing in repetition");
. return NULL;
. }
.
24,003 ( 0.07%) min = e->repeat_min;
24,003 ( 0.07%) max = e->repeat_max;
.
104,012 ( 0.31%) bool need_space = NEED_SPACE(s);
32,004 ( 0.10%) P4_Position startpos = P4_GetPosition(s);
56,007 ( 0.17%) => peppapeg.c:P4_GetPosition (8,001x)
32,004 ( 0.10%) P4_Token *head = NULL, *tail = NULL, *tok = NULL, *whitespace = NULL;
.
56,007 ( 0.17%) while (*P4_RemainingText(s) != '\0') {
80,010 ( 0.24%) => peppapeg.c:P4_RemainingText (8,001x)
31,996 ( 0.10%) P4_MarkPosition(s, before_implicit);
55,993 ( 0.17%) => peppapeg.c:P4_GetPosition (7,999x)
.
. // SPACED rule expressions are inserted between every repetition.
31,994 ( 0.10%) if (need_space && repeated > 0 ) {
. whitespace = P4_MatchSpacedExpressions(s, NULL);
. if (!NO_ERROR(s)) goto finalize;
. P4_AdoptToken(head, tail, whitespace);
. }
.
55,993 ( 0.17%) tok = P4_Match(s, e->repeat_expr);
22,833,257 (67.88%) => peppapeg.c:P4_Match'2 (7,999x)
.
31,996 ( 0.10%) if (NO_MATCH(s)) {
15,998 ( 0.05%) assert(tok == NULL);
.
. // considering the case: MATCH WHITESPACE MATCH WHITESPACE NO_MATCH
31,994 ( 0.10%) if (need_space && repeated > 0)// ^ ^ we are here
. P4_SetPosition(s, before_implicit); // ^ puke extra whitespace
. // ^ now we are here
.
39,995 ( 0.12%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. } else { // sufficient repetitions.
23,997 ( 0.07%) P4_RescueError(s);
1,705,685 ( 5.07%) => peppapeg.c:P4_RescueError (7,999x)
7,999 ( 0.02%) break;
. }
. }
.
. if (!NO_ERROR(s))
. goto finalize;
.
. if (P4_GetPosition(s) == before_implicit) {
. P4_RaiseError(s, P4_AdvanceError, "Repeated expression consumes no input");
-- line 694 ----------------------------------------
-- line 701 ----------------------------------------
. if (max != -1 && repeated == max) { // enough attempts
. P4_RescueError(s);
. break;
. }
.
. }
.
. // there should be no error when repetition is successful.
32,004 ( 0.10%) assert(NO_ERROR(s));
.
. // fails when attempts are excessive, e.g. repeated > max.
16,005 ( 0.05%) if (max != -1 && repeated > max) {
. P4_RaiseError(s, P4_MatchError, "excessive repetitions");
. goto finalize;
. }
.
40,005 ( 0.12%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. }
.
40,005 ( 0.12%) if (P4_GetPosition(s) == startpos) // success but no token is produced.
56,007 ( 0.17%) => peppapeg.c:P4_GetPosition (8,001x)
8,001 ( 0.02%) goto finalize;
.
.
. if (P4_NeedLift(s, e))
. return head;
.
. P4_Token* repetition = P4_CreateToken (s->content, startpos, P4_GetPosition(s), e);
. if (repetition == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
-- line 731 ----------------------------------------
-- line 733 ----------------------------------------
. }
.
. P4_AdoptToken(repetition->head, repetition->tail, head);
. return repetition;
.
. // cleanup before returning NULL.
. // tokens between head..tail should be freed.
. finalize:
40,005 ( 0.12%) P4_SetPosition(s, startpos);
80,010 ( 0.24%) => peppapeg.c:P4_SetPosition (8,001x)
24,003 ( 0.07%) P4_DeleteToken(head);
88,011 ( 0.26%) => peppapeg.c:P4_DeleteToken (8,001x)
8,001 ( 0.02%) return NULL;
16,002 ( 0.05%) }
.
. P4_PRIVATE(P4_Token*)
. P4_MatchPositive(P4_Source* s, P4_Expression* e) {
. assert(NO_ERROR(s) && e->ref_expr != NULL);
.
. P4_MarkPosition(s, startpos);
.
. P4_Token* token = P4_Match(s, e->ref_expr);
-- line 752 ----------------------------------------
-- line 772 ----------------------------------------
. } else if (s->err == P4_MatchError) {
. P4_RescueError(s);
. }
.
. return NULL;
. }
.
. P4_Token*
330,135 ( 0.98%) P4_Expression_dispatch(P4_Source* s, P4_Expression* e) {
66,027 ( 0.20%) P4_Token* result = NULL;
.
462,189 ( 1.37%) switch (e->kind) {
. case P4_Literal:
198,036 ( 0.59%) result = P4_MatchLiteral(s, e);
10,049,100 (29.88%) => peppapeg.c:P4_MatchLiteral (33,006x)
33,006 ( 0.10%) break;
. case P4_Range:
6 ( 0.00%) result = P4_MatchRange(s, e);
294 ( 0.00%) => peppapeg.c:P4_MatchRange (1x)
1 ( 0.00%) break;
. case P4_Reference:
60,048 ( 0.18%) result = P4_MatchReference(s, e);
32,993,043,406 (98087.2%) => peppapeg.c:P4_MatchReference'2 (10,004x)
32,992,905 (98.09%) => peppapeg.c:P4_MatchReference (4x)
10,008 ( 0.03%) break;
. case P4_Sequence:
30,048 ( 0.09%) result = P4_MatchSequence(s, e);
32,996,172 (98.10%) => peppapeg.c:P4_MatchSequence (1x)
5,008 ( 0.01%) break;
. case P4_Choice:
60,018 ( 0.18%) result = P4_MatchChoice(s, e);
33,006,260,274 (98126.5%) => peppapeg.c:P4_MatchChoice'2 (10,000x)
32,992,403 (98.09%) => peppapeg.c:P4_MatchChoice (3x)
10,003 ( 0.03%) break;
. case P4_Positive:
. result = P4_MatchPositive(s, e);
. break;
. case P4_Negative:
. result = P4_MatchNegative(s, e);
. break;
. case P4_Repeat:
48,006 ( 0.14%) result = P4_MatchRepeat(s, e);
26,325,867 (78.27%) => peppapeg.c:P4_MatchRepeat (8,001x)
8,001 ( 0.02%) break;
. case P4_BackReference:
. P4_RaiseError(s, P4_ValueError, "BackReference only works in Sequence.");
. result = NULL;
. break;
. default:
. P4_RaiseError(s, P4_ValueError, "no such kind");
. result = NULL;
. break;
. }
.
66,027 ( 0.20%) return result;
132,054 ( 0.39%) }
.
. /*
. * The match function updates the state given an expression.
. *
. * It returns a token linked list, NULL if no token is generated.
. * State pos will advance if needed.
. * Not-advancing pos / NULL returning token list do not indicate a failed match.
. * It fails when state err/errmsg are set.
. * It propagate the failed match up to the top level.
. */
. P4_Token*
330,135 ( 0.98%) P4_Match(P4_Source* s, P4_Expression* e) {
132,054 ( 0.39%) assert(e != NULL);
.
264,108 ( 0.79%) if (s->err != P4_Ok) {
. return NULL;
. }
.
66,027 ( 0.20%) P4_Error err = P4_Ok;
66,027 ( 0.20%) P4_Token* result = NULL;
.
344,180 ( 1.02%) if (IS_RULE(e) && (err = P4_PushFrame(s, e)) != P4_Ok) {
1,246 ( 0.00%) => peppapeg.c:P4_PushFrame (1x)
. P4_RaiseError(s, err, "failed to push frame");
. return NULL;
. }
.
396,162 ( 1.18%) result = P4_Expression_dispatch(s, e);
32,996,195 (98.10%) => peppapeg.c:P4_Expression_dispatch (1x)
.
334,171 ( 0.99%) if (IS_RULE(e) && (err = P4_PopFrame(s, NULL)) != P4_Ok) {
135 ( 0.00%) => peppapeg.c:P4_PopFrame (1x)
. P4_RaiseError(s, err, "failed to pop frame");
. P4_DeleteToken(result);
. return NULL;
. }
.
264,108 ( 0.79%) if (s->err != P4_Ok) {
150,078 ( 0.45%) P4_DeleteToken(result);
550,286 ( 1.64%) => peppapeg.c:P4_DeleteToken (50,026x)
100,052 ( 0.30%) return NULL;
. }
.
16,001 ( 0.05%) return result;
132,054 ( 0.39%) }
.
. P4_Token*
. P4_Match_any(P4_Source* s, P4_Expression* e) {
. P4_String str = P4_RemainingText(s);
.
. # define UTF8_CHARLEN(b) (( 0xe5000000 >> (( (b) >> 3 ) & 0x1e )) & 3 ) + 1
.
. P4_MarkPosition(s, startpos);
. size_t len = UTF8_CHARLEN(*str);
. P4_SetPosition(s, startpos+len);
.
. return NULL;
. }
.
. P4_PRIVATE(P4_Token*)
25,000 ( 0.07%) P4_MatchSpacedExpressions(P4_Source* s, P4_Expression* e) {
. // implicit whitespace is guaranteed to be an unnamed rule.
. // state flag is guaranteed to be none.
20,000 ( 0.06%) assert(NO_ERROR(s));
.
20,000 ( 0.06%) if (s->grammar == NULL)
. return NULL;
.
25,000 ( 0.07%) P4_Expression* implicit_whitespace = P4_GetWhitespaces(s->grammar);
70,000 ( 0.21%) => peppapeg.c:P4_GetWhitespaces (5,000x)
10,000 ( 0.03%) assert(implicit_whitespace != NULL);
.
. // (1) Temporarily set implicit whitespace to empty.
10,000 ( 0.03%) s->whitespacing = true;
.
. // (2) Perform implicit whitespace checks.
. // We won't do implicit whitespace inside an implicit whitespace expr.
30,000 ( 0.09%) P4_Token* result = P4_Match(s, implicit_whitespace);
18,188,545 (54.07%) => peppapeg.c:P4_Match'2 (5,000x)
20,000 ( 0.06%) if (NO_MATCH(s))
. P4_RescueError(s);
.
. // (3) Set implicit whitespace back.
10,000 ( 0.03%) s->whitespacing = false;
.
5,000 ( 0.01%) return result;
10,000 ( 0.03%) }
.
. P4_PRIVATE(P4_Token*)
. P4_MatchBackReference(P4_Source* s, P4_Expression* e, P4_Slice* backrefs, size_t index) {
. if (backrefs == NULL) {
. P4_RaiseError(s, P4_NullError, "");
. return NULL;
. }
.
-- line 908 ----------------------------------------
-- line 1001 ----------------------------------------
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->kind = P4_Numeric;
. expr->num = num;
. return expr;
. }
. */
.
. P4_PUBLIC(P4_Expression*)
210 ( 0.00%) P4_CreateLiteral(const P4_String literal, bool sensitive) {
140 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
8,050 ( 0.02%) => ???:malloc (35x)
70 ( 0.00%) expr->id = 0;
70 ( 0.00%) expr->kind = P4_Literal;
70 ( 0.00%) expr->flag = 0;
249 ( 0.00%) expr->literal = strdup(literal);
9,742 ( 0.03%) => ???:strdup (34x)
942 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
105 ( 0.00%) expr->sensitive = sensitive;
35 ( 0.00%) return expr;
70 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
45 ( 0.00%) P4_CreateRange(P4_Rune lower, P4_Rune upper) {
36 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
2,070 ( 0.01%) => ???:malloc (9x)
18 ( 0.00%) expr->id = 0;
18 ( 0.00%) expr->kind = P4_Range;
18 ( 0.00%) expr->flag = 0;
27 ( 0.00%) expr->range[0] = lower;
27 ( 0.00%) expr->range[1] = upper;
9 ( 0.00%) return expr;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
96 ( 0.00%) P4_CreateReference(P4_RuleID id) {
96 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
5,520 ( 0.02%) => ???:malloc (24x)
48 ( 0.00%) expr->id = 0;
48 ( 0.00%) expr->kind = P4_Reference;
48 ( 0.00%) expr->flag = 0;
72 ( 0.00%) expr->ref_id = id;
48 ( 0.00%) expr->ref_expr = NULL;
24 ( 0.00%) return expr;
48 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreatePositive(P4_Expression* refexpr) {
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->id = 0;
. expr->kind = P4_Positive;
. expr->flag = 0;
. expr->ref_expr = refexpr;
-- line 1047 ----------------------------------------
-- line 1054 ----------------------------------------
. expr->id = 0;
. expr->kind = P4_Negative;
. expr->flag = 0;
. expr->ref_expr = refexpr;
. return expr;
. }
.
. P4_PRIVATE(P4_Expression*)
96 ( 0.00%) P4_CreateContainer(size_t count) {
96 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
5,520 ( 0.02%) => ???:malloc (24x)
48 ( 0.00%) expr->id = 0;
48 ( 0.00%) expr->flag = 0;
72 ( 0.00%) expr->count = count;
192 ( 0.00%) expr->members = malloc(sizeof(P4_Expression*) * count);
5,520 ( 0.02%) => ???:malloc (24x)
24 ( 0.00%) return expr;
48 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
60 ( 0.00%) P4_CreateSequence(size_t count) {
60 ( 0.00%) P4_Expression* expr = P4_CreateContainer(count);
7,290 ( 0.02%) => peppapeg.c:P4_CreateContainer (15x)
.
30 ( 0.00%) if (expr == NULL)
. return NULL;
.
30 ( 0.00%) expr->kind = P4_Sequence;
.
15 ( 0.00%) return expr;
30 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
36 ( 0.00%) P4_CreateChoice(size_t count) {
36 ( 0.00%) P4_Expression* expr = P4_CreateContainer(count);
4,374 ( 0.01%) => peppapeg.c:P4_CreateContainer (9x)
.
18 ( 0.00%) if (expr == NULL)
. return NULL;
.
18 ( 0.00%) expr->kind = P4_Choice;
.
9 ( 0.00%) return expr;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
77 ( 0.00%) P4_CreateSequenceWithMembers(size_t count, ...) {
28 ( 0.00%) P4_Expression* expr = P4_CreateSequence(count);
3,507 ( 0.01%) => peppapeg.c:P4_CreateSequence (7x)
.
14 ( 0.00%) if (expr == NULL)
. return NULL;
.
. va_list members;
42 ( 0.00%) va_start (members, count);
.
132 ( 0.00%) for (int i = 0; i < count; i++) {
342 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
162 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
14 ( 0.00%) return expr;
.
. finalize:
. P4_DeleteExpression(expr);
. return NULL;
14 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
55 ( 0.00%) P4_CreateChoiceWithMembers(size_t count, ...) {
20 ( 0.00%) P4_Expression* expr = P4_CreateChoice(count);
2,505 ( 0.01%) => peppapeg.c:P4_CreateChoice (5x)
.
10 ( 0.00%) if (expr == NULL)
. return NULL;
.
. va_list members;
30 ( 0.00%) va_start (members, count);
.
150 ( 0.00%) for (int i = 0; i < count; i++) {
426 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
216 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
10 ( 0.00%) return expr;
.
. finalize:
. P4_DeleteExpression(expr);
. return NULL;
10 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
84 ( 0.00%) P4_CreateRepeatMinMax(P4_Expression* repeat, size_t min, size_t max) {
56 ( 0.00%) P4_Expression* expr = malloc(sizeof(P4_Expression));
3,220 ( 0.01%) => ???:malloc (14x)
28 ( 0.00%) expr->id = 0;
28 ( 0.00%) expr->flag = 0;
28 ( 0.00%) expr->kind = P4_Repeat;
42 ( 0.00%) expr->repeat_expr = repeat;
42 ( 0.00%) expr->repeat_min = min;
42 ( 0.00%) expr->repeat_max = max;
14 ( 0.00%) return expr;
28 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateRepeatMin(P4_Expression* repeat, size_t min) {
. return P4_CreateRepeatMinMax(repeat, min, -1);
. }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateRepeatMax(P4_Expression* repeat, size_t max) {
. return P4_CreateRepeatMinMax(repeat, -1, max);
. }
.
. P4_PUBLIC(P4_Expression*)
5 ( 0.00%) P4_CreateRepeatExact(P4_Expression* repeat, size_t minmax) {
6 ( 0.00%) return P4_CreateRepeatMinMax(repeat, minmax, minmax);
258 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (1x)
2 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
16 ( 0.00%) P4_CreateZeroOrOnce(P4_Expression* repeat) {
20 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 0, 1);
1,032 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (4x)
8 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
28 ( 0.00%) P4_CreateZeroOrMore(P4_Expression* repeat) {
35 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 0, -1);
1,806 ( 0.01%) => peppapeg.c:P4_CreateRepeatMinMax (7x)
14 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
8 ( 0.00%) P4_CreateOnceOrMore(P4_Expression* repeat) {
10 ( 0.00%) return P4_CreateRepeatMinMax(repeat, 1, -1);
516 ( 0.00%) => peppapeg.c:P4_CreateRepeatMinMax (2x)
4 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
. P4_CreateBackReference(size_t index) {
. P4_Expression* expr = malloc(sizeof(P4_Expression));
. expr->id = 0;
. expr->kind = P4_BackReference;
. expr->flag = 0;
. expr->backref_index = index;
-- line 1197 ----------------------------------------
-- line 1213 ----------------------------------------
. P4_PUBLIC(bool)
. P4_IsRule(P4_Expression* e) {
. if (e == NULL)
. return false;
.
. return e->id != 0;
. }
.
3 ( 0.00%) P4_PUBLIC(P4_Grammar*) P4_CreateGrammar(void) {
4 ( 0.00%) P4_Grammar* grammar = malloc(sizeof(P4_Grammar));
230 ( 0.00%) => ???:malloc (1x)
2 ( 0.00%) grammar->rules = NULL;
2 ( 0.00%) grammar->count = 0;
2 ( 0.00%) grammar->cap = 0;
2 ( 0.00%) grammar->spaced_count = -1;
2 ( 0.00%) grammar->spaced_rules = NULL;
2 ( 0.00%) grammar->depth = 1024*8;
1 ( 0.00%) return grammar;
2 ( 0.00%) }
.
. P4_PUBLIC(void)
4 ( 0.00%) P4_DeleteGrammar(P4_Grammar* grammar) {
2 ( 0.00%) if (grammar) {
91 ( 0.00%) for (int i = 0; i < grammar->count; i++) {
153 ( 0.00%) if (grammar->rules[i])
153 ( 0.00%) P4_DeleteExpression(grammar->rules[i]);
22,268 ( 0.07%) => peppapeg.c:P4_DeleteExpression (17x)
119 ( 0.00%) grammar->rules[i] = NULL;
. }
4 ( 0.00%) if (grammar->spaced_rules)
4 ( 0.00%) P4_DeleteExpression(grammar->spaced_rules);
260 ( 0.00%) => peppapeg.c:P4_DeleteExpression (1x)
5 ( 0.00%) free(grammar->rules);
83 ( 0.00%) => ???:free (1x)
4 ( 0.00%) free(grammar);
104 ( 0.00%) => ???:free (1x)
. }
3 ( 0.00%) }
.
. P4_PUBLIC(P4_Expression*)
136 ( 0.00%) P4_GetGrammarRule(P4_Grammar* grammar, P4_RuleID id) {
34 ( 0.00%) P4_Expression* rule = NULL;
1,779 ( 0.01%) for (int i = 0; i < grammar->count; i++) {
2,792 ( 0.01%) rule = grammar->rules[i];
2,094 ( 0.01%) if (rule && rule->id == id)
68 ( 0.00%) return rule;
. }
. return NULL;
68 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
54 ( 0.00%) P4_SetGrammarRuleFlag(P4_Grammar* grammar, P4_RuleID id, P4_ExpressionFlag flag) {
54 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
1,667 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (9x)
18 ( 0.00%) if (expr == NULL)
. return P4_NameError;
.
45 ( 0.00%) P4_SetExpressionFlag(expr, flag);
144 ( 0.00%) => peppapeg.c:P4_SetExpressionFlag (9x)
.
9 ( 0.00%) return P4_Ok;
18 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
102 ( 0.00%) P4_AddGrammarRule(P4_Grammar* grammar, P4_RuleID id, P4_Expression* expr) {
68 ( 0.00%) size_t cap = grammar->cap;
51 ( 0.00%) P4_Expression** rules = grammar->rules;
.
102 ( 0.00%) if (grammar == NULL || id == 0 || expr == NULL)
. return P4_NullError;
.
34 ( 0.00%) if (cap == 0) {
1 ( 0.00%) cap = 32;
7 ( 0.00%) rules = malloc(sizeof(P4_Expression*) * cap);
227 ( 0.00%) => ???:malloc (1x)
80 ( 0.00%) } else if (grammar->count >= cap) {
. cap <<= 1;
. rules = realloc(rules, sizeof(P4_Expression*) * cap);
. }
.
34 ( 0.00%) if (rules == NULL)
. return P4_MemoryError;
.
51 ( 0.00%) expr->id = id;
.
68 ( 0.00%) grammar->cap = cap;
51 ( 0.00%) grammar->rules = rules;
204 ( 0.00%) grammar->rules[grammar->count++] = expr;
.
17 ( 0.00%) return P4_Ok;
34 ( 0.00%) }
.
. P4_PUBLIC(P4_Source*)
5 ( 0.00%) P4_CreateSource(P4_String content, P4_RuleID rule_id) {
4 ( 0.00%) P4_Source* source = malloc(sizeof(P4_Source));
230 ( 0.00%) => ???:malloc (1x)
3 ( 0.00%) source->content = content;
3 ( 0.00%) source->rule_id = rule_id;
2 ( 0.00%) source->pos = 0;
2 ( 0.00%) source->err = P4_Ok;
2 ( 0.00%) source->errmsg = NULL;
2 ( 0.00%) source->root = NULL;
2 ( 0.00%) source->frame_stack = NULL;
2 ( 0.00%) source->frame_stack_size = 0;
2 ( 0.00%) source->whitespacing = false;
1 ( 0.00%) return source;
2 ( 0.00%) }
.
. P4_PUBLIC(void)
4 ( 0.00%) P4_DeleteSource(P4_Source* source) {
2 ( 0.00%) if (source == NULL)
. return;
.
3 ( 0.00%) P4_Frame* tmp = source->frame_stack;
5 ( 0.00%) while(source->frame_stack) {
. tmp = source->frame_stack->next;
. free(source->frame_stack);
. source->frame_stack = tmp;
. }
.
4 ( 0.00%) if (source->errmsg)
5 ( 0.00%) free(source->errmsg);
102 ( 0.00%) => ???:free (1x)
.
4 ( 0.00%) if (source->root)
4 ( 0.00%) P4_DeleteToken(source->root);
151,881 ( 0.45%) => peppapeg.c:P4_DeleteToken (1x)
.
5 ( 0.00%) free(source);
83 ( 0.00%) => ???:free (1x)
2 ( 0.00%) }
.
. P4_PUBLIC(P4_Token*)
. P4_GetSourceAst(P4_Source* source) {
. return source == NULL ? NULL : source->root;
. }
.
. P4_PUBLIC(P4_Position)
. P4_GetSourcePosition(P4_Source* source) {
. return source == NULL ? 0 : source->pos;
. }
.
. P4_PUBLIC(P4_Error)
5 ( 0.00%) P4_Parse(P4_Grammar* grammar, P4_Source* source) {
4 ( 0.00%) if (source->err != P4_Ok)
. return source->err;
.
4 ( 0.00%) if (source->root != NULL)
. return P4_Ok;
.
3 ( 0.00%) source->grammar = grammar;
.
7 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, source->rule_id);
314 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (1x)
6 ( 0.00%) P4_Token* tok = P4_Match(source, expr);
32,997,625 (98.10%) => peppapeg.c:P4_Match (1x)
.
3 ( 0.00%) source->root = tok;
.
2 ( 0.00%) return source->err;
2 ( 0.00%) }
.
.
. P4_PUBLIC(bool)
. P4_HasError(P4_Source* src) {
. if (src == NULL)
. return false;
.
. return src->err != P4_Ok;
-- line 1367 ----------------------------------------
-- line 1379 ----------------------------------------
. P4_GetErrorMessage(P4_Source* source) {
. if (source == NULL || source->errmsg == NULL)
. return NULL;
.
. return strdup(source->errmsg);
. }
.
. P4_PRIVATE(P4_Error)
4 ( 0.00%) P4_SetWhitespaces(P4_Grammar* grammar) {
1 ( 0.00%) size_t count = 0;
2 ( 0.00%) P4_RuleID ids[2] = {0};
2 ( 0.00%) P4_Expression* rules[2] = {0};
1 ( 0.00%) P4_Expression* repeat = NULL;
1 ( 0.00%) P4_Expression* rule = NULL;
.
92 ( 0.00%) for (int i = 0; i < grammar->count; i++) {
136 ( 0.00%) rule = grammar->rules[i];
.
85 ( 0.00%) if (IS_SPACED(rule)) {
4 ( 0.00%) ids[count] = rule->id;
7 ( 0.00%) rules[count] = P4_CreateReference(rule->id);
252 ( 0.00%) => peppapeg.c:P4_CreateReference (1x)
.
4 ( 0.00%) if (rules[count] == NULL)
. goto end;
.
4 ( 0.00%) rules[count]->ref_expr = rule;
.
1 ( 0.00%) count++;
. }
.
34 ( 0.00%) if (count > 1)
. break;
. }
.
2 ( 0.00%) if (count == 0) {
. return P4_Ok;
.
2 ( 0.00%) } else if (count == 1) {
3 ( 0.00%) repeat = rules[0];
.
. } else if (count == 2) {
. repeat = P4_CreateChoice(2);
. if (repeat == NULL)
. goto end;
. if (P4_SetMember(repeat, 0, rules[0]) != P4_Ok)
. goto end;
. if (P4_SetMember(repeat, 1, rules[1]) != P4_Ok)
. goto end;
. }
.
10 ( 0.00%) if ((grammar->spaced_rules = P4_CreateZeroOrMore(repeat))== NULL)
269 ( 0.00%) => peppapeg.c:P4_CreateZeroOrMore (1x)
. goto end;
.
3 ( 0.00%) grammar->spaced_count = count;
.
2 ( 0.00%) return P4_Ok;
.
. end:
. if (rules[0] != NULL)
. P4_DeleteExpression(rules[0]);
.
. if (rules[1] != NULL)
. P4_DeleteExpression(rules[1]);
.
-- line 1442 ----------------------------------------
-- line 1443 ----------------------------------------
. if (grammar->spaced_rules != NULL) {
. P4_DeleteExpression(grammar->spaced_rules);
. grammar->spaced_rules = NULL;
. }
.
. grammar->spaced_count = -1;
.
. return P4_MemoryError;
2 ( 0.00%) }
.
. P4_PRIVATE(P4_Expression*)
60,036 ( 0.18%) P4_GetWhitespaces(P4_Grammar* g) {
30,018 ( 0.09%) if (g == NULL)
. return NULL;
.
60,036 ( 0.18%) if (g->spaced_count == -1)
3 ( 0.00%) P4_SetWhitespaces(g);
923 ( 0.00%) => peppapeg.c:P4_SetWhitespaces (1x)
.
30,018 ( 0.09%) return g->spaced_rules;
30,018 ( 0.09%) }
.
. P4_PUBLIC(void)
45 ( 0.00%) P4_SetExpressionFlag(P4_Expression* e, P4_ExpressionFlag f) {
18 ( 0.00%) assert(e != NULL);
54 ( 0.00%) e->flag |= f;
27 ( 0.00%) }
.
. P4_PRIVATE(P4_Position)
339,138 ( 1.01%) P4_GetPosition(P4_Source* s) {
226,092 ( 0.67%) return s->pos;
226,092 ( 0.67%) }
.
. P4_PRIVATE(void)
176,080 ( 0.52%) P4_SetPosition(P4_Source* s, P4_Position pos) {
132,060 ( 0.39%) s->pos = pos;
132,060 ( 0.39%) }
.
. /*
. * Get the remaining text.
. */
. P4_PRIVATE(P4_String)
123,024 ( 0.37%) P4_RemainingText(P4_Source* s) {
205,040 ( 0.61%) return s->content + s->pos;
82,016 ( 0.24%) }
.
. P4_PUBLIC(P4_Error)
40 ( 0.00%) P4_AddLiteral(P4_Grammar* grammar, P4_RuleID id, const P4_String literal, bool sensitive) {
145 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateLiteral(literal, sensitive));
3,371 ( 0.01%) => peppapeg.c:P4_CreateLiteral (5x)
495 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (5x)
5 ( 0.00%) return P4_Ok;
10 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddRange(P4_Grammar* grammar, P4_RuleID id, P4_Rune lower, P4_Rune upper) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateRange(lower, upper));
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
-- line 1500 ----------------------------------------
-- line 1516 ----------------------------------------
. P4_PUBLIC(P4_Error)
. P4_AddSequence(P4_Grammar* grammar, P4_RuleID id, size_t size) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateContainer(size));
. P4_GetGrammarRule(grammar, id)->kind = P4_Sequence;
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
88 ( 0.00%) P4_AddSequenceWithMembers(P4_Grammar* grammar, P4_RuleID id, size_t count, ...) {
216 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateSequence(count));
4,008 ( 0.01%) => peppapeg.c:P4_CreateSequence (8x)
424 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (8x)
48 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
1,562 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (8x)
.
. va_list members;
48 ( 0.00%) va_start (members, count);
.
158 ( 0.00%) for (int i = 0; i < count; i++) {
413 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
198 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
16 ( 0.00%) return P4_Ok;
.
. finalize:
. P4_DeleteExpression(expr);
.
. return P4_MemoryError;
16 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddChoice(P4_Grammar* grammar, P4_RuleID id, size_t size) {
. P4_AddSomeGrammarRule(grammar, id, P4_CreateContainer(size));
. P4_GetGrammarRule(grammar, id)->kind = P4_Choice;
. return P4_Ok;
. }
.
. P4_PUBLIC(P4_Error)
44 ( 0.00%) P4_AddChoiceWithMembers(P4_Grammar* grammar, P4_RuleID id, size_t count, ...) {
108 ( 0.00%) P4_AddSomeGrammarRule(grammar, id, P4_CreateChoice(count));
2,004 ( 0.01%) => peppapeg.c:P4_CreateChoice (4x)
212 ( 0.00%) => peppapeg.c:P4_AddGrammarRule (4x)
24 ( 0.00%) P4_Expression* expr = P4_GetGrammarRule(grammar, id);
952 ( 0.00%) => peppapeg.c:P4_GetGrammarRule (4x)
.
. va_list members;
24 ( 0.00%) va_start (members, count);
.
74 ( 0.00%) for (int i = 0; i < count; i++) {
185 ( 0.00%) expr->members[i] = va_arg(members, P4_Expression*);
.
90 ( 0.00%) if (expr->members[i] == NULL) {
. goto finalize;
. }
. }
.
. va_end (members);
.
8 ( 0.00%) return P4_Ok;
.
. finalize:
. P4_DeleteExpression(expr);
.
. return P4_MemoryError;
8 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_SetMember(P4_Expression* expr, size_t offset, P4_Expression* member) {
. if (expr == NULL
. || member == NULL
. || expr->members == NULL
. || expr->count == 0) {
. return P4_NullError;
-- line 1588 ----------------------------------------
-- line 1645 ----------------------------------------
. || offset >= expr->count) {
. return NULL;
. }
.
. return expr->members[offset];
. }
.
. P4_PUBLIC(void)
424 ( 0.00%) P4_DeleteExpression(P4_Expression* expr) {
212 ( 0.00%) if (expr == NULL)
. return;
.
742 ( 0.00%) switch (expr->kind) {
. case P4_Literal:
140 ( 0.00%) if (expr->literal)
175 ( 0.00%) free(expr->literal);
520 ( 0.00%) => ???:free (5x)
105 ( 0.00%) break;
. // case P4_Reference is quite special - it is not the owner of ref_expr.
. case P4_Positive:
. case P4_Negative:
. if (expr->ref_expr)
. P4_DeleteExpression(expr->ref_expr);
. break;
. case P4_Sequence:
. case P4_Choice:
710 ( 0.00%) for (int i = 0; i < expr->count; i++) {
666 ( 0.00%) if (expr->members[i])
666 ( 0.00%) P4_DeleteExpression(expr->members[i]);
17,158 ( 0.05%) => peppapeg.c:P4_DeleteExpression'2 (32x)
518 ( 0.00%) expr->members[i] = NULL;
. }
120 ( 0.00%) free(expr->members);
1,248 ( 0.00%) => ???:free (12x)
48 ( 0.00%) expr->members = NULL;
24 ( 0.00%) break;
. case P4_Repeat:
56 ( 0.00%) if (expr->repeat_expr)
56 ( 0.00%) P4_DeleteExpression(expr->repeat_expr);
126 ( 0.00%) => peppapeg.c:P4_DeleteExpression'2 (1x)
28 ( 0.00%) break;
. default:
66 ( 0.00%) break;
. }
.
530 ( 0.00%) free(expr);
1,830 ( 0.01%) => ???:free (18x)
212 ( 0.00%) }
.
. P4_PUBLIC(P4_Error)
. P4_AddReference(P4_Grammar* grammar, P4_RuleID id, P4_RuleID ref) {
. if (ref == 0) {
. return P4_NullError;
. }
.
. P4_AddSomeGrammarRule(grammar, id, P4_CreateReference(ref));
-- line 1695 ----------------------------------------
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
16,385,652 (48.71%) events annotated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment