Okay, it took a bit of detective work, but, I think I figured it out.
Attached is a working version of a Recursive Descent Parser for Yabasic.
' rdparser.yab
' Copyright:(c) sarbayo, 2012
' special credits to: Jack Crenshaw's:
' "How to Build a Compiiler"
' This is an: LALR-RD Parser (Look-Ahead, Left-to-Right, Recursive-Descent)
' Based on: Rdparser.c, in Bxbasic
' --------------------- SYSTEM VARIABLES ---------------------
DIM pstring$(1)
tholder$ = ""
xstring$ = ""
epos = 1
xlen = 0
dreturn = 0
ireturn = 0
' ----- begin program -------------
' CLEAR SCREEN
main()
Print
label TheEnd
' Pause 10
END
' ===========================================================
SUB main()
Local value, ii, instring$
value = 0
ii = 0
instring$ = ""
Print
Print "LALR Parser"
Print
Print "Enter Expression: Example: 1+2*3*4*10/5"
Print " ";
INPUT instring$
IF (instring$ = "") THEN
GOTO DoneMain
ENDIF
xlen = LEN(instring$)
ii = xlen + 1
REDIM pstring$(ii)
FOR ii = 1 TO xlen
pstring$(ii) = MID$(instring$, ii, 1)
NEXT ii
pstring$(ii) = CHR$(0)
Expression()
value = dreturn
Print " ", "result = ", value
label DoneMain
'
END SUB
' --------- end main ---------
SUB Expression()
Local ch$, pii, isaddop, ich, eValue
pii = epos
ch$ = pstring$(pii)
IsAddop(ch$)
isaddop = ireturn
IF (isaddop = 1) THEN
eValue = 0
ELSE
Term()
eValue = dreturn
pii = epos
ch$ = pstring$(pii)
ENDIF
IsAddop(ch$)
isaddop = ireturn
WHILE (isaddop = 1)
ich = ASC(ch$)
SWITCH ich
CASE 43
Match()
Term()
eValue = eValue + dreturn
BREAK
CASE 45
Match()
Term()
eValue = eValue - dreturn
BREAK
END SWITCH
pii = epos
ch$ = pstring$(pii)
IsAddop(ch$)
isaddop = ireturn
WEND
dreturn = eValue
END SUB
' ---------- end Expression ----------
SUB Term()
Local ch$, pii, tValue, ismultop, ich
Factor()
tValue = dreturn
pii = epos
ch$ = pstring$(pii)
IsMultop(ch$)
ismultop = ireturn
WHILE (ismultop = 1)
ich = ASC(ch$)
SWITCH ich
CASE 42
Match()
Factor()
tValue = tValue * dreturn
BREAK
CASE 47
Match()
Factor()
tValue = tValue / dreturn
BREAK
CASE 94
Match()
Factor()
tValue = tValue ^ dreturn
BREAK
CASE 37
Match()
Factor()
ireturn = INT(dreturn)
tValue = INT(tValue)
tValue = mod(tValue, ireturn)
BREAK
END SWITCH
pii = epos
ch$ = pstring$(pii)
IsMultop(ch$)
ismultop = ireturn
WEND
dreturn = tValue
END SUB
' ---------- end Term ----------
SUB Factor()
Local ch$, pii, isalpha, fvalue
pii = epos
ch$ = pstring$(pii)
IF (ch$ = "(") THEN
Match()
Expression()
fvalue = dreturn
Match()
ELSE
GetNum()
fvalue = dreturn
ENDIF
dreturn = fvalue
END SUB
' ---------- end Factor ----------
' ====================== rdp utility routines ======================
SUB Match()
Local pii
pii = epos
IF (pii < xlen) THEN
GetChar()
SkipWhite()
ENDIF
END SUB
'---------- end Match ----------
SUB GetNum()
Local ch$, pii, isdigit, abcode, ln, gvalue
abcode = 12
ln = 1
pii = epos
ch$ = pstring$(pii)
IF (pii <= xlen) THEN
IsDigit(ch$)
isdigit = ireturn
IF (isdigit = 0) THEN
tholder$ = "Numeric Value"
abort(abcode, ln)
ENDIF
asc2dbl()
gvalue = dreturn
pii = epos
ch$ = pstring$(pii)
IsDigit(ch$)
isdigit = ireturn
IF (isdigit = 1) THEN
While (isdigit = 1)
pii = pii + 1
ch$ = pstring$(pii)
IsDigit(ch$)
isdigit = ireturn
WEND
epos = pii
ENDIF
SkipWhite()
ENDIF
dreturn = gvalue
END SUB
' ---------- end GetNum ----------
SUB asc2dbl()
Local ch$, cvalue$, pii, isdigit, fvalue
cvalue$ = ""
pii = epos
ch$ = pstring$(pii)
isdigit = 1
While (isdigit = 1)
cvalue$ = cvalue$ + ch$
pii = pii + 1
ch$ = pstring$(pii)
IsDigit(ch$)
isdigit = ireturn
WEND
fvalue = VAL(cvalue$)
epos = pii
dreturn = fvalue
END SUB
' ------- end asc2dbl ---------
SUB GetChar()
epos = epos + 1
END SUB
' ---------- end GetChar ----------
SUB IsAddop(ch$)
Local rval
rval = 0
IF (ch$ = "+" OR ch$ = "-") THEN
rval = 1
ENDIF
ireturn = rval
END SUB
' ---------- end IsAddop ----------
SUB IsMultop(ch$)
Local rval
rval = 0
IF (ch$ = "*" OR ch$ = "^" OR ch$ = "%" OR ch$ = "/") THEN
rval = 1
ENDIF
ireturn = rval
END SUB
' ---------- end IsMultop ----------
SUB IsDigit(ch$)
Local test, ival
test = 0
ival = 0
ival = ASC(ch$)
IF (ival >= 48 AND ival <= 57 OR ch$ = ".") THEN
test = 1
ENDIF
ireturn = test
END SUB
' ---------- end IsDigit ----------
SUB IsAlpha(ch$)
Local test, ival
test = 0
ival = 0
ival = ASC(ch$)
IF (ival >= 65 AND ival <= 90 OR ival >= 97 AND ival <= 122) THEN
test = 1
ENDIF
ireturn = test
END SUB
' ----------end IsAlpha -----------
SUB IsWhite(ch$)
Local test, tab$
test = 0
tab$ = CHR$(9)
IF (ch$ = " " OR ch$ = tab$) THEN
test = -1
ENDIF
ireturn = test
END SUB
' ---------- end IsWhite ----------
SUB SkipWhite()
Local ch$, pii, iswhite
ch$ = ""
pii = 0
iswhite = 0
pii = epos
ch$ = pstring$(pii)
IsWhite(ch$)
iswhite = ireturn
WHILE (iswhite <> 0)
GetChar()
pii = epos
ch$ = pstring$(pii)
IsWhite(ch$)
iswhite = ireturn
WEND
END SUB
' ---------- end SkipWhite ----------
SUB abort(code, linendx)
Local instring$, ii
instring$ = ""
ii = 0
FOR ii = 1 TO xlen
instring$ = instring$ + pstring$(ii)
NEXT ii
BEEP
Switch code
Case 12
Print
Print "Expected ", tholder$, " ",
Print ": in line: ", linendx
Print instring$
Print "code(", code, ")"
BREAK
DEFAULT
Print "Program aborted, undefined error."
BREAK
END SWITCH
END
END SUB
' ----------end abort -----------
To try it, simply enter: yabasic rdparser.yab
you will be prompted to enter a numeric expression.
This is a stripped down version, no algebraic functions are available in this version.
Example: 1+2*(3*4)*(10/5)