📄 ex16_1a.asm
字号:
; EX16_1a.asm
;
; A simple floating point calculator that demonstrates the use of the
; UCR Standard Library pattern matching routines. Note that this
; program requires an FPU.
.xlist
.386
.387
option segment:use16
include stdlib.a
includelib stdlib.lib
matchfuncs
.list
dseg segment para public 'data'
; The following is a temporary used when converting a floating point
; string to a 64 bit real value.
CurValue real8 0.0
; A Test String:
TestStr byte "5+2-(3-1)",0
; If the symbol "DEBUG" is defined, then call the MatchSP routine
; to do stack overflow checking. If "DEBUG" is not defined, just
; call the sl_Match2 routine directly.
DEBUG = 0 ;Define for debugging.
ifdef DEBUG
MatchPat textequ <MatchSP>
else
MatchPat textequ <sl_Match2>
endif
; Grammar for simple infix -> postfix translation operation:
; Semantic rules appear in braces.
;
; NOTE: This code has a serious problem. The first production
; is left recursive and will generate an infinite loop.
;
; E -> E+T {print result} | T {print result}
; T -> <constant> {fld constant} | (E)
;
;
;
; UCR Standard Library Pattern that handles the grammar above:
; An expression consists of an "E" item followed by the end of the string:
Expression pattern {MatchPat,E,,EndOfString}
EndOfString pattern {EOS}
; An "E" item consists of an "E" item optionally followed by "+" or "-"
; and a "T" item (E -> E+T | T):
E pattern {MatchPat, E,T,Eplus}
Eplus pattern {MatchChar, '+', T, epPlus}
epPlus pattern {DoFadd}
; A "T" item is either a floating point constant or "(" followed by
; an "E" item followed by ")".
;
; The regular expression for a floating point constant is
;
; [0-9]+ ( "." [0-9]* | ) ( ((e|E) (+|-| ) [0-9]+) | )
;
; Note: the pattern "Const" matches exactly the characters specified
; by the above regular expression. It is the pattern the calc-
; ulator grabs when converting a string to a floating point number.
Const pattern {MatchPat, ConstStr, 0, FLDConst}
ConstStr pattern {MatchPat, DoDigits, 0, Const2}
Const2 pattern {matchchar, '.', Const4, Const3}
Const3 pattern {MatchPat, DoDigits, Const4, Const4}
Const4 pattern {matchchar, 'e', const5, const6}
Const5 pattern {matchchar, 'E', Succeed, const6}
Const6 pattern {matchchar, '+', const7, const8}
Const7 pattern {matchchar, '-', const8, const8}
Const8 pattern {MatchPat, DoDigits}
FldConst pattern {PushValue}
; DoDigits handles the regular expression [0-9]+
DoDigits pattern {Anycset, Digits, 0, SpanDigits}
SpanDigits pattern {Spancset, Digits}
; The S production handles constants or an expression in parentheses.
T pattern {MatchChar, '(', Const, IntE}
IntE pattern {MatchPat, E, 0, CloseParen}
CloseParen pattern {MatchChar, ')'}
; The Succeed pattern always succeeds.
Succeed pattern {DoSucceed}
; We use digits from the UCR Standard Library cset standard sets.
include stdsets.a
dseg ends
cseg segment para public 'code'
assume cs:cseg, ds:dseg
; Debugging feature #1:
; This is a special version of sl_Match2 that checks for
; stack overflow. Stack overflow occurs whenever there
; is an infinite loop (i.e., left recursion) in a pattern.
MatchSP proc far
cmp sp, offset StkOvrfl
jbe AbortPgm
jmp sl_Match2
AbortPgm: print
byte cr,lf,lf
byte "Error: Stack overflow in MatchSP routine.",cr,lf,0
ExitPgm
MatchSP endp
; DoSucceed matches the empty string. In other words, it matches anything
; and always returns success without eating any characters from the input
; string.
DoSucceed proc far
mov ax, di
stc
ret
DoSucceed endp
; DoFadd - Adds the two items on the top of the FPU stack.
DoFadd proc far
faddp st(1), st
mov ax, di ;Required by sl_Match
stc ;Always succeed.
ret
DoFadd endp
; PushValue- We've just matched a string that corresponds to a
; floating point constant. Convert it to a floating
; point value and push that value onto the FPU stack.
PushValue proc far
push ds
push es
pusha
mov ax, dseg
mov ds, ax
lesi Const ;FP val matched by this pat.
patgrab ;Get a copy of the string.
atof ;Convert to real.
free ;Return mem used by patgrab.
lesi CurValue ;Copy floating point accumulator
sdfpa ; to a local variable and then
fld CurValue ; copy that value to the FPU stk.
popa
mov ax, di
pop es
pop ds
stc
ret
PushValue endp
; The main program tests the expression evaluator.
Main proc
mov ax, dseg
mov ds, ax
mov es, ax
meminit
finit ;Be sure to do this!
fwait
lesi TestStr
puts ;Print the expression
ldxi Expression
xor cx, cx
match
jc GoodVal
printff
byte " is an illegal expression",cr,lf,0
ret
GoodVal: fstp CurValue
printff
byte " = %12.6ge\n",0
dword CurValue
Quit: ExitPgm
Main endp
cseg ends
sseg segment para stack 'stack'
word 64 dup (?) ;Buffer for stack overflow
StkOvrfl word ? ;Stack overflow if drops
stk db 1024 dup ("stack ") ; below StkOvrfl.
sseg ends
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg ends
end Main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -