commit 1f4874cced9c4f1308556b07e835bb47547becc0
parent 3e7e69413c50005c9e35de23fab8fc8ec9604f68
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 12 Jun 2012 21:53:47 +0200
Rewrite the expression parser
This parser applies the rule in the correct order and runs actions each time
that one of the rule matches.
Diffstat:
M | Makefile | | | 2 | +- |
A | code.c | | | 253 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | code.h | | | 8 | ++++++++ |
M | expr.c | | | 276 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
4 files changed, 469 insertions(+), 70 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
-OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o keyword.o
+OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o keyword.o code.o
LIBS =
all: kcc
diff --git a/code.c b/code.c
@@ -0,0 +1,253 @@
+
+#include "cc.h"
+#include "code.h"
+#include "symbol.h"
+
+
+#define NR_MACHINE_OP 30
+#define NR_SYM_STACK 30
+
+static struct symbol *stack[NR_SYM_STACK];
+static struct symbol **stackp = stack;
+
+void push(register struct symbol *sym)
+{
+ if (stackp == &stack[NR_SYM_STACK])
+ error("out of memory");
+ *stackp++ = sym;
+}
+
+void code(void *data)
+{
+}
+
+void execute(void)
+{
+}
+
+
+
+void gen_ary(void)
+{
+ puts("gen_ary");
+}
+
+void gen_call(void)
+{
+ puts("gen_call");
+}
+
+void gen_or(void)
+{
+ puts("gen_or");
+}
+
+void gen_tern(void)
+{
+ puts("gen_tern");
+}
+
+void gen_band(void)
+{
+ puts("gen_band");
+}
+
+void gen_bxor(void)
+{
+ puts("gen_bxor");
+}
+
+void gen_bor(void)
+{
+ puts("gen_bor");
+}
+
+void gen_and(void)
+{
+ puts("gen_and");
+}
+
+void gen_sizeof(void)
+{
+ puts("gen_sizeof");
+}
+
+void gen_field(void)
+{
+ puts("gen_field");
+}
+
+void gen_ptr(void)
+{
+ puts("gen_ptr");
+}
+
+void gen_preinc(void)
+{
+ puts("gen_preinc");
+}
+
+void gen_predec(void)
+{
+ puts("gen_predec");
+}
+
+void gen_addr(void)
+{
+ puts("gen_addr");
+}
+
+void gen_indir(void)
+{
+ puts("gen_indir");
+}
+
+void gen_minus(void)
+{
+ puts("gen_minus");
+}
+
+void gen_plus(void)
+{
+ puts("gen_plus");
+}
+
+void gen_cpl(void)
+{
+ puts("gen_cpl");
+}
+
+void gen_neg(void)
+{
+ puts("gen_neg");
+}
+
+void gen_mul(void)
+{
+ puts("gen_mul");
+}
+
+void gen_div(void)
+{
+ puts("gen_div");
+}
+
+void gen_mod(void)
+{
+ puts("gen_mod");
+}
+
+void gen_add(void)
+{
+ puts("gen_add");
+}
+
+void gen_sub(void)
+{
+ puts("gen_sub");
+}
+
+void gen_shl(void)
+{
+ puts("gen_shl");
+}
+
+void gen_shr(void)
+{
+ puts("gen_shr");
+}
+
+void gen_lt(void)
+{
+ puts("gen_lt");
+}
+
+void gen_gt(void)
+{
+ puts("gen_gt");
+}
+
+void gen_ge(void)
+{
+ puts("gen_ge");
+}
+
+void gen_le(void)
+{
+ puts("gen_le");
+}
+
+void gen_eq(void)
+{
+ puts("gen_eq");
+}
+
+void gen_ne(void)
+{
+ puts("gen_ne");
+}
+
+void gen_a_mul(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_div(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_mod(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_add(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_sub(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_shl(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_shr(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_and(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_xor(void)
+{
+ puts("gen_a");
+}
+
+void gen_a_or(void)
+{
+ puts("gen_a");
+}
+
+void gen_postinc(void)
+{
+ puts("gen_postinc");
+}
+
+void gen_postdec(void)
+{
+ puts("gen_postdec");
+}
+
+void gen_assign(void)
+{
+ puts("gen_assign");
+}
diff --git a/code.h b/code.h
@@ -0,0 +1,8 @@
+#ifndef CODE_H
+#define CODE_H
+
+struct symbol;
+extern void push(register struct symbol *sym);
+extern void runcode(void);
+
+#endif
diff --git a/expr.c b/expr.c
@@ -1,22 +1,38 @@
#include <stddef.h>
+#include <stdio.h>
+#include "cc.h"
#include "tokens.h"
#include "symbol.h"
#include "syntax.h"
+#include "code.h"
-#include <stdio.h> /* TODO: remove this */
+extern void gen_ary(void), gen_call(void), gen_or(void), gen_tern(void),
+ gen_band(void), gen_bxor(void), gen_bor(void), gen_and(void),
+ gen_sizeof(void), gen_field(void), gen_ptr(void), gen_preinc(void),
+ gen_predec(void), gen_addr(void), gen_indir(void), gen_minus(void),
+ gen_plus(void), gen_cpl(void), gen_neg(void), gen_mul(void),
+ gen_div(void), gen_mod(void), gen_add(void), gen_sub(void),
+ gen_shl(void), gen_shr(void), gen_lt(void), gen_gt(void),
+ gen_ge(void), gen_le(void), gen_eq(void), gen_ne(void),
+ gen_a_mul(void), gen_a_div(void), gen_a_mod(void), gen_a_add(void),
+ gen_a_sub(void), gen_a_shl(void), gen_a_shr(void), gen_a_and(void),
+ gen_a_xor(void), gen_a_or(void), gen_postinc(void),
+ gen_postdec(void), gen_assign(void);
void expr(void);
static void primary(void)
{
+ fputs("static void primary(void)", stderr);
switch (yytoken) {
case IDEN:
if (!yyval.sym)
error("'%s' undeclared", yytext);
case CONSTANT:
next();
+ push(yyval.sym);
break;
case '(':
next();
@@ -24,35 +40,44 @@ static void primary(void)
expect(')');
break;
}
+ fputs("leaving static void primary(void)", stderr);
}
static void postfix(void)
{
- primary();
+ fputs("static void postfix(void)", stderr);
+ primary(); /* TODO: fix ( case */
for (;;) {
+ register void (*fp)(void);
switch (yytoken) {
case '[':
next();
expr();
expect(']');
- break;
+ gen_ary();
+ continue;
case '(':
next();
expr();
expect(')');
- break;
- case '.':
- case PTR:
- next();
- expect(IDEN);
- break;
- case INC:
- case DEC:
- next();
- break;
+ gen_call();
+ continue;
+ case '.': fp = gen_field; goto expect_iden;
+ case PTR: fp = gen_ptr; goto expect_iden;
+ case INC: fp = gen_postinc; goto next;
+ case DEC: fp = gen_postdec; goto next;
default:
+ fputs("leaving static void postfix(void)", stderr);
return;
}
+ expect_iden:
+ next();
+ expect(IDEN);
+ fp();
+ continue;
+ next:
+ next();
+ continue;
}
}
@@ -60,146 +85,259 @@ static void cast(void);
static void unary(void)
{
+ fputs("static void unary(void)", stderr);
for (;;) {
+ register void (*fp)(void);
switch (yytoken) {
case SIZEOF:
next();
if (accept('(')) {
type_name();
expect(')');
- return;
+ } else {
+ unary();
}
- break;
- case INC:
- case DEC:
- next();
- break;
- case '&': case '*': case '-': case '~': case '!': case '+':
- next();
- cast();
- return;
+ gen_sizeof();
+ continue;
+ case INC: fp = gen_preinc; goto call_unary;
+ case DEC: fp = gen_predec; goto call_unary;
+ case '&': fp = gen_addr; goto call_cast;
+ case '*': fp = gen_indir; goto call_cast;
+ case '-': fp = gen_minus; goto call_cast;
+ case '+': fp = gen_plus; goto call_cast;
+ case '~': fp = gen_cpl; goto call_cast;
+ case '!': fp = gen_neg; goto call_cast;
default:
postfix();
+ fputs("leaving static void unary(void)", stderr);
return;
}
+ call_cast:
+ next();
+ cast();
+ fp();
+ return;
+ call_unary:
+ next();
+ unary();
+ fp();
+ return;
}
}
static void cast(void)
{
+ fputs("static void cast(void)", stderr);
while (accept('(')) {
type_name(); /* check if it really is a type name */
expect(')');
}
unary();
+ fputs("leaving static void cast(void)", stderr);
}
static void mul(void)
{
- do
+ fputs("static void mul(void)", stderr);
+ cast();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case '*': fp = gen_mul; break;
+ case '/': fp = gen_div; break;
+ case '%': fp = gen_mod; break;
+ default:
+ fputs("leaving static void mul(void)", stderr);
+ return;
+ }
+ next();
cast();
- while(accept('*') || accept('/') || accept('%'));
+ fp();
+ }
}
static void add(void)
{
- do
+ fputs("static void add(void)", stderr);
+ mul();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case '+': fp = gen_add; break;
+ case '-': fp = gen_sub; break;
+ default:
+ fputs("leaving static void add (void)", stderr);
+ return;
+ }
+ next();
mul();
- while (accept('+') || accept('-'));
+ fp();
+ }
}
static void shift(void)
{
- do
+ fputs("static void shift(void)", stderr);
+ add();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case LSHIFT: fp = gen_shl; break;
+ case RSHIFT: fp = gen_shr; break;
+ default:
+ fputs("leaving static void shift (void)", stderr);
+ return;
+ }
+ next();
add();
- while (accept(LSHIFT) || accept(RSHIFT));
+ fp();
+ }
}
static void relational(void)
{
- do
+ fputs("static void relational(void)", stderr);
+ shift();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case '<': fp = gen_lt; break;
+ case '>': fp = gen_gt; break;
+ case GE: fp = gen_ge; break;
+ case LE: fp = gen_le; break;
+ default:
+ fputs("leaving static void relational (void)", stderr);
+ return;
+ }
+ next();
shift();
- while (accept('<') || accept('>') || accept(GE) || accept(LE));
+ fp();
+ }
}
-static void equality(void)
+static void eq(void)
{
- do
+ fputs("static void eq(void)", stderr);
+ relational();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case EQ: fp = gen_eq; break;
+ case NE: fp = gen_ne; break;
+ default:
+ fputs("leaving static void eq (void)", stderr);
+ return;
+ }
+ next();
relational();
- while (accept(EQ) || accept(NE));
+ fp();
+ }
}
static void bit_and(void)
{
- do
- equality();
- while (accept('&'));
+ fputs("static void bit_and(void)", stderr);
+ eq();
+ while (yytoken == '&') {
+ next();
+ eq();
+ gen_band();
+ }
+ fputs("leaving static void bit_and (void)", stderr);
}
-static void bit_exor(void)
+static void bit_xor(void)
{
- do
+ fputs("static void bit_xor(void)", stderr);
+ bit_and();
+ while (yytoken == '^') {
+ next();
bit_and();
- while (accept('^'));
+ gen_bxor();
+ }
+ fputs("leaving static void bit_xor(void)", stderr);
}
static void bit_or(void)
{
- do
- bit_exor();
- while (accept('|'));
+ fputs("static void bit_or(void)", stderr);
+ bit_xor();
+ while (yytoken == '|') {
+ next();
+ bit_xor();
+ gen_bor();
+ }
+ fputs("leaving static void bit_or(void)", stderr);
}
static void and(void)
{
- do
+ fputs("static void and(void)", stderr);
+ bit_or();
+ while (yytoken == AND) {
+ next();
bit_or();
- while (accept(AND));
+ gen_and();
+ }
+ fputs("leaving static void and(void)", stderr);
}
static void or(void)
{
- do
+ fputs("static void or(void)", stderr);
+ and();
+ while (yytoken == OR) {
+ next();
and();
- while (accept(OR));
+ gen_or();
+ }
+ fputs("leaving static void or(void)", stderr);
}
-static void conditional(void)
+static void cond(void)
{
+ fputs("static void cond(void)", stderr);
or();
- if (accept('?')) {
- expr();
- expect(':');
- conditional();
+ while (yytoken == '?') {
+ expr();
+ expect(':');
+ or();
+ gen_tern();
}
+ fputs("leaving static void cond(void)", stderr);
}
static void assign(void)
{
- unary();
- switch (yytoken) {
- case '=':
- case MUL_EQ:
- case DIV_EQ:
- case MOD_EQ:
- case ADD_EQ:
- case SUB_EQ:
- case LSHIFT_EQ:
- case RSHIFT_EQ:
- case AND_EQ:
- case XOR_EQ:
- case OR_EQ:
+ fputs("static void assign(void)", stderr);
+ cond();
+ for (;;) {
+ register void (*fp)(void);
+ switch (yytoken) {
+ case '=': fp = gen_assign; break;
+ case MUL_EQ: fp = gen_a_mul; break;
+ case DIV_EQ: fp = gen_a_div; break;
+ case MOD_EQ: fp = gen_a_mod; break;
+ case ADD_EQ: fp = gen_a_add; break;
+ case SUB_EQ: fp = gen_a_sub; break;
+ case LSHIFT_EQ: fp = gen_a_shl; break;
+ case RSHIFT_EQ: fp = gen_a_shr; break;
+ case AND_EQ: fp = gen_a_and; break;
+ case XOR_EQ: fp = gen_a_xor; break;
+ case OR_EQ: fp = gen_a_or; break;
+ default:
+ fputs("static void assign (void)", stderr);
+ return;
+ }
next();
assign();
- break;
- default:
- conditional();
- break;
+ fp();
}
}
void expr(void)
{
+ fputs("void expr(void)", stderr);
do
assign();
while (yytoken == ',');