thank you
i try to use your lesson but i have errors in file
can you help me???
Code:
/* global.h */

#include <stdio.h> /* include declarations for i/o routines */
#include <ctype.h> /* ... and for character test routines */
#include <stdlib.h> /* ... and for some standard routines, such as exit */
#include <string.h> /* ... and for string 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
#define PLUS 243
#define MINUS 255
int tokenval = NONE; /* value of token attribute */ 
int lineno = 1;

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

struct entry symtable[]; /* symbol table */

void init(); /* loads keywords into symtable */
void error(char* m); /* generates all error messages */
int lexan(); /* lexical analyzer */
void parse(); /* parses and translates expression list */
int insert(char *s, int tok); /* returns position of entry for s */
int lookup(char *s); /* returns position of entry for s */
void emit (int t, int tval); /* generates output */
/* init.c */

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

void init() /* loads keywords into symtable */
{
struct entry *p;
for (p = keywords; p->token; p++)
insert(p->lexptr, p->token);
}
/* symbol.c */


#define STRMAX 999 /* size of lexemes array */
#define SYMMAX 100 /* size of symbol table */

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

int lookup(char *s) /* returns position of entry for s */
{
int p;
for (p = lastentry; p > 0; p = p - 1)
if (strcmp(symtable[p].lexptr, s) == 0)
return p;
return 0;
}

int insert(char *s, int tok) /* returns position of entry for s */
{
int len;
len = strlen(s); /* strlen computes length of 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;
}
/* lexer.c */


char lexbuf[BSIZE];


int lexan () /* lexical analyzer */
{

int t;
while(1) {
t = fgetc (fs);
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, fs);
fscanf(fs,"%d", &tokenval);
return NUM;
}
else if (isalpha(t)) { /* t is a letter */
int p, b = 0;
while (isalnum(t)) { /* t is alphanumeric */
lexbuf [b] = t; 
t = fgetchar (fs);
b = b + 1;
if (b >= BSIZE)
error("compiler error");
}
lexbuf[b] = EOS;
if (t != EOF)
ungetc(t, fs);
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;
}
}
}

/* emitter.c */
void emit (int t, int tval) /* generates output */
{
switch(t) {
case '+' : case '-' : case '*' : case '/':
fprintf(ft,"%c\n", t); break;
case PLUS :
fprintf(ft,"PLUS\n"); break;
case MINUS :
fprintf(ft,"MINUS\n"); break;
case DIV:
fprintf(ft,"DIV\n"); break; 
case MOD:
fprintf(ft,"MOD\n"); break;
case NUM:
fprintf(ft,"%d\n", tval); break;
case ID:
fprintf(ft,"%s\n", symtable[tval].lexptr); break; 
default: 
fprintf(ft,"token %d, tokenval %d\n", t, tval);
}
}
/* parser.c -- without the optimizations */

int lookahead;

void match(int);
void start(), list(), expr(), moreterms(), term(), morefactors(), factor();

void parse() /* parses and translates expression list */
{
lookahead = lexan();
start();
}

void start ()
{
/* Just one production for start, so we don't need to check lookahead */
list(); match(DONE);
}

void list()
{
if (lookahead == '(' || lookahead == ID || lookahead == NUM) {
expr(); match(';'); list();
}
else {
/* Empty */
}
}

void expr ()
{
/* Just one production for expr, so we don't need to check lookahead */
term(); moreterms();
}

void moreterms()
{
if (lookahead == '+') {
match('+'); term(); emit('+', tokenval); moreterms();
}
else if (lookahead == '-') {
match('-'); term(); emit('-', tokenval); moreterms();
}
else {
/* Empty */
}
}

void term ()
{
/* Just one production for term, so we don't need to check lookahead */
factor(); morefactors();
}

void morefactors ()
{
if (lookahead == '*') {
match('*'); factor(); emit('*', tokenval); morefactors();
}
else if (lookahead == '/') {
match('/'); factor(); emit('/', tokenval); morefactors();
}
else if (lookahead == PLUS) {
match(PLUS); factor(); emit(PLUS, tokenval); morefactors();
}
else if (lookahead == MINUS) {
match(MINUS); factor(); emit(MINUS, tokenval); morefactors();
}
else if (lookahead == DIV) {
match(DIV); factor(); emit(DIV, tokenval); morefactors();
}
else if (lookahead == MOD) {
match(MOD); factor(); emit(MOD, tokenval); morefactors();
}
else {
/* Empty */
}
}

void factor ()
{
if (lookahead == '(') {
match('('); expr(); match(')');
}
else if (lookahead == ID) {
int id_lexeme = tokenval;
match(ID);
emit(ID, id_lexeme);
}
else if (lookahead == NUM) {
int num_value = tokenval;
match(NUM);
emit(NUM, num_value);
}
else
error("syntax error in factor");
}

void match(int t)
{
if (lookahead == t)
lookahead = lexan();
else
error ("syntax error in match");
}
/* error.c */

void error(char* m) /* generates all error messages */
{
fprintf(stderr, "line %d: %s\n", lineno, m);
exit(EXIT_FAILURE); /* unsuccessful termination */
}
/* main.c */

int main(void)
{
FILE *fs, *ft ;
char ch ;
fs = fopen ( "d:\\source.txt", "r" ) ;
if ( fs == NULL )
{ puts ( "Cannot open source file" ) ;
exit(0 ) ; 
}
ft = fopen ( "d:\\out.txt","w" ) ; 
if ( ft == NULL ) 
{ puts ( "Cannot open target file" ) ;
exit(0 ) ; 
} 


init();
parse();
fclose(ft);
fclose(fs);
exit(0); /* successful termination */
}

Last edited by shabbir; 13Mar2011 at 09:13.. Reason: Code blocks