Post on 24-Apr-2015
1. Write a two pass assembler for 8085
Making the list of opcodesopCodeFile = file("opcodeslisting.txt")tempString = opCodeFile.read()tempString = tempString.upper()opCodesList = tempString.split("\n")opCodesMap = {}for i in range(0,len(opCodesList)): if len(opCodesList[i]): tempList = opCodesList[i].split("|") if len(tempList) >= 3: opCodesMap[tempList[1].rstrip()] = tempList[2].rstrip()
#for k in opCodesMap:# print k + "=>" + opCodesMap[k]
Generating the assembly code
import opcodemap
code = '''ORG 4000H START:LXI H,4000H MOV R,M INX H ADD M INX H MOV M,R HLT END:JMP START'''
def buildSymbolTable(code): code = code.lstrip().rstrip() lines = code.split("\n") #print lines symbolTable = {} i = 0 if "ORG" in lines[0]: i = int(lines[0].split(" ")[1][:-1])-1 symbolTable['codestartshere'] = i #print lines[1] #print "i ==>", #print i for line in lines: if line[0] == ";": continue if len(line.split(":")) > 1: symbolTable[line.split(":")[0].rstrip().lstrip()] = i i += 1 if line.split(",")[-1][:-1].isdigit(): if int(line.split(",")[-1][:-1]) >= 0xFF: i += 2 else: i += 1 #print i print "The symbol table is" for k in symbolTable: if k == "codestartshere": continue print k, print " ", print symbolTable[k]
return symbolTable
def createMachineCode(symbolTable,code,opcodesMap): loc = symbolTable['codestartshere'] + 1 lines = code.split("\n") objectCode = {} for line in lines: if line[0:3] == "ORG": continue #if line[0] == ";": # continue #print line line = line.rstrip().lstrip() if ":" in line: line = line.split(":")[1] if line in opcodemap.opCodesMap.keys(): objectCode[loc] = opcodemap.opCodesMap[line] loc += 1 elif line[-3:-1].isdigit() or line[-5:-1].isdigit(): codeLine = line.split(",") print codeLine[-1] if int(codeLine[-1][:-1]) >= 0xFF: objectCode[loc] = opcodemap.opCodesMap[codeLine[0]+",NN"] loc += 1 objectCode[loc] = codeLine[1][-3:-1] loc += 1 objectCode[loc] = codeLine[1][-5:-3] loc += 1 else: objectCode[loc] = opcodemap.opCodesMap[codeLine[0]+",N"] loc += 1 objectCode[loc] = codeLine[1][-3:-1] loc += 1 else: line = line.split(' ') objectCode[loc] = opcodemap.opCodesMap[line[0] +" A"] loc += 1 if len(str(symbolTable[line[1]])) > 2: objectCode[loc] = str(symbolTable[line[1]])[-3:-1] loc += 1 objectCode[loc] = str(symbolTable[line[1]])[0:2] else: objectCode[loc] = symbolTable[line[1]] return objectCode print "Assembly code"print codemachineCode = createMachineCode(buildSymbolTable(code),code,opcodemap.op-CodesMap)print "Machine code"for k in machineCode.keys(): print k, print " ", print machineCode[k]#print opcodemap.opCodesMap
2. Write a Lexical analyzer for a subset of C language
Lex.l%{ /* need this for the call to atof() below */#include <math.h>%}
DELIM [ \t\n]WHITESPACE {DELIM}+DIGIT [0-9]LETTER [a-zA-Z]ID {LETTER}({LETTER}|{DIGIT})*NUMBER {DIGIT}+(\.{DIGIT}+)?(e[+\-]?{DIGIT}+)?
%%{DIGIT}+ { printf( "An integer: %s (%d)\n", yytext, atoi( yytext ) ); }{DIGIT}+"."{DIGIT}* { printf( "A float: %s (%g)\n", yytext, atof( yytext ) ); }if|else|return|main|include|int|float|char { printf( "A keyword: %s\n", yytext ); }{ID} printf( "An identifier: %s\n", yytext );"+"|"-"|";"|"="|"("|")"|"{"|"}"|"<"|">"|"*"|"/" printf( "An operator: %s\n", yytext );
"{"[^}\n]*"}" /* eat up one-line comments */[ \t\n]+ /* eat up whitespace */. printf( "Unrecognized character: %s\n", yytext );%%
main( argc, argv )int argc;char **argv; { ++argv, --argc; /* skip over program name */ if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; yylex(); }
File.cmain(){int a1, a2;float f1=9.09;a1=10;if(a1>10)a2=a1;}
Output[S@localhost ~]$ flex lex.l[S@localhost ~]$ gcc -c lex.yy.c[S@localhost ~]$ gcc -o final lex.yy.o -lfl[S@localhost ~]$ ./final file.cA keyword: mainAn operator: (
An operator: )An operator: {A keyword: intAn identifier: a1Unrecognized character: ,An identifier: a2An operator: ;A keyword: floatAn identifier: f1An operator: =A float: 9.09 (9.09)An operator: ;An identifier: a1An operator: =An integer: 10 (10)An operator: ;A keyword: ifAn operator: (An identifier: a1An operator: >An integer: 10 (10)An operator: )An identifier: a2An operator: =An identifier: a1An operator: ;An operator: }[S@localhost ~]$
3. Make a simple calculator using lex and yaccLex Code
%{
#include "y.tab.h"
%}
%%
[0-9]+ {yylval.a_number = atoi(yytext); return number;}
[ \t\n] ;
[-+*/();] {return yytext[0];}
. {ECHO; yyerror ("unexpected character");}
%%
int yywrap (void) {return 1;}
YACC code
%{
#include <stdio.h>
%}
%union {int a_number;}
%start line
%token <a_number> number
%type <a_number> exp term factor
%%
line : exp ';' {printf ("result is %d\n", $1);}
;
exp : term {$$ = $1;}
| exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
;
term : factor {$$ = $1;}
| term '*' factor {$$ = $1 * $3;}
| term '/' factor {$$ = $1 / $3;}
;
factor : number {$$ = $1;}
| '(' exp ')' {$$ = $2;}
;
%%
int main (void) {return yyparse ( );}
void yyerror (char *s) {fprintf (stderr, "%s\n", s);}
Output
labwork@nikhil-laptop:~/Desktop/compilers/calc$ bison -d calcy.y
labwork@nikhil-laptop:~/Desktop/compilers/calc$ mv calcy.tab.h y.tab.h
labwork@nikhil-laptop:~/Desktop/compilers/calc$ gcc -c calcy.tab.c
calcy.y:29: warning: conflicting types for ‘yyerror’
calcy.tab.c:1420: note: previous implicit declaration of ‘yyerror’ was here
labwork@nikhil-laptop:~/Desktop/compilers/calc$ flex calcl.l
labwork@nikhil-laptop:~/Desktop/compilers/calc$ gcc -c lex.yy.c
labwork@nikhil-laptop:~/Desktop/compilers/calc$ gcc lex.yy.o calcy.tab.o -o calc
labwork@nikhil-laptop:~/Desktop/compilers/calc$ ./calc
1 + (2*3);
result is 7
1 - 5;
result is -4