commit 09c14bf22ea534174eb70df46456ad5a19d042a6
parent c7fec7be35fc12334a3546c1189ae01cf36db729
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 3 Jun 2012 09:46:25 +0200
Added expr parser
This patch insert the initial parser for expressions
Diffstat:
M | Makefile | | | 2 | +- |
M | decl.c | | | 4 | ++++ |
A | expr.c | | | 240 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | flow.c | | | 6 | ------ |
4 files changed, 245 insertions(+), 7 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
+OBJS = types.o decl.o lex.o error.o symbol.o flow.o main.o expr.o
LIBS =
all: kcc
diff --git a/decl.c b/decl.c
@@ -232,3 +232,7 @@ char decl_list(void)
/* nothing */;
puts("leaving decl_list");
}
+
+void type_name()
+{
+}
diff --git a/expr.c b/expr.c
@@ -0,0 +1,240 @@
+#include <stddef.h>
+
+#include "tokens.h"
+#include "symbol.h"
+#include "syntax.h"
+
+#include <stdio.h> /* TODO: remove this */
+
+
+void expr(void);
+
+static void primary(void)
+{
+ puts("primary");
+ switch (yytoken) {
+ case IDENTIFIER:
+ case CONSTANT:
+ case STRING_LITERAL:
+ next();
+ break;
+ case '(':
+ next();
+ expr();
+ expect(')');
+ break;
+ }
+ puts("leaving primary");
+}
+
+static void postfix(void)
+{
+ puts("postfix");
+ primary();
+ for (;;) {
+ switch (yytoken) {
+ case '[':
+ next();
+ expr();
+ expect(']');
+ break;
+ case '(':
+ next();
+ expr();
+ expect(')');
+ break;
+ case '.':
+ case PTR_OP:
+ next();
+ expect(IDENTIFIER);
+ break;
+ case INC_OP:
+ case DEC_OP:
+ next();
+ break;
+ default:
+ puts("leaving postfix");
+ return;
+ }
+ }
+}
+
+static void cast(void);
+
+static void unary(void)
+{
+ puts("unary");
+ for (;;) {
+ switch (yytoken) {
+ case SIZEOF:
+ next();
+ if (accept('(')) {
+ type_name();
+ expect(')');
+ goto leaving;
+ }
+ break;
+ case INC_OP:
+ case DEC_OP:
+ next();
+ break;
+ case '&': case '*': case '-': case '~': case '!': case '+':
+ next();
+ cast();
+ goto leaving;
+ default:
+ postfix();
+ goto leaving;
+ }
+ }
+leaving:
+ puts("leaving unary");
+}
+
+static void cast(void)
+{
+ puts("cast");
+ while (accept('(')) {
+ type_name(); /* check if it really is a type name */
+ expect(')');
+ }
+ unary();
+ puts("leaving cast");
+}
+
+static void mul(void)
+{
+ puts("mul");
+ do
+ cast();
+ while(accept('*') || accept('/') || accept('%'));
+ puts("leaving mul");
+}
+
+static void add(void)
+{
+ puts("add");
+ do
+ mul();
+ while (accept('+') || accept('-'));
+ puts("leaving add");
+}
+
+static void shift(void)
+{
+ puts("shift");
+ do
+ add();
+ while (accept(LEFT_OP) || accept(RIGHT_OP));
+ puts("leaving shift");
+}
+
+static void relational(void)
+{
+ puts("relational");
+ do
+ shift();
+ while (accept('<') || accept('>') || accept(GE_OP) || accept(LE_OP));
+ puts("leaving relational");
+}
+
+static void equality(void)
+{
+ puts("equality");
+ do
+ relational();
+ while (accept(EQ_OP) || accept(NE_OP));
+ puts("leaving equality");
+}
+
+static void bit_and(void)
+{
+ puts("bit_and");
+ do
+ equality();
+ while (accept('&'));
+ puts("leaving bit_and");
+}
+
+static void bit_exor(void)
+{
+ puts("bit_exor");
+ do
+ bit_and();
+ while (accept('^'));
+ puts("leaving bit_exor");
+}
+
+static void bit_or(void)
+{
+ puts("bit_or");
+ do
+ bit_exor();
+ while (accept('|'));
+ puts("leaving bit_or");
+}
+
+static void and(void)
+{
+ puts("and");
+ do
+ bit_or();
+ while (accept(AND_OP));
+ puts("leaving and");
+}
+
+static void or(void)
+{
+ puts("or");
+ do
+ and();
+ while (accept(OR_OP));
+ puts("leaving or");
+}
+
+static void conditional(void)
+{
+ puts("conditional");
+ or();
+ if (accept('?')) {
+ expr();
+ expect(':');
+ conditional();
+ }
+ puts("leaving conditional");
+}
+
+static void assign(void)
+{
+ puts("assign");
+ unary();
+ switch (yytoken) {
+ case '=':
+ case MUL_ASSIGN:
+ case DIV_ASSIGN:
+ case MOD_ASSIGN:
+ case ADD_ASSIGN:
+ case SUB_ASSIGN:
+ case LSHIFT_ASSIGN:
+ case RSHIFT_ASSIGN:
+ case AND_ASSIGN:
+ case XOR_ASSIGN:
+ case OR_ASSIGN:
+ next();
+ assign();
+ break;
+ default:
+ conditional();
+ break;
+ }
+ puts("leaving assign");
+}
+
+void expr(void)
+{
+ puts("expr");
+ do
+ assign();
+ while (yytoken == ',');
+ puts("leaving expr");
+}
diff --git a/flow.c b/flow.c
@@ -7,12 +7,6 @@
void stmt(void);
-void expr(void)
-{
- puts("expr");
- puts("leaving expr");
-}
-
static void do_goto(void)
{
puts("void do_goto");