shithub: scc

Download patch

ref: 09c14bf22ea534174eb70df46456ad5a19d042a6
parent: c7fec7be35fc12334a3546c1189ae01cf36db729
author: Roberto E. Vargas Caballero <[email protected]>
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");