scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
MMakefile | 2+-
Mdecl.c | 4++++
Aexpr.c | 240+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mflow.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");