Thursday, October 1, 2015

Compiler lab

/* global.h */

#include<stdio.h>  //load i/o routines
#include<ctype.h>  //load character test routines

#define BSIZE 128  //buffer size
#define NONE  -1
#define EOS   '\0'

#define NUM  256
#define DIV  257
#define MOD  258
#define ID   259
#define DONE 260

int tokenval;  //value of token attribute
int lineno;

struct entry {    //from of symbol table entry
char *lexptr;
int token;
};

struct entry symtable[];  //symbol table


/**** lexer.c ************/

#include "global.h"
char lexbuf[BSIZE];
int lineno = 1;
int tokenval = NONE;

int lexan()    //lexical analyzer
{
int t;
while(1){
t = getchar();
if(t==''|| t=='\t')
;              //strip out white space
else if(t=='\n')
lineno = lineno + 1;
else if (isdigit(t)){      //t is a digit
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;
}
else if(isalpha(t)){   //tis a letter
int p, b = 0;
while (isalnum(t)){    //t is alphanumeric
lexbuf[b] = t;
t = getchar();
b = b + 1;
if (b>=BSIZE)
error("Compiler Error");
}
lexbuf[b] = EOS;
if (t!=EOF)
ungetc(t, stdin);
p = lookup(lexbuf);
if (p == 0)
p = insert(lexbuf, ID);
tokenval = p;
return symtable[p].token;
}
else if(t == EOF)
return DONE;
else {
tokenval = NONE;
return t;
}
}
}


/******** parser.c **************/

#include "global.h"
int lookahead;

parse()   //parses and translates expression list
{
lookahead = lexan();
while (lookahead = DONE){
expr(); match(';');
}
}

expr()
{
int t;
term();
while(1)
switch (lookahead){
case '+':case '-':
t = lookahead;
match(lookahead); term(); emit(t,NONE);
continue;
default:
return;
}
}

term()
{
int t;
factor();
while(1)
switch(lookahead){
case '*': case '/': case DIV: case MOD:
t = lookahead;
match(lookahead); factor(); emit(t, NONE);
continue;
default:
return;
}
}

factor()
{
switch(lookahead){
case '(':
match('('); expr(); match(')'); break;
case NUM:
emit(NUM, tokenval); match(NUM); break;
case ID:
emit(ID,tokenval); match(ID); break;
default:
error("syntax error");
}
}

match(t)
int t;
{
if (lookahead == t)
lookahead = lexan();
else error("syntax error");
}


/********** Emitter.c ***************/

#include "global.h"

emit(t, tval)    // generates outputs
int t, tval;
{
switch(t){
case '+': case '-': case '*': case '/':
printf("%c\n",t); break;
case DIV:
printf("DIV\n"); break;
case MOD:
printf("MOD\n"); break;
case NUM:
printf("%d\n",tval); break;
case ID:
printf("%s\n",symtable[tval].lexptr); break;
default:
printf("token % d, tokenval %d\n",t,tval);
}
}


/****** symbol.c **************/

#include "global.h"
#define STRMAX 999 //size of lexemes array
#define SYMMAX 100 // size of symtable

char lexemes[STRMAX];
int lastchar = -1;  //last used position in lexemes
struct entry symtable[SYMMAX];
int lastentry = 0;

int lookup(s)
char s[];
{
int p;
for (p = lastentry; p>0 p=p-1)
if(stromp(symtable[p].lexptr, s)==0)
return p;
return 0;
}

int insert(s,tok)  //returns position of entry for s
char s[];
int tok;
{
int len;
len = strlen(s);
if(lastentry + 1 >= SYMMAX)
error("symbol table full");
if (lastchar + len + 1 >=STRMAX)
error("lexemes array full");
lastentry = lastentry + 1;
symtable[lastentry].token = tok;
symtable[lastentry].lexptr = &lexemes[lastchar + 1];
lastchar = lastchar + len + 1;
strcpy(symtable[lastentry].lexptr, s);
return lastentry;
}


/******** init.c **********/

#include "global.h"

struct entry keywords[] = {
"div",DIV,
"mod",MOD,
0,    0
};

init()
{
struct entry *p;
for (p = keywords; p->token; p++)
insert(p->lexptr, p->token);
}


/******** error.c **************/

#include "global.h"

error(m)
char m;
{
fprintf(stderr, "line %d: %s\n", lineno,m);
exit(1);
}


/********* main.c **********/

#include "global.h"
main()
{
init();
parse();
exit(0);
}