PDA

View Full Version : Can someone show me this?



Oldbitcollector (Jeff)
09-19-2007, 11:02 AM
Now that I've got a handle on storing information from the keyboard, I'm attempting to figure out ways to manipulate it.

for Instance, if I store "type filename" into @command can someone show me how to strip the "type " off leaving
only the "filename" in @command?

It looks like I've got to dump everything after the space to get this right, but I haven't cracked it.

Thanks
Oldbitcollector

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Buttons . . . check. Dials . . . check. Switches . . . check. Little colored lights . . . check.

— Calvin, of 'Calvin and Hobbes.

Mike Green
09-19-2007, 11:31 AM
Just for fun ... Here's an input match routine that you could use to do your keyboard processing. It's currently part of a project using a VMusic2, and is intended for parsing both error messages from the Vinculum and data from a text file from a USB flash drive. It inputs from a serial port, but could be modified to use the keyboard input driver just as easily. The comments pretty well describe what it does. The metacharacter "*" is matched against an arbitrary string and the starting index and length of the matching substrings are stored in a table. The input buffer and substrings are not zero-terminated strings because a zero byte is acceptable as data. The routine follows (because the Attachment Manager is broken with the current Mac Safari browser).


CON
Cr = $0D ' New line / Return
Lf = $0A ' Line feed
Del = $7F ' Delete

maxLine = 80 ' Maximum line / pattern length
maxTime = 1000 ' Maximum time for response
maxArb = 8 ' Maximum number of arbitrary strings

matchArb = $0100 ' Match arbitrary string
matchMax = matchArb + maxArb - 1
matchAny = $01FF ' Match any single character

VAR
long msTime ' Precomputed clkfreq / 1000
word pattern[maxLine] ' Work area for pattern match pattern
byte line[maxLine] ' Input line buffer
byte lineLen ' Current length of input line buffer
byte patternLen ' Current length of pattern
byte arbPtr[maxArb] ' Arbitrary string - pointer to buffer
byte arbLen[maxArb] ' Arbitrary string - length of substring
byte arbPos[maxArb] ' Arbitrary string - position in pattern
byte arbCnt ' Number of arbitrary strings in pattern

OBJ
ser : "FullDuplexSerial"

PUB start(TxD,RxD)
msTime := clkfreq / 1000 ' Precompute system clocks per ms
clearLine ' Initialize input line buffer
ser.start(TxD,RxD,%0000,9600) ' Start the serial port

PRI clearLine ' Clear input line
lineLen := 0

PRI match(str,ptr,lenPtr,maxLen) | p, i, t, s, c, len, arb
'' This routine matches the input line against a pattern supplied as a string.
'' The pattern consists of characters and the metacharacters "*" and "?".
'' The "\" character is an escape and the next byte is taken literally.
'' Special cases include "\0" for a zero byte, "\r" for a carriage return,
'' "\n" for a Unix newline (line feed), and "\d" for delete ($7F).
'' "?" will match any single byte value. "*" will match any arbitrary string.
'' These matches are recorded in arbPtr and arbLen as index and length of the
'' matched substring in the input. This routine returns true if successful
'' and false if there's no match. The match algorithm works by extending the
'' last "*" to the first substring that produces a match. If the input line
'' is not long enough for the match, this routine attempts to read additional
'' characters from the serial (FullDuplexSerial) driver with a total timeout
'' defined by the constant maxTime.
'' str is the address of the pattern, a zero terminated string.
'' ptr is the address of the input line buffer
'' lenPtr is the address of a byte containing the length of the input line
'' maxLen is the allocated size of the input line buffer
patternLen := 0 ' Anchor on left to start of line
arbCnt := 0
repeat ' Go through pattern string
case p := byte[str++]
0: quit ' End of pattern string
"*": ' Match arbitrary string
arbLen[arbCnt] := 0
arbPos[arbCnt] := patternLen
pattern[patternLen++] := matchArb + arbCnt++
"\": ' Escape any byte value
case p := byte[str++]
0: quit ' Ignore if at end of pattern
"0": p := 0 ' Substitute a zero byte
"r": p := Cr ' Substitute a return character
"n": p := Lf ' Substitute a line feed character
"d": p := Del ' Substitute a delete character
pattern[patternLen++] := p
"?": ' Match any single character
pattern[patternLen++] := matchAny
other: ' Any other, take literally
pattern[patternLen++] := p
p := 0
i := 0
arb := -1
len := byte[lenPtr]
t := cnt
repeat ' Go back and forth through pattern
if p == patternLen
if i == len ' At end of pattern, have we matched
return true ' the whole input line?
if arb < 0 ' Can we extend the last arbitrary
return false ' string to get a complete match?
p := arbPos[arb]
i := arbPtr[arb]
arbLen[arb]++
case s := pattern[p++]
matchArb..matchMax: ' Going forward through arbitrary
arb := s - matchArb ' string, just skip over text
arbPtr[arb] := i
i += arbLen[arb]
matchAny: ' Going forward through arbitrary
if i++ == len ' single character. Check length
if len == maxLen
return false
repeat while (c := ser.rxcheck) < 0
if (cnt - t) => msTime * maxTime
return false
byte[lenPtr]++ ' Increment text buffer size
byte[ptr][len++] := c ' and save the character
other: ' Going forward through a literal
if i == len ' character, check max length
if len == maxLen
return false
repeat while (c := ser.rxcheck) < 0
if (cnt - t) => msTime * maxTime
return false
byte[lenPtr]++ ' Increment text buffer size
byte[ptr][len++] := c ' and save the character
if s <> byte[ptr][i++] ' then check for a match
if arb < 0 ' See if we can extend the previous
return false ' arbitrary string to get a match
p := arbPos[arb] ' Extend current arbitrary string
i := arbPtr[arb] ' and try to match again
arbLen[arb]++

deSilva
09-19-2007, 12:34 PM
@Bitcollector: It might be a good idea to look through the appropriate C-libraries, as the techniques used in C are very close to the algorithmic needs of SPIN

Oldbitcollector (Jeff)
09-19-2007, 09:44 PM
Mike: Wow... It could take me a another month to digest how that routine works..

Desilva: Yes, I'm starting to see the similarities to C in spin. That's practical advice.

Actually, I'm pretty close to a working solution. If I use @buffer[#] I could grab each
character of the part I need since I know where the starting position is in each command.
Not a pretty solution, but one I can understand at the level I'm at.

Now that I've gotten my mind wrapped around some of the concepts of byte,and case
(which kept going right over my head initially) The section in the manual for .spin
commands is starting to make sense. There is a real gap that has to be crossed for
someone like myself with limited experience in object-oriented programming.

One of the walls I ran into early with the Propeller is that there is an assumption
of experience in with other micros when starting with the Propeller, a wall
I've been chipping away 'hardware-wise' with the Cookbook.

I'm still building the foundation for a text called ".spin for BASIC programmers"
Perhaps I can bridge this learning gap for others.

Oldbitcollector

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Buttons . . . check. Dials . . . check. Switches . . . check. Little colored lights . . . check.

— Calvin, of 'Calvin and Hobbes.

Bergamot
09-19-2007, 10:02 PM
I'm surprised that Mike Green didn't implement a full regular expression parser http://forums.parallax.com/images/smilies/smilewinkgrin.gif

Mightor
09-20-2007, 02:26 AM
Bergamot said...
I'm surprised that Mike Green didn't implement a full regular expression parser http://forums.parallax.com/images/smilies/smilewinkgrin.gif

He's working on that for the next post, just wait...

Mike, how's the flux_capacitor.spin program coming along?

Gr,
Mightor

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
| To know recursion, you must first know recursion.
| I reject your reality and substitute my own!
| - Adam Savage

Oldbitcollector (Jeff)
09-20-2007, 02:53 AM
He must still be working on the time_space.spin dependency..

;)

Oldbitcollector

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Buttons . . . check. Dials . . . check. Switches . . . check. Little colored lights . . . check.

— Calvin, of 'Calvin and Hobbes.

mcstar
09-20-2007, 02:58 AM
Thanks for the post Mike! Truly,truly I was just thinking about how to go about writing a parser (to handle the vinculum responses) myself. This will give me a great start. The next parser I'm thinking about is one for propositional logic. Perhaps I can work on that one next now.
BTW, my vinculum host responses are already in stuffed into a LockPool, so I'll be modifying Mike's code to work from there. If anyone else wants a version that reads from a memory pool stay tuned and I'll post the code here.