#include <p16f873.inc> ; processor specific variable definitions #define parse_state_offset 0x5 cblock 0x20 parse_state, parse_char endc cblock buffer endc push macro x movlw x movwf INDF incf FSR, f endm movlw buffer movwf FSR push 'o' push 'f' push 'f' ; push 's' ; push 'e' ; push 't' push'\0' movlw buffer - 1 movwf FSR start clrf parse_state again incf FSR, f ;read next character movfw INDF call parse movfw parse_state ;still initial state? skpnz goto again sublw parse_state_offset-1 ;comand code? skpnc goto match incfsz parse_state, w ;error? goto again goto p_error ; ... ; match nop nop nop goto start p_error nop nop goto start ;-------------- keywords list --------------------- ; Case Sensitive ; Incomplete words match ; Whitespaces: ' ', '\t', 0x0D, 0x0A ; Delimiters: 0, ' ', '\t', 0x0D, 0x0A ; ; Keywords codes: ; 0x1 offset ; 0x2 echo ; 0x3 on ; 0x4 off ;*********************************************** ; Simple parser for command names ; ; Input: ; w next character in a string ; parse_state current state ; Output: ; parse_state contains current state: ; 0 - initial state ; 1...(parse_state_offset-1) - command code ; parse_state_offset...0xFE - next state ; 0xFF - error (not matched) ; Temporary: ; parse_char, parse_state ; Usage: ; 1)clrf parse_state ; 2)call parse with a new character ; 3)check parse_state and perform actions ; 4)repeat from 2) ; Note: ; 1) The parser takes one character as a look-ahead. ; When a command name matches, parse_char contains ; the first character AFTER the name. If it should ; be checked also, initialize and call parse once more ; with the same character first, then others as usually. ; 2) Size of state table is approximately 4 instructions ; per each character of the total characters number ; (e.g. total for commands "read" and "set" is 7, ; i.e state table is about 21 instructions) ; ;*********************************************** parse movwf parse_char ;save new character movfw parse_state ;check if current state is zero skpz goto parse2 movfw parse_char ;then skip whitespaces addlw -' ' ;accumulator == ' ' ? skpnz retlw 0 ;return if equal addlw ' ' - '\t' ;restore accumulator and check if equals '\t' skpnz retlw 0 ;return if equal addlw '\t' - 0x0D ;restore accumulator and check if equals 0x0D skpnz retlw 0 ;return if equal addlw 0x0D - 0x0A ;restore accumulator and check if equals 0x0A skpnz retlw 0 ;return if equal parse2 call parse_table iorlw 0 ;check if w == 0 (look ahead for delimiter succesful) skpz movwf parse_state ;store new state return ;*********************************************** ; State Table ; ; Input: ; parse_state -> current state + parse_state_offset ; Output: ; w -> new state + parse_state_offset ; ; Note ; Zero parse_state means initial state ;*********************************************** parse_table movlw high(parse_table_start) movwf PCLATH movfw parse_state ;read current state skpnz ;is it inital? goto parse_state0 addlw -parse_state_offset-1 ;remove offset ;jump table with automatic block boundary workaround addlw low(parse_table_start) skpnc incf PCLATH, f movwf PCL ;-> takeoff parse_state_delimiter ;called from state table to check for end of name movwf parse_state movfw parse_char addlw -0 ;accumulator == 0 ? skpnz retlw 0 ;return if equal addlw 0 - ' ' ;restore accumulator and check if equals ' ' skpnz retlw 0 ;return if equal addlw ' ' - '\t' ;restore accumulator and check if equals '\t' skpnz retlw 0 ;return if equal addlw '\t' - 0x0D ;restore accumulator and check if equals 0x0D skpnz retlw 0 ;return if equal addlw 0x0D - 0x0A ;restore accumulator and check if equals 0x0A skpnz retlw 0 ;return if equal retlw 0xFF parse_table_start ;---------------- jump table start ---------------- goto parse_state1 goto parse_state2 goto parse_state3 goto parse_state4 goto parse_state5 goto parse_state6 goto parse_state7 goto parse_state8 goto parse_state9 goto parse_state10 goto parse_state11 ;---------------- jump table end ------------------ ;--------------- state table start ---------------- parse_state0 movf parse_char, w addlw -'o' skpnz retlw 0x6 addlw 'o'-'e' skpnz retlw 0xC retlw 0xFF parse_state1 movf parse_char, w addlw -'f' skpnz retlw 0x7 addlw 'f'-'n' skpnz retlw 0x10 goto parse_state11 parse_state2 movf parse_char, w addlw -'f' skpnz retlw 0x8 retlw 0xFF parse_state3 movf parse_char, w addlw -'s' skpnz retlw 0x9 movlw 0x4 goto parse_state_delimiter parse_state4 movf parse_char, w addlw -'e' skpnz retlw 0xA goto parse_state6 parse_state5 movf parse_char, w addlw -'t' skpnz retlw 0xB parse_state6 movlw 0x1 goto parse_state_delimiter parse_state7 movf parse_char, w addlw -'c' skpnz retlw 0xD goto parse_state10 parse_state8 movf parse_char, w addlw -'h' skpnz retlw 0xE goto parse_state10 parse_state9 movf parse_char, w addlw -'o' skpnz retlw 0xF parse_state10 movlw 0x2 goto parse_state_delimiter parse_state11 movlw 0x3 goto parse_state_delimiter ;--------------- state table end ------------------ ; Generated by www.piclist.com/cgi-bin/keyword.exe (version April 21, 2000) ; Fri Apr 21 09:47:08 2000 GMT end
Code: