Skip to content

Instantly share code, notes, and snippets.

@soasme
Created February 16, 2021 09:23
Show Gist options
  • Save soasme/38471063511aa14302e5ccad173767de to your computer and use it in GitHub Desktop.
Save soasme/38471063511aa14302e5ccad173767de to your computer and use it in GitHub Desktop.
--------------------------------------------------------------------------------
Profile data file 'callgrind.out.63642' (creator: callgrind-3.16.0)
--------------------------------------------------------------------------------
I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 190863280
Trigger: Program termination
Profiled target: ./a.out (PID 63642, part 1)
Events recorded: Ir
Events shown: Ir
Event sort order: Ir
Thresholds: 99
Include dirs:
User annotated:
Auto-annotation: on
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
1,265,470,759 (100.0%) PROGRAM TOTALS
--------------------------------------------------------------------------------
Ir file:function
--------------------------------------------------------------------------------
706,187,168 (55.80%) peppapeg.c:P4_NeedLoosen [/app/a.out]
320,620,450 (25.34%) peppapeg.c:P4_IsTight [/app/a.out]
170,320,160 (13.46%) peppapeg.c:P4_IsScoped [/app/a.out]
25,020,000 ( 1.98%) peppapeg.c:P4_NeedSquash [/app/a.out]
10,000,000 ( 0.79%) peppapeg.c:P4_IsSquashed [/app/a.out]
4,617,160 ( 0.36%) ???:_int_free [/usr/lib64/libc-2.28.so]
3,382,226 ( 0.27%) ???:malloc [/usr/lib64/ld-2.28.so]
2,727,160 ( 0.22%) peppapeg.c:P4_Match'2 [/app/a.out]
1,925,056 ( 0.15%) ???:__strlen_avx2 [/usr/lib64/libc-2.28.so]
1,848,485 ( 0.15%) ???:free [/usr/lib64/ld-2.28.so]
1,841,351 ( 0.15%) peppapeg.c:P4_MatchLiteral [/app/a.out]
1,705,988 ( 0.13%) peppapeg.c:P4_MatchChoice'2 [/app/a.out]
1,540,594 ( 0.12%) peppapeg.c:P4_IsRule [/app/a.out]
1,518,598 ( 0.12%) peppapeg.c:P4_Expression_dispatch'2 [/app/a.out]
--------------------------------------------------------------------------------
-- Auto-annotated source: peppapeg.c
--------------------------------------------------------------------------------
Ir
-- line 34 ----------------------------------------
.
. # 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.00%) {
10,016 ( 0.00%) void **pp = (void **) p;
20,032 ( 0.00%) if (*pp)
25,040 ( 0.00%) free (*pp);
436,536 ( 0.03%) => ???:free (5,008x)
15,024 ( 0.00%) }
.
. # 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 54 ----------------------------------------
-- line 132 ----------------------------------------
. *
. * > 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 167 ----------------------------------------
-- line 185 ----------------------------------------
. return 0;
. }
.
.
. /*
. * Determine if the implicit whitespace should be applied.
. */
. P4_PRIVATE(bool)
130,035 ( 0.01%) P4_NeedLoosen(P4_Source* s, P4_Expression* e) {
104,028 ( 0.01%) assert(s != NULL && e != NULL && s->frames_len >= 0);
.
. // Insert no whitespace
.
. // (1) when there is no implicit whitespace rule.
156,042 ( 0.01%) if (P4_GetWhitespaces(s->grammar) == NULL)
365,194 ( 0.03%) => peppapeg.c:P4_GetWhitespaces (26,007x)
. return false;
.
. // (2) when we're already matching whitespace.
104,028 ( 0.01%) if (s->whitespacing)
19,996 ( 0.00%) return false;
.
. // Traverse the frame stack from the highest frame,
48,205,132 ( 3.81%) for (int i = s->frames_len-1; i >=0; i--) {
. // (3) when e is inside a continuance expression and no tightness at all.
368,713,452 (29.14%) if (!P4_IsTight(s->frames[i]) && P4_IsScoped(s->frames[i]))
160,310,230 (12.67%) => peppapeg.c:P4_IsTight (16,031,023x)
160,310,160 (12.67%) => peppapeg.c:P4_IsScoped (16,031,016x)
. return true;
. }
.
. // traversing the frame stack since the inner most,
112,345,184 ( 8.88%) for (int i = 0; i < s->frames_len; i++) {
. // (3) when e is a tighted expression.
176,341,242 (13.93%) if (P4_IsTight(s->frames[i]))
160,310,220 (12.67%) => peppapeg.c:P4_IsTight (16,031,022x)
12 ( 0.00%) return false;
. }
.
16,003 ( 0.00%) return true;
52,014 ( 0.00%) }
.
. /*
. * Determine if inner tokens should be generated.
. */
. P4_PRIVATE(bool)
5,000 ( 0.00%) P4_NeedSquash(P4_Source* s, P4_Expression* e) {
. // A continuance expr forces no hollowness.
5,000 ( 0.00%) if (P4_IsScoped(e))
10,000 ( 0.00%) => peppapeg.c:P4_IsScoped (1,000x)
. return false;
.
. // Start from expr's parent.
3,007,000 ( 0.24%) for (int i = s->frames_len-2; i>=0; i--) {
. // Any of expr's ancestor being continuance forces no hollowness.
11,000,000 ( 0.87%) if (P4_IsScoped(s->frames[i]))
10,000,000 ( 0.79%) => peppapeg.c:P4_IsScoped (1,000,000x)
. return false;
.
. // Otherwise, being the descendant of hollowness token should be hollowed.
. // printf("frame %d: id=%lu, %d\n", i, s->frames[i]->id, s->frames[i]->flag);
11,000,000 ( 0.87%) if (P4_IsSquashed(s->frames[i]))
10,000,000 ( 0.79%) => peppapeg.c:P4_IsSquashed (1,000,000x)
. return true;
. }
.
1,000 ( 0.00%) return false;
2,000 ( 0.00%) }
.
. /*
. * Determine if the corresponding token to `e` should be ignored.
. *
. * 1. Intermediate expr.
. * 2. Bareness expr.
. * 3. Hollowed expr.
. */
. P4_PRIVATE(bool)
40,000 ( 0.00%) P4_NeedLift(P4_Source* s, P4_Expression* e) {
88,000 ( 0.01%) return !P4_IsRule(e) || P4_IsLifted(e) || P4_NeedSquash(s, e);
45,030,000 ( 3.56%) => peppapeg.c:P4_NeedSquash (1,000x)
88,000 ( 0.01%) => peppapeg.c:P4_IsRule (8,000x)
20,000 ( 0.00%) => peppapeg.c:P4_IsLifted (2,000x)
16,000 ( 0.00%) }
.
.
. /*
. * Raise an error.
. *
. * Set err and errmsg to state.
. */
. P4_PRIVATE(void)
234,054 ( 0.02%) P4_RaiseError(P4_Source* s, P4_Error err, P4_String errmsg) {
117,027 ( 0.01%) s->err = err;
.
156,036 ( 0.01%) if (s->errmsg != NULL)
195,040 ( 0.02%) free(s->errmsg);
3,237,664 ( 0.26%) => ???:free (39,008x)
.
273,063 ( 0.02%) s->errmsg = strdup(errmsg);
3,947,095 ( 0.31%) => ???:strdup (39,009x)
. /*
. size_t len = strlen(errmsg)+10;
. for (int i=s->frames_len-1; i>=0; i--) {
. if (s->frames[i]->name) {
. len += 9;
. } else {
. len += strlen(s->frames[i]->name);
. }
-- line 280 ----------------------------------------
-- line 288 ----------------------------------------
. } else {
. strcat(s->errmsg, "<UNKNOWN>");
. }
. strcat(s->errmsg, ": ");
. }
.
. strcat(s->errmsg, errmsg);
. */
117,027 ( 0.01%) }
.
.
. /*
. * Clear an error.
. *
. * It allows the parser to keep parsing the text.
. */
. P4_PRIVATE(void)
124,024 ( 0.01%) P4_RescueError(P4_Source* s) {
62,012 ( 0.00%) s->err = P4_Ok;
124,024 ( 0.01%) if (s->errmsg != NULL) {
155,034 ( 0.01%) free(s->errmsg);
2,573,415 ( 0.20%) => ???:free (31,005x)
677 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
62,012 ( 0.00%) s->errmsg = NULL;
186,036 ( 0.01%) s->errmsg = strdup("");
3,193,618 ( 0.25%) => ???:strdup (31,006x)
. }
93,018 ( 0.01%) }
.
.
. /*
. * Initialize a token.
. */
. P4_Token*
. P4_CreateToken (const P4_String str,
. size_t slice_i,
. size_t slice_j,
7,000 ( 0.00%) P4_Expression* expr) {
. P4_Token* token;
.
6,000 ( 0.00%) if ((token=malloc(sizeof(P4_Token))) == NULL)
45,000 ( 0.00%) => ???:malloc (1,000x)
. return NULL;
.
3,000 ( 0.00%) token->text = str;
3,000 ( 0.00%) token->slice.i = slice_i;
3,000 ( 0.00%) token->slice.j = slice_j;
3,000 ( 0.00%) token->expr = expr;
2,000 ( 0.00%) token->next = NULL;
2,000 ( 0.00%) token->head = NULL;
2,000 ( 0.00%) token->tail = NULL;
.
1,000 ( 0.00%) return token;
2,000 ( 0.00%) }
.
.
. /*
. * 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.00%) P4_DeleteTokenNode(P4_Token* token) {
2,000 ( 0.00%) assert(token != NULL);
2,000 ( 0.00%) if (token)
4,000 ( 0.00%) free(token);
103,893 ( 0.01%) => ???:free (1,000x)
3,000 ( 0.00%) }
.
.
. /*
. * Free all of the children tokens of the token.
. */
. P4_PRIVATE(void)
3,996 ( 0.00%) P4_DeleteTokenChildren(P4_Token* token) {
1,998 ( 0.00%) assert(token != NULL);
2,997 ( 0.00%) P4_Token* child = token->head;
999 ( 0.00%) P4_Token* tmp = NULL;
.
4,995 ( 0.00%) while (child) {
2,997 ( 0.00%) tmp = child->next;
3,996 ( 0.00%) if (child->head)
2,994 ( 0.00%) P4_DeleteTokenChildren(child);
151,586 ( 0.01%) => peppapeg.c:P4_DeleteTokenChildren'2 (1x)
2,997 ( 0.00%) P4_DeleteTokenNode(child);
119 ( 0.00%) => peppapeg.c:P4_DeleteTokenNode (1x)
1,998 ( 0.00%) child = tmp;
. }
2,997 ( 0.00%) }
.
.
. /*
. * Free the token list and all the children nodes of each
. * node in the token list.
. */
. P4_PUBLIC(void)
244,144 ( 0.02%) P4_DeleteToken(P4_Token* token) {
61,036 ( 0.00%) P4_Token* tmp = NULL;
183,110 ( 0.01%) while (token) {
3 ( 0.00%) tmp = token->next;
3 ( 0.00%) P4_DeleteTokenChildren(token);
151,738 ( 0.01%) => 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.01%) }
.
.
. /*
. * Push e into s->frames.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.00%) P4_PushFrame(P4_Source* s, P4_Expression* e) {
70,063 ( 0.01%) if (s->frames_len > (s->grammar->depth)) {
. return P4_StackError;
. }
.
30,027 ( 0.00%) P4_Expression** frames = s->frames;
.
. # define DEFAULT_CAP 32
.
40,036 ( 0.00%) if (s->frames_cap == 0) {
2 ( 0.00%) s->frames_cap = DEFAULT_CAP;
8 ( 0.00%) frames = malloc(sizeof(P4_Expression*) * s->frames_cap);
227 ( 0.00%) => ???:malloc (1x)
70,056 ( 0.01%) } else if (s->frames_len >= s->frames_cap - 1) {
30 ( 0.00%) s->frames_cap <<= 1;
64 ( 0.00%) frames = realloc(s->frames, sizeof(P4_Expression*) * s->frames_cap);
14,771 ( 0.00%) => ???:realloc (5x)
1,119 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
. }
20,018 ( 0.00%) if (frames == NULL)
. return P4_MemoryError;
.
30,027 ( 0.00%) s->frames = frames;
80,072 ( 0.01%) s->frames[s->frames_len] = e;
50,045 ( 0.00%) s->frames_len++;
.
10,009 ( 0.00%) return P4_Ok;
20,018 ( 0.00%) }
.
.
. /*
. * Pop e from s->frames.
. */
. P4_PRIVATE(P4_Error)
50,045 ( 0.00%) P4_PopFrame(P4_Source* s, P4_Expression** e) {
80,072 ( 0.01%) if (s->frames_cap == 0 || s->frames_len == 0)
. return P4_MemoryError;
.
40,036 ( 0.00%) assert(s->frames != NULL);
.
50,045 ( 0.00%) s->frames_len--;
.
20,018 ( 0.00%) if (e != NULL)
. *e = s->frames[s->frames_len];
.
80,072 ( 0.01%) s->frames[s->frames_len+1] = 0;
.
10,009 ( 0.00%) return P4_Ok;
20,018 ( 0.00%) }
.
.
. P4_PRIVATE(P4_Token*)
165,030 ( 0.01%) P4_MatchLiteral(P4_Source* s, P4_Expression* e) {
132,024 ( 0.01%) assert(NO_ERROR(s));
.
132,024 ( 0.01%) P4_String str = P4_RemainingText(s);
330,060 ( 0.03%) => peppapeg.c:P4_RemainingText (33,006x)
.
. # define EOT(s) (*(s) == 0x0)
.
132,024 ( 0.01%) if (EOT(str)) {
. P4_RaiseError(s, P4_MatchError, "eof");
. return NULL;
. }
.
198,040 ( 0.02%) size_t len = strlen(e->literal);
556,084 ( 0.04%) => ???:__strlen_avx2 (33,005x)
633 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
.
132,024 ( 0.01%) P4_MarkPosition(s, startpos);
231,042 ( 0.02%) => peppapeg.c:P4_GetPosition (33,006x)
165,030 ( 0.01%) if ((!e->sensitive && P4_CaseCmpInsensitive(e->literal, str, len) != 0)
462,088 ( 0.04%) || (e->sensitive && memcmp(e->literal, str, len) != 0)) {
297,087 ( 0.02%) => ???:__memcmp_avx2_movbe (33,005x)
627 ( 0.00%) => ???:_dl_runtime_resolve_xsave (1x)
155,025 ( 0.01%) P4_RaiseError(s, P4_MatchError, "expect literal");
6,604,162 ( 0.52%) => peppapeg.c:P4_RaiseError (31,005x)
62,010 ( 0.00%) return NULL;
. }
14,007 ( 0.00%) P4_SetPosition(s, startpos+len);
20,010 ( 0.00%) => peppapeg.c:P4_SetPosition (2,001x)
8,004 ( 0.00%) P4_MarkPosition(s, endpos);
14,007 ( 0.00%) => peppapeg.c:P4_GetPosition (2,001x)
.
14,007 ( 0.00%) if (P4_NeedLift(s, e))
54,027 ( 0.00%) => peppapeg.c:P4_NeedLift (2,001x)
4,002 ( 0.00%) 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.01%) }
.
. 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");
217 ( 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.01%) P4_GetReference(P4_Source* s, P4_Expression* e) {
56,016 ( 0.00%) if (e->ref_expr != NULL)
42,003 ( 0.00%) 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.00%) }
.
. P4_PRIVATE(P4_Token*)
50,040 ( 0.00%) P4_MatchReference(P4_Source* s, P4_Expression* e) {
40,032 ( 0.00%) assert(NO_ERROR(s));
.
40,068 ( 0.00%) 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.00%) if (e->ref_expr == NULL) {
. P4_RaiseError(s, P4_NameError, "");
. return NULL;
. }
.
40,032 ( 0.00%) P4_MarkPosition(s, startpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
70,056 ( 0.01%) P4_Token* reftok = P4_Match(s, e->ref_expr);
1,265,041,244 (99.97%) => peppapeg.c:P4_Match'2 (4x)
40,032 ( 0.00%) P4_MarkPosition(s, endpos);
28 ( 0.00%) => peppapeg.c:P4_GetPosition (4x)
.
. // Ref matching is terminated when error occurred.
40,032 ( 0.00%) if (!NO_ERROR(s))
16,018 ( 0.00%) return NULL;
.
. // The referenced token is returned when silenced.
13,993 ( 0.00%) if (P4_NeedLift(s, e))
27 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
3,998 ( 0.00%) 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.00%) }
.
. P4_PRIVATE(P4_Token*)
30,048 ( 0.00%) P4_MatchSequence(P4_Source* s, P4_Expression* e) {
20,032 ( 0.00%) assert(NO_ERROR(s));
.
5,008 ( 0.00%) P4_Expression *member = NULL;
5,008 ( 0.00%) P4_Token *head = NULL,
5,008 ( 0.00%) *tail = NULL,
5,008 ( 0.00%) *tok = NULL,
5,008 ( 0.00%) *whitespace = NULL;
.
55,088 ( 0.00%) 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.00%) if (backrefs == NULL) {
. P4_RaiseError(s, P4_MemoryError, "OOM");
. return NULL;
. }
.
20,032 ( 0.00%) P4_MarkPosition(s, startpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
89,071 ( 0.01%) for (int i = 0; i < e->count; i++) {
80,072 ( 0.01%) member = e->members[i];
.
. // Optional `WHITESPACE` and `COMMENT` are inserted between every member.
70,063 ( 0.01%) if (P4_NeedLoosen(s, e)
1,471 ( 0.00%) => peppapeg.c:P4_NeedLoosen (3x)
20,010 ( 0.00%) && i > 0) {
25,000 ( 0.00%) whitespace = P4_MatchSpacedExpressions(s, NULL);
4,023 ( 0.00%) => peppapeg.c:P4_MatchSpacedExpressions (2x)
20,000 ( 0.00%) if (!NO_ERROR(s)) goto finalize;
10,000 ( 0.00%) P4_AdoptToken(head, tail, whitespace);
. }
.
40,036 ( 0.00%) P4_MarkPosition(s, member_startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
.
40,036 ( 0.00%) if (member->kind == P4_BackReference) {
. tok = P4_MatchBackReference(s, e, backrefs, member->backref_index);
. if (!NO_ERROR(s)) goto finalize;
. } else {
60,054 ( 0.00%) tok = P4_Match(s, member);
1,265,041,180 (99.97%) => 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.00%) if (!NO_ERROR(s)) {
3,008 ( 0.00%) goto finalize;
. }
.
45,986 ( 0.00%) P4_AdoptToken(head, tail, tok);
49,007 ( 0.00%) backrefs[i].i = member_startpos;
63,009 ( 0.00%) backrefs[i].j = P4_GetPosition(s);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
. }
.
14,000 ( 0.00%) if (P4_NeedLift(s, e))
42 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
4,000 ( 0.00%) 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.00%) P4_SetPosition(s, startpos);
30,080 ( 0.00%) => peppapeg.c:P4_SetPosition (3,008x)
9,024 ( 0.00%) P4_DeleteToken(head);
33,088 ( 0.00%) => peppapeg.c:P4_DeleteToken (3,008x)
3,008 ( 0.00%) return NULL;
20,032 ( 0.00%) }
.
. P4_PRIVATE(P4_Token*)
50,015 ( 0.00%) P4_MatchChoice(P4_Source* s, P4_Expression* e) {
10,003 ( 0.00%) P4_Token* tok = NULL;
10,003 ( 0.00%) 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.00%) P4_MarkPosition(s, startpos);
21 ( 0.00%) => peppapeg.c:P4_GetPosition (3x)
241,073 ( 0.02%) for (int i = 0; i < e->count; i++) {
264,080 ( 0.02%) member = e->members[i];
198,060 ( 0.02%) tok = P4_Match(s, member);
1,265,038,949 (99.97%) => peppapeg.c:P4_Match'2 (10x)
134,040 ( 0.01%) if (NO_ERROR(s)) break;
124,040 ( 0.01%) if (NO_MATCH(s)) {
. // retry until the last one.
217,070 ( 0.02%) if (i < e->count-1) {
69,021 ( 0.01%) P4_RescueError(s);
2,082 ( 0.00%) => peppapeg.c:P4_RescueError (7x)
138,042 ( 0.01%) 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.00%) P4_RaiseError(s, P4_MatchError, "no match");
418 ( 0.00%) => peppapeg.c:P4_RaiseError (2x)
8,003 ( 0.00%) goto finalize;
. }
. }
. }
8,000 ( 0.00%) P4_MarkPosition(s, endpos);
7 ( 0.00%) => peppapeg.c:P4_GetPosition (1x)
.
14,000 ( 0.00%) if (P4_NeedLift(s, e))
27 ( 0.00%) => peppapeg.c:P4_NeedLift (1x)
2,000 ( 0.00%) return tok;
.
8,000 ( 0.00%) P4_Token* oneof = P4_CreateToken (s->content, startpos, endpos, e);
79,000 ( 0.01%) => peppapeg.c:P4_CreateToken (1,000x)
2,000 ( 0.00%) if (oneof == NULL) {
. P4_RaiseError(s, P4_MemoryError, "oom");
. goto finalize;
. }
.
26,975 ( 0.00%) P4_AdoptToken(oneof->head, oneof->tail, tok);
2,000 ( 0.00%) return oneof;
.
. finalize:
40,015 ( 0.00%) P4_SetPosition(s, startpos);
20 ( 0.00%) => peppapeg.c:P4_SetPosition (2x)
32,012 ( 0.00%) free(tok);
24 ( 0.00%) => ???:free (2x)
8,003 ( 0.00%) return NULL;
20,006 ( 0.00%) }
.
. /*
. * Repetition matcher function.
. *
. * Returns a token in a greedy fashion.
. *
. * There are seven repetition mode: zeroormore, zerooronce,
. */
. P4_PRIVATE(P4_Token*)
40,005 ( 0.00%) P4_MatchRepeat(P4_Source* s, P4_Expression* e) {
24,003 ( 0.00%) size_t min = -1, max = -1, repeated = 0;
.
32,004 ( 0.00%) assert(e->repeat_min != min || e->repeat_max != max); // need at least one of min/max.
32,004 ( 0.00%) assert(e->repeat_expr != NULL); // need repeat expression.
32,004 ( 0.00%) 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.01%) if (IS_PROGRESSING(e->repeat_expr->kind) ||
24,003 ( 0.00%) (IS_REF(e->repeat_expr)
126,036 ( 0.01%) && IS_PROGRESSING(P4_GetReference(s, e->repeat_expr)->kind))) {
196,790 ( 0.02%) => peppapeg.c:P4_GetReference (14,004x)
. P4_RaiseError(s, P4_AdvanceError, "no progressing in repetition");
. return NULL;
. }
.
24,003 ( 0.00%) min = e->repeat_min;
24,003 ( 0.00%) max = e->repeat_max;
.
32,004 ( 0.00%) P4_Position startpos = P4_GetPosition(s);
56,007 ( 0.00%) => peppapeg.c:P4_GetPosition (8,001x)
32,004 ( 0.00%) P4_Token *head = NULL, *tail = NULL, *tok = NULL, *whitespace = NULL;
.
56,007 ( 0.00%) while (*P4_RemainingText(s) != '\0') {
80,010 ( 0.01%) => peppapeg.c:P4_RemainingText (8,001x)
31,996 ( 0.00%) P4_MarkPosition(s, before_implicit);
55,993 ( 0.00%) => peppapeg.c:P4_GetPosition (7,999x)
.
. // SPACED rule expressions are inserted between every repetition.
55,993 ( 0.00%) if (P4_NeedLoosen(s, e)
222,560,084 (17.59%) => peppapeg.c:P4_NeedLoosen (7,999x)
5,998 ( 0.00%) && repeated > 0 ) {
. whitespace = P4_MatchSpacedExpressions(s, NULL);
. if (!NO_ERROR(s)) goto finalize;
. P4_AdoptToken(head, tail, whitespace);
. }
.
55,993 ( 0.00%) tok = P4_Match(s, e->repeat_expr);
96,296,671 ( 7.61%) => peppapeg.c:P4_Match'2 (7,999x)
.
31,996 ( 0.00%) if (NO_MATCH(s)) {
15,998 ( 0.00%) assert(tok == NULL);
.
. // considering the case: MATCH WHITESPACE MATCH WHITESPACE NO_MATCH
55,993 ( 0.00%) if (P4_NeedLoosen(s, e) // ^ ^
222,560,084 (17.59%) => peppapeg.c:P4_NeedLoosen (7,999x)
5,998 ( 0.00%) && repeated > 0) // ^ ^ we are here
. P4_SetPosition(s, before_implicit); // ^ puke extra whitespace
. // ^ now we are here
.
39,995 ( 0.00%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. } else { // sufficient repetitions.
23,997 ( 0.00%) P4_RescueError(s);
1,695,788 ( 0.13%) => peppapeg.c:P4_RescueError (7,999x)
7,999 ( 0.00%) break;
. }
. }
.
. if (!NO_ERROR(s))
. goto finalize;
.
. if (P4_GetPosition(s) == before_implicit) {
. P4_RaiseError(s, P4_AdvanceError, "Repeated expression consumes no input");
-- line 748 ----------------------------------------
-- line 755 ----------------------------------------
. if (max != -1 && repeated == max) { // enough attempts
. P4_RescueError(s);
. break;
. }
.
. }
.
. // there should be no error when repetition is successful.
32,004 ( 0.00%) assert(NO_ERROR(s));
.
. // fails when attempts are excessive, e.g. repeated > max.
16,005 ( 0.00%) if (max != -1 && repeated > max) {
. P4_RaiseError(s, P4_MatchError, "excessive repetitions");
. goto finalize;
. }
.
40,005 ( 0.00%) if (min != -1 && repeated < min) {
. P4_RaiseError(s, P4_MatchError, "insufficient repetitions");
. goto finalize;
. }
.
40,005 ( 0.00%) if (P4_GetPosition(s) == startpos) // success but no token is produced.
56,007 ( 0.00%) => peppapeg.c:P4_GetPosition (8,001x)
8,001 ( 0.00%) 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 785 ----------------------------------------
-- line 787 ----------------------------------------
. }
.
. P4_AdoptToken(repetition->head, repetition->tail, head);
. return repetition;
.
. // cleanup before returning NULL.
. // tokens between head..tail should be freed.
. finalize:
40,005 ( 0.00%) P4_SetPosition(s, startpos);
80,010 ( 0.01%) => peppapeg.c:P4_SetPosition (8,001x)
24,003 ( 0.00%) P4_DeleteToken(head);
88,011 ( 0.01%) => peppapeg.c:P4_DeleteToken (8,001x)
8,001 ( 0.00%) return NULL;
16,002 ( 0.00%) }
.
. 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 806 ----------------------------------------
-- line 826 ----------------------------------------
. } else if (s->err == P4_MatchError) {
. P4_RescueError(s);
. }
.
. return NULL;
. }
.
. P4_Token*
330,135 ( 0.03%) P4_Expression_dispatch(P4_Source* s, P4_Expression* e) {
66,027 ( 0.01%) P4_Token* result = NULL;
.
462,189 ( 0.04%) switch (e->kind) {
. case P4_Literal:
198,036 ( 0.02%) result = P4_MatchLiteral(s, e);
9,949,090 ( 0.79%) => peppapeg.c:P4_MatchLiteral (33,006x)
33,006 ( 0.00%) break;
. case P4_Range:
6 ( 0.00%) result = P4_MatchRange(s, e);
302 ( 0.00%) => peppapeg.c:P4_MatchRange (1x)
1 ( 0.00%) break;
. case P4_Reference:
60,048 ( 0.00%) result = P4_MatchReference(s, e);
1,674,584,905,215 (132329.0%) => peppapeg.c:P4_MatchReference'2 (10,004x)
1,265,042,074 (99.97%) => peppapeg.c:P4_MatchReference (4x)
10,008 ( 0.00%) break;
. case P4_Sequence:
30,048 ( 0.00%) result = P4_MatchSequence(s, e);
1,265,047,368 (99.97%) => peppapeg.c:P4_MatchSequence (1x)
5,008 ( 0.00%) break;
. case P4_Choice:
60,018 ( 0.00%) result = P4_MatchChoice(s, e);
1,675,312,163,116 (132386.5%) => peppapeg.c:P4_MatchChoice'2 (10,000x)
1,265,042,118 (99.97%) => peppapeg.c:P4_MatchChoice (3x)
10,003 ( 0.00%) 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.00%) result = P4_MatchRepeat(s, e);
544,855,534 (43.06%) => peppapeg.c:P4_MatchRepeat (8,001x)
8,001 ( 0.00%) 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.01%) return result;
132,054 ( 0.01%) }
.
. /*
. * 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.03%) P4_Match(P4_Source* s, P4_Expression* e) {
132,054 ( 0.01%) assert(e != NULL);
.
264,108 ( 0.02%) if (s->err != P4_Ok) {
. return NULL;
. }
.
66,027 ( 0.01%) P4_Error err = P4_Ok;
66,027 ( 0.01%) P4_Token* result = NULL;
.
410,207 ( 0.03%) if (P4_IsRule(e) && (err = P4_PushFrame(s, e)) != P4_Ok) {
277 ( 0.00%) => peppapeg.c:P4_PushFrame (1x)
11 ( 0.00%) => peppapeg.c:P4_IsRule (1x)
. P4_RaiseError(s, err, "failed to push frame");
. return NULL;
. }
.
396,162 ( 0.03%) result = P4_Expression_dispatch(s, e);
1,265,047,391 (99.97%) => peppapeg.c:P4_Expression_dispatch (1x)
.
400,198 ( 0.03%) if (P4_IsRule(e) && (err = P4_PopFrame(s, NULL)) != P4_Ok) {
35 ( 0.00%) => peppapeg.c:P4_PopFrame (1x)
11 ( 0.00%) => peppapeg.c:P4_IsRule (1x)
. P4_RaiseError(s, err, "failed to pop frame");
. P4_DeleteToken(result);
. return NULL;
. }
.
264,108 ( 0.02%) if (s->err != P4_Ok) {
150,078 ( 0.01%) P4_DeleteToken(result);
550,286 ( 0.04%) => peppapeg.c:P4_DeleteToken (50,026x)
100,052 ( 0.01%) return NULL;
. }
.
16,001 ( 0.00%) return result;
132,054 ( 0.01%) }
.
. 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.00%) 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.00%) assert(NO_ERROR(s));
.
20,000 ( 0.00%) if (s->grammar == NULL)
. return NULL;
.
25,000 ( 0.00%) P4_Expression* implicit_whitespace = P4_GetWhitespaces(s->grammar);
70,000 ( 0.01%) => peppapeg.c:P4_GetWhitespaces (5,000x)
10,000 ( 0.00%) assert(implicit_whitespace != NULL);
.
. // (1) Temporarily set implicit whitespace to empty.
10,000 ( 0.00%) s->whitespacing = true;
.
. // (2) Perform implicit whitespace checks.
. // We won't do implicit whitespace inside an implicit whitespace expr.
30,000 ( 0.00%) P4_Token* result = P4_Match(s, implicit_whitespace);
18,321,591 ( 1.45%) => peppapeg.c:P4_Match'2 (5,000x)
20,000 ( 0.00%) if (NO_MATCH(s))
. P4_RescueError(s);
.
. // (3) Set implicit whitespace back.
10,000 ( 0.00%) s->whitespacing = false;
.
5,000 ( 0.00%) return result;
10,000 ( 0.00%) }
.
. 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 962 ----------------------------------------
-- line 1055 ----------------------------------------
. 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.00%) => ???: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,750 ( 0.00%) => ???: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.00%) => ???: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.00%) => ???: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 1101 ----------------------------------------
-- line 1108 ----------------------------------------
. 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.00%) => ???: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.00%) => ???: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.00%) => 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.00%) => 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.00%) => 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.00%) => 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.00%) => ???: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.00%) => 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 1251 ----------------------------------------
-- line 1260 ----------------------------------------
. if (e->id != 0 || id == 0)
. return P4_ValueError;
.
. e->id = id;
. return P4_Ok;
. }
.
. P4_PUBLIC(bool)
420,162 ( 0.03%) P4_IsRule(P4_Expression* e) {
280,108 ( 0.02%) if (e == NULL)
. return false;
.
560,216 ( 0.04%) return e->id != 0;
280,108 ( 0.02%) }
.
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,142 ( 0.00%) => 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.00%) for (int i = 0; i < grammar->count; i++) {
2,792 ( 0.00%) rule = grammar->rules[i];
2,094 ( 0.00%) 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->frames = NULL;
2 ( 0.00%) source->frames_len = 0;
2 ( 0.00%) source->frames_cap = 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;
.
4 ( 0.00%) if (source->frames)
5 ( 0.00%) free(source->frames);
128 ( 0.00%) => ???:free (1x)
.
4 ( 0.00%) if (source->errmsg)
5 ( 0.00%) free(source->errmsg);
83 ( 0.00%) => ???:free (1x)
.
4 ( 0.00%) if (source->root)
4 ( 0.00%) P4_DeleteToken(source->root);
151,881 ( 0.01%) => 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);
1,265,047,776 (99.97%) => 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 1418 ----------------------------------------
-- line 1430 ----------------------------------------
. 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 (P4_IsSpaced(rule)) {
170 ( 0.00%) => peppapeg.c:P4_IsSpaced (17x)
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 1493 ----------------------------------------
-- line 1494 ----------------------------------------
. 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*)
124,028 ( 0.01%) P4_GetWhitespaces(P4_Grammar* g) {
62,014 ( 0.00%) if (g == NULL)
. return NULL;
.
124,028 ( 0.01%) if (g->spaced_count == -1)
3 ( 0.00%) P4_SetWhitespaces(g);
1,093 ( 0.00%) => peppapeg.c:P4_SetWhitespaces (1x)
.
62,014 ( 0.00%) return g->spaced_rules;
62,014 ( 0.00%) }
.
. 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 ( 0.03%) P4_GetPosition(P4_Source* s) {
226,092 ( 0.02%) return s->pos;
226,092 ( 0.02%) }
.
. P4_PRIVATE(void)
176,080 ( 0.01%) P4_SetPosition(P4_Source* s, P4_Position pos) {
132,060 ( 0.01%) s->pos = pos;
132,060 ( 0.01%) }
.
. /*
. * Get the remaining text.
. */
. P4_PRIVATE(P4_String)
123,024 ( 0.01%) P4_RemainingText(P4_Source* s) {
205,040 ( 0.02%) return s->content + s->pos;
82,016 ( 0.01%) }
.
. 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.00%) => 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 1551 ----------------------------------------
-- line 1567 ----------------------------------------
. 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.00%) => 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.00%) => 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 1639 ----------------------------------------
-- line 1696 ----------------------------------------
. || 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);
478 ( 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,097 ( 0.00%) => peppapeg.c:P4_DeleteExpression'2 (32x)
518 ( 0.00%) expr->members[i] = NULL;
. }
120 ( 0.00%) free(expr->members);
1,225 ( 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.00%) => ???: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 1746 ----------------------------------------
-- line 1837 ----------------------------------------
.
. return P4_CopySliceString(token->text, &(token->slice));
. }
.
. /*
. * Determine if expression has flag P4_FLAG_SQUASHED.
. */
. P4_PUBLIC(bool)
3,000,000 ( 0.24%) P4_IsSquashed(P4_Expression* e) {
5,000,000 ( 0.40%) return (e->flag & P4_FLAG_SQUASHED) != 0;
2,000,000 ( 0.16%) }
.
. /*
. * Determine if expression has flag P4_FLAG_LIFTED.
. */
. P4_PUBLIC(bool)
6,000 ( 0.00%) P4_IsLifted(P4_Expression* e) {
10,000 ( 0.00%) return (e->flag & P4_FLAG_LIFTED) != 0;
4,000 ( 0.00%) }
.
. /*
. * Determine if expression has flag P4_FLAG_TIGHT.
. */
. P4_PUBLIC(bool)
96,186,135 ( 7.60%) P4_IsTight(P4_Expression* e) {
160,310,225 (12.67%) return (e->flag & P4_FLAG_TIGHT) != 0;
64,124,090 ( 5.07%) }
.
. /*
. * Determine if expression has flag P4_FLAG_SPACED.
. */
. P4_PUBLIC(bool)
51 ( 0.00%) P4_IsSpaced(P4_Expression* e) {
85 ( 0.00%) return (e->flag & P4_FLAG_SPACED) != 0;
34 ( 0.00%) }
.
. /*
. * Set expression flag P4_FLAG_SQUASHED.
. */
. P4_PUBLIC(bool)
51,096,048 ( 4.04%) P4_IsScoped(P4_Expression* e) {
85,160,080 ( 6.73%) return (e->flag & P4_FLAG_SCOPED) != 0;
34,064,032 ( 2.69%) }
.
. /*
. * Set expression flag P4_FLAG_SQUASHED.
. */
. P4_PUBLIC(void)
. P4_SetSquashed(P4_Expression* e) {
. return P4_SetExpressionFlag(e, P4_FLAG_SQUASHED);
. }
-- line 1887 ----------------------------------------
--------------------------------------------------------------------------------
Ir
--------------------------------------------------------------------------------
1,250,117,915 (98.79%) events annotated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment