⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prsutil.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	mov	ah,PSERR_fAlert / 100h	;set ALERT flag in result
					;this error is reported at entry
					;time, rather than waiting until
					;the pre-run reparse loop
	SKIP2_PSW			;skip following mov ah,0 instruction
ReparseErr:
	mov	ah,0			;DON'T alter condition codes
BindRude:
	jmp	SHORT ParseErr		;ParseErr(ax,bx)
					; result doesn't matter because of error
PErrVarMgr ENDP

;error "id can't end with % & ! # or $", al=PR_BadSyntax on exit
;
PUBLIC	PErrExpIdImp
PErrExpIdImp PROC NEAR
	mov	ax,MSG_IdImp		;"id can't end with % & ! # or $"
PErrExpIdImp ENDP
;fall into PErrMsg_AX
;*********************************************************************
; VOID NEAR PErrMsg_AX, PErrPrevTok_AX, PErrMsg_AX_BX
;
; Purpose:
;	Append the standard message identified by iMsgErr to current error line.
;
; Entry:
;	ax = error code (from qbimsgs.inc)
;	pTokScan->oSrc is used for column offset by PErrMsg_AX
;	OR
;	bx->oSrc is used for column offset by PErrMsg_AX_BX [09]
;
; Exit:
;	al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
;PErrPrevTok_Ax uses the column offset of the last token consumed 
;for reporting the error
PUBLIC	PErrPrevTok_AX			
PErrPrevTok_AX PROC NEAR		
	mov	bx,[pTokLastConsumed]	;bx -> last consumed token
	; fall into PErrMsg_AX_BX	
	jmp	SHORT PErrMsg_Ax_Bx	
PErrPrevTok_AX ENDP			

PUBLIC	PErrMsg_AX
PErrMsg_AX PROC NEAR
	mov	bx,[pTokScan]
	; fall into PErrMsg_AX_BX	
PErrMsg_AX ENDP				

cProc	PErrMsg_AX_BX,<PUBLIC,NEAR>	
cBegin	PErrMsg_AX_BX			
	test	BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
	jne	GotEos1			;brif not 1st msg for this line
	test	BYTE PTR([ps.PS_errCode+1]),PSERR_fAlert / 100h
	jne	NoOmErr			;brif already got an error not
					; consisting of pasting together
					; messages into ps.bdErr (like
					; Id too long, or Out of memory)
					;This still overrides errors like ER_DD
					; so syntax errors get reported before
					; variable mgr re-parse type errors
					; (because a syntax error is more
					;  valuable to the user).

	push	ax			;save msg id
	mov	[ps.PS_bdErr.BD_cbLogical],0 ;reset bdErr buffer

	mov	ax,PSERR_fAsciiMsg + PSERR_fAlert
					;tells ParseLine's caller that err msg
					; is in ps.bdErr
	call	ParseErr		;set ps.errCode, ps.oSrcErr
GetEos:
	call	NtEndStatement
	jne	GotEos			;brif current token is end-of-stmt
	call	ScanTok
	jmp	SHORT GetEos

GotEos:
	pop	ax			;restore ax = msg id
GotEos1:
	push	ax			;pass msgId to ListStdMsgToBd
	PUSHI	ax,<dataOFFSET ps.PS_bdErr>
	call	ListStdMsgToBd		;append std msg to error buffer
	or	ax,ax
	jne	NoOmErr			;brif not out-of-memory
	call	ParseErrOm		;Error "Out of memory"
NoOmErr:
	mov	al,PR_BadSyntax
	or	al,al			;set condition codes for caller
cEnd	PErrMsg_AX_BX

;*********************************************************************
; VOID NEAR PErrExpectedOr()
;
; Purpose:
;	If this is the 1st clause of this err msg, output 'Expected: '
;	Otherwise output ' or '.
;
; Exit:
;	al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
PErrExpectedOr PROC NEAR
	mov	ax,MSG_or
	test	BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
	jne	OrNot1stMsg		;brif not 1st msg for this line
	mov	ax,MSG_expected
OrNot1stMsg:
	jmp	SHORT PErrMsg_AX	;emit msg, al = PR_BadSyntax
					; return to caller
PErrExpectedOr	ENDP

;*********************************************************************
; VOID NEAR PErrExpRw_AX
;
; Purpose:
;	Produce the error message:  "Expected <reserved word>"
;
; Entry:
;	ax = IRW for expected reserved word (from prsirw.inc)
; Exit:
;	al = PR_BadSyntax
; 
;*********************************************************************
cProc	PErrExpRw_AX,<PUBLIC,NEAR,NODATA>,<si>
cBegin
	xchg	si,ax			;si = IRW for expected reserved word
	DbAssertRel si,be,NTOKENS,CP,<Illegal token in PErrExpRw>
	;list ASCII this opcode maps to
	call	PErrExpectedOr		;output "Expected" or "or"
	cmp	si,IRW_NewLine
	jne	NotNewLine
	mov	ax,MSG_eos
	call	PErrMsg_AX		;output "end of statement"
	jmp	SHORT PErrExpRwExit

NotNewLine:
	push	si
	call	ListIRW			;output reserved word's name to
					; bufStdMsg, ax = byte count
	DbAssertRel ax,ne,0,CP,<ListIRW called with bad IRW>

	PUSHI	bx,<dataOFFSET ps.PS_bdErr>	;pass ptr to destination buffer
	PUSHI	bx,<dataOFFSET bufStdMsg>
					;pass ptr to 1st byte of text
	push	ax			;push byte count
	call	BdAppend		
PErrExpRwExit:
	mov	al,PR_BadSyntax		;return PR_BadSyntax
cEnd

;error "Expected id", al=PR_BadSyntax on exit
;
PUBLIC	PErrExpId
PErrExpId PROC NEAR
	mov	ax,MSG_ExpId
;;	jmp	SHORT PErrExpMsg_AX
PErrExpId ENDP
;fall into PErrExpMsg_AX
;*********************************************************************
; VOID NEAR PErrExpMsg_AX
;
; Purpose:
;	Produce the error message:  "Expected <Standard BASIC Message>"
;
; Entry:
;	ax = error code (from qbimsgs.inc)
;
; Exit:
;	al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
PUBLIC	PErrExpMsg_AX
PErrExpMsg_AX PROC NEAR
	push	ax			;save msgId
	call	PErrExpectedOr
	pop	ax			;restore ax = msgId
	jmp	PErrMsg_AX		;al = PR_BadSyntax
					;return to caller
PErrExpMsg_AX ENDP

if ND_ACCEPT - 0
	Error: PErrState assumes ND_ACCEPT = 0
endif
if ND_REJECT - 1
	Error: PErrState assumes ND_REJECT = 1
endif
if ND_MARK - 2
	Error: PErrState assumes ND_MARK = 2
endif
if ND_EMIT - 3
	Error: PErrState assumes ND_EMIT = 3
endif
if ND_BRANCH - 4
	Error: PErrState assumes ND_BRANCH = 4
endif

;*************************************************************************
; VOID NEAR PErrState
;
; Purpose:
;	Append an error message to the error buffer indicating
;	'A or B or C ...  or Z'  was expected.
;
; Entry:
;	ushort pStateLastScan - pointer into tState for expected syntax
;	  when last token was scanned.
;	ushort pStateLastGood - pointer into tState for expected syntax
;	  when last non-terminal was accepted.
;
; Exit:
;	al = PR_BadSyntax
;	  
;*************************************************************************
cProc	PErrState,<PUBLIC,NODATA,NEAR>,<si>
cBegin	PErrState
	test	BYTE PTR([ps.PS_errCode+1]),PSERR_fAlert / 100h
	jne	GotBadSyntax		;brif already got an error not
					; consisting of pasting together
					; messages into ps.bdErr (like
					; Id too long, or Out of memory)
					;This still overrides errors like ER_DD
					; so syntax errors get reported before
					; variable mgr re-parse type errors
					; (because a syntax error is more
					;  valuable to the user).
	mov	ax,[pStateLastScan]
	call	PErrState1		;PErrState(pStateLastScan - tState)
	test	BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
	jne	GotBadSyntax	      ;brif PErrState1 didn't generate anything
	mov	ax,[pStateLastGood]
	call	PErrState1
GotBadSyntax:
	mov	al,PR_BadSyntax
cEnd	PErrState

