Arithmetic Expression Parser

Charlie Veniot12th March 2022 at 12:06am
' This program based on https://rosettacode.org/wiki/Arithmetic_evaluation#BBC_BASIC
'
' ๐ŸŸ  FUNCTION DECLARATIONS
	declare function fNast$()
	declare function fNast1$()
	declare function fNast2$()
	declare function fNumber$()
' ๐ŸŸ  MAIN PROGRAM
	Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
	'Expr$ = "(1 + 2) * 3"
	PRINT "Input = " + Expr$
	print "fNast$ = " + fNast$()
	'AST$ = fNast$()
	'PRINT "AST =   " +  AST$
	'PRINT "Value = " ;EVAL(AST$)
	END
'
' ๐ŸŸ  FUNCTION DEFINITIONS
function fNast$()
	dim ast$, oper$ as string
	ast$ = ""
	fNast_repeat:
		ast$ += FNast1$()
		WHILE ASC(Expr$)=32
			Expr$ = MID$(Expr$,2,len(Expr$)-1)
		wend
		oper$ = LEFT$(Expr$,1)
		IF oper$="+" OR oper$="-" THEN
			ast$ += oper$
			Expr$ = MID$(Expr$,2,len(Expr$)-1)
			goto fNast_repeat
		end if
	fNast$ = "(" + ast$ + ")"
end function
function fNast1$()
	dim ast$, oper$ as string
	ast$ = ""
	fNast1_repeat:
		ast$ += fNast2$()
		WHILE ASC(Expr$)=32
			Expr$ = MID$(Expr$,2,len(Expr$)-1)
		wend
		oper$ = LEFT$(Expr$,1)
		IF oper$="*" OR oper$="/" THEN
			ast$ += oper$
			Expr$ = MID$(Expr$,2,len(Expr$)-1)
			goto fNast1_repeat
		end if
	fNast1$ = "(" + ast$ + ")"
end function
function fNast2$()
	dim ast$ as string
	WHILE ASC(Expr$)=32
  		Expr$ = MID$(Expr$,2,len(Expr$)-1)
	wend
	IF ASC(Expr$)=40 THEN
		Expr$ = MID$(Expr$, 2, len(Expr$)-1)
		ast$ = fNast$()
		Expr$ = MID$(Expr$,2, len(Expr$)-1)
	ELSE
		ast$ = fNumber$()
	end if
	fNast2$ = ast$
end function
function fNumber$()
	dim ch$, num$ as string
	num$ = ""
	fNumber_repeat:
		ch$ = left$(Expr$, 1)
		' ๐Ÿšจ wwwBASIC: issues with instr breaking app when the character is a parenthesis
		if ch$ <> "" and instr("0123456789.", ch$) then
			num$ += ch$
			Expr$ = mid$(Expr$,2,len(Expr$)-1)
			goto fNumber_repeat
		end if
	fNumber$ = num$
end function