i well right the compiler we wright it in our book but i do't understand it i well right it
Code:
#include "global.h"
/*****************************************/
char lexemes[STRMAX];
int lastchar = -1;
int lastentry = 0;
int lookup(char s[])
{
int p;
for(p=lastentry;p>0;p--)
if(strcmp(symtable[p].lexptr ,s)==0)
return p;
return 0;
}
// insert: برنامج فرعي لإضافة رمز إلى مصفوفة الرموز
int insert(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++;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr =&lexemes[lastchar+1];
lastchar+=len+1;
strcpy(symtable[lastentry].lexptr ,s);
return lastentry;
}
========================================
#include "global.h"
void error(char* m)
{
fprintf(fptrErr,"\nline %d: %s\n",lineno,m); // write the error in the error file istead of screen
++errorCount; // add 1 to error counter
}
===================================
#include "global.h"
//void if1();
/****************************************/
void emit(int t,int tval)
{
switch(t){
case'+':
fprintf(fptrObj,"pop r1\npop r2\nadd r2,r1\npush r2\n"); break;
case'-':
fprintf(fptrObj,"pop r1\npop r2\nsub r2,r1\npush r2\n"); break;
case '*':
fprintf(fptrObj,"pop r1\npop r2\nmult r2,r1\npush r2\n"); break;
case '/':
fprintf(fptrObj,"pop r1\npop r2\nrdiv r2,r1\npush r2\n"); break;
case DIV:
fprintf(fptrObj,"pop r1\npop r2\ndiv r2,r1\npush r2\n"); break;
case MOD:
fprintf(fptrObj,"pop r1\npop r2\nmod r2,r1\npush r2\n"); break;
case NUM:
fprintf(fptrObj,"push %d \n",tval); break;
case ID:
fprintf(fptrObj,"push %s\n",symtable[tval].lexptr); break;
/* **************** */
case LID: // ex: x=y+3; LID is x
fprintf(fptrObj,"pop %s\n",symtable[tval].lexptr); break;
case IF1:
fprintf(fptrObj,"pop r2\ncmp r2,0\nbe else\n"); break; // call f1 we can write directly
case IF2:
fprintf(fptrObj,"else\n"); break;
case W1:
fprintf(fptrObj,"while\n"); break;
case W2:
fprintf(fptrObj,"pop r2\ncmp r2,0\nbe endwhile\n"); break;
case W3:
fprintf(fptrObj,"b while\n endwhile\n"); break;
case FOR1:
fprintf(fptrObj," ............. ");break;
case FOR2:
fprintf(fptrObj," ............. ");break;
default:
fprintf(fptrObj,"toke %d, tokenval %d\n ",t,tval); break;
}
}
/*void if1()
{
fprintf(fptrObj,"pop r2\ncmp r2,0\nbe else\n"); // if I want it take out from case IF1 fprintf... and change it by if1();
}
*/
==============================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define BSIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 256
#define DIV 257
#define MOD 258
#define ID 259
#define DONE 260
#define IF 261
#define THEN 262
#define WHILE 263
#define DO 264
#define BEGIN 265
#define END 266
#define FOR 267
#define TO 268
//*********************************these to use in emit.c only
#define LID 300 //left id
#define IF1 301
#define IF2 302
#define W1 303
#define W2 304
#define W3 305
#define FOR1 306
#define FOR2 307
//**********************************
struct entry{
char *lexptr;
int token;
};
void init();
void parse();
void FilesInit();
void match(int);
void expr();
void CS();
void stmt();
void term();
void factor();
int lexan();
void FilesInit();
void emit(int,int);
void error(char*);
int lookup(char s[]);
int insert(char s[],int);
//char lexbuf[BSIZE];
int lineno ;
int tokenval;
FILE *fptrObj,*fptrErr,*fptrExp; // pointers to files
int errorCount; // error counter
int lookahead;
#define STRMAX 999
#define SYMMAX 100
//char lexemes[STRMAX];
//int lastchar=-1;
struct entry symtable[SYMMAX];
//int lastentry=0; // I added | for {for1} id=Num to Num stmt {for2} // the hole translation done in (parser.c) // case FOR: ....
// FOR & TO keywords added to (Init.c) // for1 & for2 the translation added to (emitter.c) // as case for1: fprintf(out," .......");
========================================
#include "global.h"
struct entry keywords[]={
"div",DIV,
"mod",MOD,
"if",IF,
"then",THEN,
"while",WHILE,
"do",DO,
"begin",BEGIN,
"end",END,
"for",FOR,
"to",TO,
0,0
};
linno=1;
tokenval=NONE;
errorcount=0;
//init: puts the keyword in symbol arry
void init()
{
struct entry *p;
for(p = keywords; p->token ; p++)
insert(p->lexptr , p->token );
}
void FilesInit()
{
char ObjFileName[31],ErrFileName[31],ExpFileName[31];
printf("please enter input file name:" );
scanf("%s",ExpFileName); // give the input file name
strcpy(ObjFileName,ExpFileName); // copy the scanned file name
strcpy(ErrFileName,ExpFileName); // copy the scanned file name
strcat(ObjFileName,".obj"); // past the .obj extention the name
strcat(ErrFileName,".err");
strcat(ExpFileName,".exp");
fptrErr=fopen(ErrFileName,"w"); // open for write
fptrObj=fopen(ObjFileName,"w"); // open for write
fptrExp=fopen(ExpFileName,"r"); // read from input file
}
===========================================
#include "global.h"
void main()
{
FilesInit();
init();
parse();
fprintf(fptrErr,"\n Compile Done with - %d error(s) \n\n",errorCount); //printed on error file
printf("Compile Done with - %d error(s) \n\n",errorCount); // printed on screen
fclose(fptrErr);
fclose(fptrObj);
fclose(fptrExp);
getchar();
}
=============================
#include "global.h"
/*************************************/
char lexbuf[BSIZE];
int lexan()
{
int t;
while(1)
{
t=fgetc(fptrExp); // 1- instead of getchar(); ==> fptrExp is the input file
if(t==' ' || t=='\t');
else if(t=='\n')
lineno++;
else if(isdigit(t))
{
ungetc(t,fptrExp);
fscanf(fptrExp,"%d",&tokenval); // 2- fptrExp is the input file
return NUM;
}
else if (isalpha(t))
{
int p,b=0;
while(isalnum(t))
{
lexbuf[b]=t;
t=fgetc(fptrExp); // 1-...
b++;
if(b>=BSIZE)
error("compiler error : identifier was truncated to '128' characters");
}
lexbuf[b]=EOS;
if(t!=EOF)
ungetc(t,fptrExp); // 3- ungetc(t,.....) unget from the input file
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
#include "global.h"
/*****************************************/
void parse()
{
//lookahead=lexan();
while((lookahead=lexan()) != DONE)
stmt();
// match(';');
}
void stmt()
{
int tval=tokenval;
switch (lookahead){
case ID:
match(ID);match('=');expr();emit(LID,tval);break;
case IF:
match(IF);match('(');expr();emit(IF1,NONE);match(')');
match(THEN);stmt();emit(IF2,NONE);break;
case WHILE:
match(WHILE);emit(W1,NONE);match('(');expr();match(')');emit(W2,NONE);
match(DO);stmt();emit(W3,NONE);break;
case BEGIN:
match(BEGIN);CS();match(END);break;
case FOR:
match(FOR);emit(FOR1,NONE);match(ID);match('=');match(NUM);
match(TO);match(NUM);stmt();
emit(FOR2,NONE);break;
}
}
void CS()
{
while ((lookahead!=END) && (lookahead!=DONE))
{
stmt();
match(';');
}
}
void expr()
{
int t;
term();
while(1)
switch (lookahead){
case '+' :case '-' :
t=lookahead;
match(lookahead);term();emit(t,NONE);
continue;
default:
return;
}
}
void 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;
}
}
void 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 : missing identefire or number");
}
}
void match(int t)
{
if (lookahead==t)
lookahead=lexan();
else if(t==';')
error ("syntax error : missing ';' ");
else if (t==')')
error ("syntax error : missing ')' ");
else if (t=='=')
error ("syntax error : missing '=' ");
else if (t==END)
error ("syntax error : missing end of statment ");
else if (t==THEN)
error ("syntax error : missing 'then' ");
else if (t==DO)
error ("syntax error : missing 'do' ");
}
====================================
the grammer is
while (expr) do stmt
ex : while (1) do y=y+1
if (expr) then stmt
ex : if(1) then x=x+1
.
.
.
.
.