;Register usage:
;	dx = pStateTrue
;	cx = nodeId
;	si = pState
;
cProc	PErrState1,<NODATA,NEAR>,<si>
cBegin	PErrState1
	xchg	si,ax			;si = pState
	or	si,si
	jne	ErrLoop			;brif not NULL pState
J1_ErrLoopExit:
	jmp	ErrLoopExit		;brif ACCEPT or REJECT node (done)

ErrLoop:
	lods	BYTE PTR cs:[si]	;al = node id
	cmp	al,ND_REJECT
	jbe	J1_ErrLoopExit		;brif ACCEPT or REJECT node

	cmp	al,ND_EMIT
	ja	NotEmitOrMark		;brif not EMIT or MARK node
	lodsb				;bump si without changing status flags
	jne	ErrLoop			;brif MARK node (1 byte operand)
	inc	si			;EMIT has 2 byte operand
	jmp	SHORT ErrLoop

;got a branch, token, or nonterminal - fetch its id
NotEmitOrMark:
	sub	ah,ah			;ax = nodeId
	cmp	al,ENCODE1BYTE
	jb	OneByteNodeId		;brif 1 byte nodeId

	;nodeId = ((nodeId-ENCODE1BYTE) << 8) + (*pState++) + ENCODE1BYTE
	mov	ah,al
	lods	BYTE PTR cs:[si]	;ax = nodeId * 256 + next byte
	sub	ax,255 * ENCODE1BYTE
OneByteNodeId:	
	xchg	cx,ax			;save nodeId in cx
;node is followed by 1 or 2 byte branch operand, fetch it
	lods	BYTE PTR cs:[si]
	sub	ah,ah			;ax = operand
	cmp	al,ENCODE1BYTE
	jb	OneByteOperand		;brif 1 byte operand (< ENCODE1BYTE)
	cmp	al,255
	je	HandleNode		;brif special id->accept node
					; never generated for a BRANCH node,
					; which is the only reason we care
					; about the operand in this function
	;operand is 2 byte offset into tState
	;operand = ((operand-ENCODE1BYTE) << 8) + *pState++
	mov	ah,al
	lods	BYTE PTR cs:[si]	;ax = operand * 256 + next byte
	sub	ax,256 * ENCODE1BYTE
	add	ax,OFFSET CP:tState
	xchg	dx,ax			;pStateTrue = &tState[operand]
	jmp	SHORT HandleNode

OneByteOperand:
	;operand is 1 byte relative branch in state table
	mov	dx,ax			;dx = offset to new state
	add	dx,si			;pStateTrue = pState + operand
	cmp	al,ENCODE1BYTE/2
	jbe	HandleNode		;brif positive relative branch
	sub	dx,ENCODE1BYTE		;negative relative branch
HandleNode:
	xchg	ax,cx			;ax = nodeId
	cmp	ax,ND_BRANCH
	jne	NotBranchNode
	mov	si,dx			;unconditional branch to another state,
					; pState = pStateTrue
	jmp	SHORT ErrLoop		; continue scanning

NotBranchNode:
	sub	ax,ND_BRANCH + 1
	cmp	ax,NUMNTINT
	jae	NotIntNt

	;we expected a non-terminal described by a state tree
	xchg	bx,ax
	shl	bx,1
	mov	ax,cs:tIntNtDisp[bx]
	add	ax,CPOFFSET tState	;ax = pState
	call	PErrState1		;recurse
J1_ErrLoop:
	jmp	SHORT ErrLoop

NotIntNt:
	sub	ax,NUMNTINT
	cmp	ax,NUMNTEXT
	jae	NotExtNt

	;we expected a non-terminal defined by a C function
	xchg	bx,ax
	shl	bx,1
	mov	ax,cs:tExtNtHelp[bx]
					;iMsg = tExtNtHelp[nodeId]
	or	ax,ax
	je	J1_ErrLoop		;brif no error msg for this nonterminal
	call	PErrExpMsg_AX		;emit the message
	jmp	SHORT J1_ErrLoop

NotExtNt:
	;we expected a reserved word:  Error "Expected <reserved word>"
	sub	ax,NUMNTEXT		;ax = nodeId
	call	PErrExpRw_AX		;PErrExpRw(ax:nodeId)
	jmp	SHORT J1_ErrLoop

ErrLoopExit:
cEnd	PErrState1
sEnd	CP




end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -