ref: 09c14bf22ea534174eb70df46456ad5a19d042a6
parent: c7fec7be35fc12334a3546c1189ae01cf36db729
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Jun 3 05:46:25 EDT 2012
Added expr parser This patch insert the initial parser for expressions
--- 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
--- a/decl.c
+++ b/decl.c
@@ -232,3 +232,7 @@
/* nothing */;
puts("leaving decl_list");}
+
+void type_name()
+{+}
--- /dev/null
+++ b/expr.c
@@ -1,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");+}
--- 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");--
⑨