наверно я что то пропустил:)
направьте на путь истинный:)
- - - Добавлено - - -
оно?Цитата:
.MCALL .MODULE
.MODULE TPARS,VERSION=03,COMMENT=<Finite State Parser>,IDENT=NO,GLOBAL=.TPAR
Вид для печати
Это сам модуль парсера. Кто его пользует - не знаю, поиском можно найти.
- - - Добавлено - - -
Вот где еще пример ипользования парсера есть - команднострочный калькулятор-конвертер из DECовского TSXа от RSX (ну собственно на СТАКАНе он тоже есть).
gfd71, это не полностью законченный пример, это скорей - библиотечная процедура, которой на вход нужна определённая инфа (примерный вид которой я показал). К сожалению, пока времени крайне мало, но в субботу смогу и проверить и нарисовать законченный пример использования.
gfd71, на образе дискеты для ДВК, что я вам скидывал должен быть текстовый файл MACMIS.LST где расшифрованы ошибки при прогоне через MACRO.SAV? Если нету, его легко в архиве по оглавлению найти.
там скорее не ошибка, а ворнинг, SAV собирается
если я правильно понимаю что то нужно добавить:)Цитата:
?LINK-W-Undefined globals:
RMETH2
RMETH1
Добавить процедуры, которые вызываются для команд :)
Проверил. Пару ошибок нашёл. Программа в данном варианте различает большие маленькие буквы! Если не требуется, нужна правка :)
Вроде как рабочий пример:
Результат:Код:.TITLE TEST
.MCALL .GTLIN, .PRINT, .EXIT
.PSECT DATA,RW
CMDBUF: .BLKB 81. ;Буфер команды
PROMPT: .ASCII /CMD>/<200>
; Имена команд
CMD1: .ASCIZ /COM1/
CMD2: .ASCIZ /COM2/
.EVEN
; Описатель - команда-процедура. Окончание - нулевое слово
DESC: .WORD CMD1 ; Имя
.WORD RMETH1 ; Ссылка на процедуру
.WORD CMD2
.WORD RMETH2
.WORD 0
.PSECT CODE,RO
START: .GTLIN #CMDBUF, #PROMPT
MOV #CMDBUF, R0 ; Строка команды в формате .ASCIZ
MOV #DESC, R1 ; Дескриптор команд-процедур
CALL PARSE
.EXIT
.PSECT DATA,RW
MESS1: .ASCIZ /COM1/
MESS2: .ASCIZ /COM2/
.EVEN
.PSECT CODE,RO
RMETH1: .PRINT #MESS1
RETURN
RMETH2: .PRINT #MESS2
RETURN
;------------------------------
;
; .PSECT DATA,RW
;
;; Имена команд
;CMD1: .ASCIZ /COM1/
;CMD2: .ASCIZ /COM2/
; .EVEN
;
;; Описатель - команда-процедура. Окончание - нулевое слово
;DESC: .WORD CMD1 ; Имя
; .WORD RMETH1 ; Ссылка на процедуру
; .WORD CMD2
; .WORD RMETH2
; .WORD 0
;
; .PSECT CODE,RO
;
; MOV #CMD, R0 ; Строка команды в формате .ASCIZ
; MOV #DESC, R1 ; Дескриптор команд-процедур
; CALL PARSE
;
PARSE::
MOV R1, -(SP) ; Сохраним описатель команд
LOOP: TSTB (R0) ; Дошли до конца строки команд
BEQ EXIT ; Да - выход
CMPB (R0), #', ; Нет. Разделитель команд?
BNE NCOMMA ; Нет - дальше повторитель-команда или команда
INC R0 ; Пропуск запятой
BR LOOP ; Дальше по командной строке
NCOMMA:
CLR R3 ; Повторитель команды
DIG: CMPB (R0), #'0 ; Цифра?
BLO NDIG ; Нет - дальше пошла команда
CMPB (R0), #'9 ; Цифра
BHI NDIG ; Нет - дальше пошла команда
MUL #10., R3 ; Предыдущее*10
SUB #'0, R3 ; Минус код ASCII минус код нуля
MOVB (R0)+, R2 ; Очердной символ-цифра
ADD R2, R3 ; Плюс следующаяя цифра в коде ASCII
BR DIG ; Смотрим дальше
NDIG: TST R3 ; Повторитель задан?
BNE SCMD ; Да - ищем команду
INC R3 ; Нет - но один раз команду выполнить надо
SCMD:
MOV (SP), R1 ; Описатель команд
MOV R0, -(SP) ; Начало имени команды
LCMD: MOV (R1)+, R2 ; Имя следующей команды. Описатель закончился?
BEQ ECMD ; Да - (тут в принципе можно вставить переход на обработку ошибки)
MOV (R1)+, R5 ; Процедура, её выполняющая
MOV (SP), R0 ; Начало имени команды - для очередного сравнения
SCMP:
TSTB (R0) ; В конце строки (окончание имени команды)?
BEQ CCHK2 ; Да
CMPB (R0), #', ; Запятая (тоже окончание имени команды)?
BEQ CCHK1 ; Да
TSTB (R2) ; Имя команды в описателе закончилось (а в строке команды - нет)?
BEQ LCMD
CMPB (R0)+, (R2)+ ; Символ тот же?
BEQ SCMP ; Да, продолжаем сравнение
BR LCMD ; Нет - смотрим следующую команду
CCHK1: INC R0 ; Пропустить запятую
CCHK2: TSTB (R2) ; В строке команда закончилась. А в описателе?
BNE LCMD ; Нет - не та команды
CALL MCMD ; Да - выполнить связанную с ней процедуру
ECMD: TST (SP)+
BR LOOP
EXIT: TST (SP)+
RETURN
MCMD:
CALL $SAVAL
MLOOP: MOV R3,-(SP)
CALL (R5)
MOV (SP)+, R3
SOB R3, MLOOP
RETURN
;
;В принципе, стандартная процедура сохранения восстановления всех регистров,
;но с этим кодом процедура становится самодостаточной.
;Можно выкинуть :)
;
$SAVAL: MOV R4,-(SP)
MOV R3,-(SP)
MOV R2,-(SP)
MOV R1,-(SP)
MOV R0,-(SP)
MOV 12(SP),-(SP)
MOV R5,14(SP)
JSR PC,@(SP)+
MOV (SP)+,R0
MOV (SP)+,R1
MOV (SP)+,R2
MOV (SP)+,R3
MOV (SP)+,R4
MOV (SP)+,R5
RETURN
;----------------------------------------------------
.END START
Код:.RU TEST 2COM1,1COM2
COM1
COM1
COM2
.RU TEST 2COM1,0COM2
COM1
COM1
COM2
.RU TEST 2COM1,3COM2,COM3
COM1
COM1
COM2
COM2
COM2
.RU TEST 2COM1,3COm2,COM3
COM1
COM1
.
подросла программа:)
Сама процедура парсинга - нет. Появился код, демонстрирующий, как использовать :)