自己的简单c编译器

按照龙书编的
实现了最简单的整形变量声明
但初始值是按序增长的
效果如下:
在这里插入图片描述
编译生成的效果
在这里插入图片描述
源代码如下


INCLUDE Irvine32.inc

ParseTableEntryCount=12
;==================== DATA =======================
.data
sourceCode byte "int adfcx_2324;int intsasdas;int intsasdas1;"
state byte 0					;lexana的状态
sourceCodePointer dword 0	;指向源代码的指针  分析lexical用
symbolTable byte 200 dup(0)		;字符表	每个表项占10个字节 当前每个表项只存两个成员 各占一个字节 1:id名字地址 2:id变量地址
token byte 0					;当前解析出来的lex是啥
tempIDNameBuffer byte 20 dup(0)	;临时存放id名字用的  在分析lex中用到
tempIDNameBufferPointer byte 0  ;指向tempIDNameBuffer的指针
symbolTableCount byte 0			;当前symbolTable表项的数量
IDNameBuffer byte 200 dup(0)	;存放id名字用的
IDNameBufferPointer byte 0		;存放id名字用的表的指针
parseTable dword 300 dup(2)		;解析表
shift byte "shift ",0
reduce byte "reduce ",0
accp byte "accpt",0
entry word  0
sr word 0						;是shift还是reduce?
value word 0					;解析表中对应的值
pStack dword 300 dup(0)			;解析栈
pStackTop dword 0				;栈顶指针
action dword 0
staCo word 0
staNum byte "the number of state is ",0
iMediate byte "interMediateTable",0
declare byte "declare ",0
interMediateTable byte 300 dup(0)		;中间语言表
interMediateTableCount dword 0			;中间语言表数量
symbolTableText byte 200 dup (0)		;把symbol存到目标文本中
idbufferText byte 900 dup(0)			;把idbuffer存到目标文本中
filename byte "output.txt",0
fileHandle DWORD ?
bytesWritten Dword ?
bufSize Dword ?
alloc byte 0							;id变量位置
dlc byte 30H								;id名字标号
initCodeText byte "mov eax,initValue",0ah,"mov dword ptr[data1+",0,0,"h],eax",0ah,"inc initValue",0ah
codeBegin byte "INCLUDE Irvine32.inc",0ah,".code",0ah,"main PROC",0ah,0
codeMedia byte "call iterSymbolTable",0ah,"exit",0ah,"main ENDP",0ah,"iterSymbolTable PROC",0ah,"mov esi,offset e0",0ah,"mov eax,0",0ah
codeMedia1 byte "movzx ecx,idco",0ah,"mov ebx,10",0ah,"l1:",0ah,"push eax",0ah,"mov ebx,10",0ah,"mul ebx",0ah
codeMedia2 byte "movzx ebx,byte ptr[esi+eax+0]",0ah,"mov edx,offset d0",0ah,"add edx,ebx",0ah,"call writeString",0ah
codeMedia3 byte "push eax",0ah,"mov eax,20h",0ah,"call writeChar",0ah,"pop eax",0ah,"movzx ebx,byte ptr[esi+eax+1]",0ah,"mov eax,dword ptr[data1+ebx]",0ah,"call writeDec",0ah,"call crlf",0ah
codeMedia4 byte "pop eax",0ah,"inc eax",0ah,"loop l1",0ah,"ret",0ah,"iterSymbolTable ENDP",0ah,".data",0ah,"data1 byte 200 dup(0)",0ah,"initValue dword 0",0ah,0
codeEnd byte 0ah,"END main",0ah,0
.code

main PROC
;设置parseTable
call setParseTable
mov eax,0
mov ebx,1
call iterParseTableEntry
mov eax,5
mov ebx,0
call iterParseTableEntry
mov eax,6
mov ebx,1
call iterParseTableEntry
mov eax,0
mov [pStack],eax
call LexAna

parse:
mov ecx,pStackTop
inc ecx
mov eax,pStackTop
ll:
push eax
mov ebx,4
mul ebx
mov ebx,eax

push eax
mov eax,0
mov al,byte ptr[pStack+ebx]
call writeDec
pop eax
pop eax
dec eax
loop ll
call crlf
mov eax,pStackTop

mov ebx,4
mul ebx
mov bl,byte ptr[pStack+eax]				
mov eax,ebx							;获取当前栈顶元素
movzx ebx,token

call iterParseTableEntry
mov dx,sr
mov cx,value
cmp sr,0							;shift?
je shif
cmp sr,1							;reduce?
je reduc
cmp sr,3							;acc?
je ql1
shif:
call pushToStack
call LexAna
movzx eax,token
cmp eax,3			;如果是id加入paserTable中
jne conLoop
push ecx
call addSymbolTableEntry
pop ecx
conLoop:
jmp parse

reduc:
cmp value,2
je r2
cmp value,0
je r0
cmp value,1
je r1

r2:mov ecx,1					;reduce T->int
mov action,4
call pushGoto
mov byte ptr[pStack+ebx+1],1		;标记当前是整形	
jmp parse
r1:

mov eax,pStackTop
sub eax,1
mov ebx,4
mul ebx
mov bl,byte ptr[pStack+eax+1]				
mov ecx,ebx							;获取当前栈顶下面一个元素 id在symbolTable的位置

;添加interMediate表项
mov eax,interMediateTableCount
mov ebx,3
mul ebx
mov byte ptr[interMediateTable+eax],1			;1代表声明变量操作
mov byte ptr[interMediateTable+eax+1],cl		;操作数在SymbolTablE中的位置
inc interMediateTableCount
mov ecx,3					;reduce s->T id;
mov action,5
call pushGoto
inc staCo
jmp parse
r0:mov ecx,2
mov action,5
call pushGoto
jmp parse
ql1:
mov edx,offset staNum
call writeString
movzx eax,staCo
call writeDec
call crlf
;call lookIDNameBuffer
;call iterSymbolTable
mov edx,offset declare
call writeString
INVOKE CreateFile,ADDR filename,GENERIC_WRITE,DO_NOT_SHARE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
mov fileHandle,eax
call handleInterMediateTable
call addMediaText
call crlf
call WriteText
call addEndText
exit
main ENDP

addEndText PROC
mov bufSize,lengthof codeEnd
INVOKE WriteFile,fileHandle,ADDR codeEnd,bufSize,ADDR bytesWritten,0
INVOKE CloseHandle,fileHandle
ret
addEndText endp
;把中间那块代码放入到文本中
addMediaText PROC
mov bufsize,lengthof codeMedia
INVOKE WriteFile,fileHandle,ADDR codeMedia,bufSize,ADDR bytesWritten,0
mov bufsize,lengthof codeMedia1
INVOKE WriteFile,fileHandle,ADDR codeMedia1,bufSize,ADDR bytesWritten,0
mov bufsize,lengthof codeMedia2
INVOKE WriteFile,fileHandle,ADDR codeMedia2,bufSize,ADDR bytesWritten,0
mov bufsize,lengthof codeMedia3
INVOKE WriteFile,fileHandle,ADDR codeMedia3,bufSize,ADDR bytesWritten,0
mov bufsize,lengthof codeMedia4
dec bufsize
INVOKE WriteFile,fileHandle,ADDR codeMedia4,bufSize,ADDR bytesWritten,0

ret
addMediaText ENDP
addEL PROC
dec esi
mov al,0ah
mov [symbolTableText+esi],al
inc esi

mov al,65h
mov [symbolTableText+esi],al
inc esi
mov al,dlc
inc dlc
mov [symbolTableText+esi],al
inc esi
mov al,20h
mov [symbolTableText+esi],al
inc esi
mov al,62h
mov [symbolTableText+esi],al
inc esi
mov al,79h
mov [symbolTableText+esi],al
inc esi
mov al,74h
mov [symbolTableText+esi],al
inc esi
mov al,65h
mov [symbolTableText+esi],al
inc esi
mov al,20h
mov [symbolTableText+esi],al
inc esi
ret
addEL ENDP
;把symbolTable和idbuffer写入到文本中 方便调试
WriteText PROC
movzx ecx,symbolTableCount
mov esi,0

mov al,69h
mov [symbolTableText+esi],al
inc esi
mov al,64h
mov [symbolTableText+esi],al
inc esi
mov al,63h
mov [symbolTableText+esi],al
inc esi
mov al,6fh
mov [symbolTableText+esi],al
inc esi
mov al,20h
mov [symbolTableText+esi],al
inc esi
mov al,62h
mov [symbolTableText+esi],al
inc esi
mov al,79h
mov [symbolTableText+esi],al
inc esi
mov al,74h
mov [symbolTableText+esi],al
inc esi
mov al,65h
mov [symbolTableText+esi],al
inc esi
mov al,20h
mov [symbolTableText+esi],al
inc esi
movzx eax,symbolTableCount
mov edx,16
div dl
inc edx
add al,48
cmp ah,0Ah
jge af2
add ah,48
jmp ssw2
af2:
add ah,55
ssw2:

mov [symbolTableText+esi],al
mov [symbolTableText+esi+1],ah
add esi,3

l1:
call addEL
mov eax,ecx
push ecx
sub eax,1
mov ecx,10
mov edx,0
mov ebx,10
mul ebx
mov ebx,eax
l2:
movzx eax,byte ptr[symbolTable+ebx+edx]
push edx
mov edx,16
div dl
pop edx
inc edx
add al,48
cmp ah,0Ah
jge af1
add ah,48
jmp ssw1
af1:
add ah,55
ssw1:
mov [symbolTableText+esi],al
mov [symbolTableText+esi+1],ah
mov al,68h
mov [symbolTableText+esi+2],al
mov al,2ch
mov [symbolTableText+esi+3],al
add esi,4
loop l2
pop ecx

loop l1


dec esi
mov bufSize,esi
INVOKE WriteFile,fileHandle,ADDR symbolTableText,bufSize,ADDR bytesWritten,0
mov ecx,0
mov ebx,0
mov esi,0
mov dlc,30h
mov al,0ah
mov [idbufferText+esi],al
inc esi
mov al,64h
mov [idbufferText+esi],al
inc esi
mov al,dlc
inc dlc
mov [idbufferText+esi],al
inc esi
mov al,20h
mov [idbufferText+esi],al
inc esi
mov al,62h
mov [idbufferText+esi],al
inc esi
mov al,79h
mov [idbufferText+esi],al
inc esi
mov al,74h
mov [idbufferText+esi],al
inc esi
mov al,65h
mov [idbufferText+esi],al
inc esi
mov al,20h
mov [idbufferText+esi],al
inc esi
l3:
movzx eax,byte ptr[IDNameBuffer+ebx]

mov edx,16
div dl

add al,48
cmp ah,0Ah
jge af
add ah,48
jmp ssw
af:
add ah,55
ssw:
mov [idbufferText+esi],al
inc esi
mov [idbufferText+esi],ah
inc esi
mov al,68h
mov [idbufferText+esi],al
inc esi
mov al,2ch
mov [idbufferText+esi],al
inc esi
movzx eax,byte ptr[IDNameBuffer+ebx]

cmp al,0
jne con
inc ecx
cmp cl,symbolTableCount
je qu
dec esi
mov al,0ah
mov [idbufferText+esi],al
inc esi

mov al,64h
mov [idbufferText+esi],al
inc esi
mov al,dlc
inc dlc
mov [idbufferText+esi],al
inc esi
mov al,20h
mov [idbufferText+esi],al
inc esi
mov al,62h
mov [idbufferText+esi],al
inc esi
mov al,79h
mov [idbufferText+esi],al
inc esi
mov al,74h
mov [idbufferText+esi],al
inc esi
mov al,65h
mov [idbufferText+esi],al
inc esi
mov al,20h
mov [idbufferText+esi],al
inc esi
con:inc ebx

jmp l3

qu:
dec esi
mov bufSize,esi
INVOKE WriteFile,fileHandle,ADDR idbufferText,bufSize,ADDR bytesWritten,0




ret
WriteText ENDP

handleInitCodeText PROC
pushad
mov eax,0
mov al,dl
mov edx,16
div dl
add al,48
cmp ah,0Ah
jge af
add ah,48
jmp ssw
af:
add ah,55
ssw:
mov [initCodeText+38],al
mov [initCodeText+39],ah
mov bufsize,61
INVOKE WriteFile,fileHandle,ADDR initCodeText,bufSize,ADDR bytesWritten,0
popad
ret
handleInitCodeText ENDP

;处理中间表的
handleInterMediateTable PROC
mov bufSize,lengthof codeBegin
dec bufsize
INVOKE WriteFile,fileHandle,ADDR codeBegin,bufSize,ADDR bytesWritten,0


mov ecx,interMediateTableCount
mov eax,0
l1:push eax
mov ebx,3
mul ebx
mov ebx,eax
cmp [interMediateTable+ebx],1		;是声明吗
jne con
mov edx,offset declare
call writeString
mov eax,0
movzx eax,byte ptr[interMediateTable+ebx+1]		;是取出位置
mov ebx,10
mul ebx
movzx ebx,byte ptr[symbolTable+eax]
mov dl,alloc
mov [symbolTable+eax+1],dl
call handleInitCodeText

add alloc,4
mov edx,offset IDNameBuffer
add edx,ebx
call writeString
call crlf
con:
pop eax
inc eax
loop l1
ret
handleInterMediateTable ENDP

pushToStack PROC

inc pStackTop
mov eax,pStackTop
mov ebx,4
mul ebx
mov ebx,eax

movzx eax,value
mov [pStack+ebx],eax
cmp eax,5					;是id嘛
jne l1
mov eax,0
mov al,symbolTableCount
sub al,1
mov byte ptr[pStack+ebx+1],al
l1:
ret
pushToStack ENDP

pushGoto PROC
l1:
dec pStackTop
loop l1
mov eax,pStackTop
mov ebx,4
mul ebx
mov ebx,eax
mov eax,0
mov al,byte ptr[pStack+ebx]		;当前栈顶元素
mov ebx,action
call iterParseTableEntry
inc pStackTop
mov eax,pStackTop
mov ebx,4
mul ebx
mov ebx,eax
movzx eax,value
mov byte ptr[pStack+ebx],al				;后面那三个byte根据不同的item 填不同的值
ret
pushGoto ENDP
;查看parseTable表项
iterParseTableEntry PROC
push eax
mov eax,ebx
mov ebx,4
mul ebx
mov ebx,eax
pop eax
mov ecx,0
mov edx,0
mov si,24
mul si
mov esi,offset parseTable
add eax,ebx
mov cx,word ptr[esi+eax]
mov dx,word ptr[esi+eax+2]
mov value,dx
cmp cx,0
je shif
cmp cx,1
je redu
cmp cx,3
je acc
redu:
mov edx,offset reduce
mov byte ptr[sr],1
jmp pr
shif:
mov edx,offset shift
mov byte ptr[sr],0
jmp pr
acc:mov edx,offset accp
mov byte ptr[sr],3
jmp pr
pr:
call WriteString
call WriteDec
call crlf
ret
iterParseTableEntry ENDP
;设置parseTable
setParseTable PROC
mov eax,0
mov ebx,0
mov sr,3		;3代表结束
mov entry,0
call setEntry
mov eax,0
mov ebx,2
mov sr,0
mov entry,3
call setEntry
mov eax,0
mov ebx,4
mov sr,0
mov entry,2
call setEntry
mov eax,0
mov ebx,5
mov sr,0
mov entry,1
call setEntry
mov eax,1
mov ebx,0
mov sr,3		;3代表结束
mov entry,0
call setEntry
mov eax,1
mov ebx,2
mov sr,0
mov entry,3
call setEntry
mov eax,1
mov ebx,4
mov sr,0
mov entry,2
call setEntry
mov eax,1
mov ebx,5
mov sr,0
mov entry,4
call setEntry

mov eax,2
mov ebx,3
mov sr,0
mov entry,5
call setEntry
mov eax,3
mov ebx,3
mov sr,1
mov entry,2
call setEntry
mov eax,4
mov ebx,2
mov sr,1
mov entry,0
call setEntry
mov eax,5
mov ebx,1
mov sr,0
mov entry,6
call setEntry
mov eax,6
mov ebx,0
mov sr,1		;3代表结束
mov entry,1
call setEntry
mov eax,6
mov ebx,2
mov sr,1
mov entry,1
call setEntry
ret
setParseTable ENDP
setEntry PROC
;设置ParseTable表项 eax:,ebx:列 ecx:shift(0)reduce(1), edx:shift值或reduce值 表项每个单元占4个字节 前两个表示是shift还是reduce 后两个表示对应值
mov si,24
mul si
push eax
mov eax,ebx
mov ebx,4
mul ebx
mov ebx,eax
pop eax

mov esi,offset parseTable
add eax,ebx
movzx edx,entry
mov cx,sr
mov word ptr[esi+eax],cx
mov word ptr[esi+eax+2],dx
ret
setEntry ENDP
;查看parseTable
iterSymbolTable PROC
mov esi,offset symbolTable
mov eax,0
movzx ecx,symbolTableCount
mov ebx,10
l1:
push eax
mul ebx
movzx eax,byte ptr[esi+eax+0]
call writeDec
call crlf
pop eax
inc eax
loop l1
ret
iterSymbolTable ENDP
;如果是id  把id相关信息放表中
addSymbolTableEntry PROC
mov edx,offset tempIDNameBuffer
call WriteString
call crlf

;向parseTable插入表项
mov esi,offset symbolTable
movzx eax,symbolTableCount
mov ebx,10
mul ebx
movzx ebx,IDNameBufferPointer
mov byte ptr[esi+eax+0],bl
mov byte ptr[esi+eax+1],0		;初始位置 0
inc symbolTableCount


movzx eax,IDNameBufferPointer
;把ID名字从缓存区导出来
mov esi,offset IDNameBuffer
mov ebx,offset tempIDNameBuffer
movzx ecx,tempIDNameBufferPointer
add esi,eax
l1:
mov al,[ebx]
mov byte ptr[esi],al
inc esi
inc ebx
inc IDNameBufferPointer
loop l1
mov byte ptr[esi],0
inc IDNameBufferPointer
ret
addSymbolTableEntry ENDP

;查看IDNameBuffer
lookIDNameBuffer PROC
mov esi,offset IDNameBuffer
movzx ecx,IDNameBufferPointer
mov ebx,0
l1:
movzx eax,byte ptr[esi+ebx]
call writeChar
inc ebx
loop l1
ret
lookIDNameBuffer ENDP
;解析Lex
LexAna PROC
mov tempIDNameBufferPointer,0
mov esi,offset sourceCode
lex:
cmp state,0
je state0
cmp state,1
je state1
cmp state,2
je state2
cmp state,3
je state3
cmp state,4
je state4
cmp state,5
je state5
cmp state,6
je state6
cmp state,7
je state7
cmp state,8
je state8

state0:call readNextChar
mov ebx,sourceCodePointer
cmp eax,3bh		;是分号吗
je state01
cmp eax,69h		;是i吗
je state02
cmp eax,0
je state08
jmp state06		;不是上面两个那就是 id了

state01:mov state,1
jmp lex
state02:mov state,2
jmp lex
state06:mov state,6
jmp lex
state08:mov state,8
jmp lex
state1:mov state,0
mov token,1
ret

state2:
call readNextChar

cmp eax,6eh
je state23
jmp state26
state23:mov state,3
jmp lex
state26:mov state,6
jmp lex

state3:call readNextChar
cmp eax,74h
je state34
jmp state36
state34:mov state,4
jmp lex
state36:mov state,6
jmp lex

state4:call readNextChar
cmp eax,20h
je state45
jmp state46
state45:mov state,5
jmp lex
state46:mov state,6
jmp lex


state5:mov state,0
mov token,2
inc SourceCode
ret

state6:call readNextChar
cmp eax,3bh
je state67		;是分号吗 
jmp lex

state67:
mov state,7
jmp lex

state7:dec sourceCodePointer
dec tempIDNameBufferPointer
movzx ebx,tempIDNameBufferPointer
mov [tempIDNameBuffer+ebx],0
mov state,0
mov token,3
ret

state8:mov state,0
mov token,0
ret

readNextChar:				;读取下一个字节 放到eax中
mov ebx,sourceCodePointer
movzx eax,byte ptr[esi+ebx]
inc sourceCodePointer
call addIDBuffer
ret

addIDBuffer:				;把当前字节放到缓存中
movzx ebx,tempIDNameBufferPointer
mov [tempIDNameBuffer+ebx],al
inc tempIDNameBufferPointer
ret
LexAna ENDP
END main

完整项目及第三方库在这:
链接:https://pan.baidu.com/s/1iepVEAl_sp16TcgxZ8jFpw?pwd=d5vh
提取码:d5vh

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值