Last active
February 17, 2021 19:38
-
-
Save soasme/f31ea5f78420304a1b12b434a4a808e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------------------------------------------------------------------- | |
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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------------------------------------------------------------------- | |
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