aboutsummaryrefslogtreecommitdiff
path: root/src/prc1/parse.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-10-01 01:04:30 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-10-05 00:38:49 +0200
commit2b0d4ead061a39da9dbd705c18c9955549c4d405 (patch)
tree1412ac39adce3428b96caf67b1e7543f6c1246a5 /src/prc1/parse.c
parent9140988be4e5bb028b7140aca1a67af1370c72a7 (diff)
downloadprc-sym.tar.gz
WIP symsym
Diffstat (limited to 'src/prc1/parse.c')
-rw-r--r--src/prc1/parse.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/src/prc1/parse.c b/src/prc1/parse.c
index 1c3aba2..81bb2ff 100644
--- a/src/prc1/parse.c
+++ b/src/prc1/parse.c
@@ -4,6 +4,7 @@
#include "fn.h"
#include "lex.h"
#include "lit.h"
+#include "sym.h"
#include "prv.h"
#include "type.h"
#include <stddef.h>
@@ -45,6 +46,29 @@ static const char *expected(const struct step *s)
return s->id ? s->id : tmap[s->type];
}
+static int unexpected(const struct tk *tk)
+{
+ switch (tk->type)
+ {
+ case LIT:
+ errloc(tk, "unexpected literal \"%s\"", tk->s);
+ break;
+ case NUM:
+ errloc(tk, "unexpected number %s", tk->s);
+ break;
+ case ID:
+ errloc(tk, "unexpected %s %s", kw(tk->s) ?
+ "keyword" : "identifier", tk->s);
+ break;
+ case ANY:
+ case UNDEF:
+ errloc(tk, "%s: unreachable", __func__);
+ break;
+ }
+
+ return -1;
+}
+
static int iter(const struct lex *l, struct prv *p)
{
struct pos *pos = p->pos;
@@ -52,41 +76,28 @@ static int iter(const struct lex *l, struct prv *p)
const struct tk *tk = p->tk;
if (!pos)
- return p->entry(l, p);
+ {
+ if (lex_eof(l, p->stk))
+ return 0;
+
+ return p->entry(l, p) ? -1 : 1;
+ }
pos = &p->pos[p->i];
+ /* no rules have matched the current token */
if (!(s = pos->step))
{
- if (lex_eof(l, tk))
- return 0;
- else if (p->n > 1)
+ if (p->n > 1)
return pop(l, p) ? -1 : 1;
+ else if (lex_eof(l, tk))
+ return 0;
else
- {
- switch (tk->type)
- {
- case LIT:
- errloc(tk, "unexpected literal \"%s\"", tk->s);
- break;
- case NUM:
- errloc(tk, "unexpected number %s", tk->s);
- break;
- case ID:
- errloc(tk, "unexpected %s %s", kw(tk->s) ?
- "keyword" : "identifier", tk->s);
- break;
- case ANY:
- case UNDEF:
- errloc(tk, "%s: unreachable", __func__);
- break;
- }
-
- return -1;
- }
+ return unexpected(tk);
}
else if (lex_eof(l, tk))
{
+ /* pop all remaining rules */
if (p->stk == p->tk)
return pop(l, p) ? -1 : 1;
else if (s->type)
@@ -101,41 +112,26 @@ static int iter(const struct lex *l, struct prv *p)
}
}
+ /* rule has been completely parsed, execute */
if (!s->type)
- return pos->seq->fn(l, p);
- else if ((s->type == ID || s->type == ANY) && !s->id && kw(tk->s)
- && !s->chain)
- {
- if (tk != p->stk || !p->n)
- {
- errloc(tk, "unexpected keyword %s", tk->s);
- return -1;
- }
- else if (pop(l, p))
- return -1;
-
- pos = &p->pos[p->i];
- }
- else if ((s->type != tk->type && s->type != ANY)
+ return pos->seq->fn(l, p) ? -1 : 1;
+ /* skip if: */
+ else if (
+ /* rule type does not match */
+ s->type != tk->type
+ /* ID does not match */
|| (s->type == ID && s->id && strcmp(s->id, tk->s))
- || (s->type == ID && kw(tk->s) && s->chain))
+ /* rule does not expect a keyword */
+ || (s->type == ID && !s->id && kw(tk->s)))
{
+ /* move to next rule on no match */
pos->step = (++pos->seq)->steps;
p->tk = p->stk;
}
+ /* move to next step */
else
{
- const struct tk *next = tk + 1;
-
- if (!s->chain)
- pos->step++;
- else if (!lex_eof(l, next))
- {
- if (s->chain && kw(next->s))
- pos->step++;
- }
- else
- pos->step++;
+ pos->step++;
if (!lex_eof(l, p->tk))
p->tk++;
@@ -146,6 +142,7 @@ static int iter(const struct lex *l, struct prv *p)
static void free_prv(struct prv *p)
{
+ sym_free(p->s);
free(p->tdc);
free(p->pos);
}