PCP - general aproach
#21
As i say on BPlus topic...sorry mark again i continue here
and as i said above PCP method require some sort of stack or table or list
as Ed explain ,and Ed thanks for that Wink

Code:
' Simple expression evaluator utilizing precedence climbing.
' Ed Davis - works with FreeBasic.
'  test cases:
'  2*-3--4+-0.25 : returns -2.25
'  1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10 : returns 71

'screen setup
Const XMAX = 1200
Const YMAX = 720
ScreenRes XMAX, YMAX
Width XMAX\8, YMAX\16      ' Use 8*16 font

common shared as string eval_error, tok, input_str
const right_assoc=0, left_assoc=1

declare function associativity(op as string) as integer
declare function binary_prec(op as string) as integer
declare function evaluate(e as string) as double
declare function expr(p as integer) as double
declare function is_binary_operator(op as string) as integer
declare function is_digit(ch as string) as integer
declare function is_unary_operator(op as string) as boolean
declare function primary() as double
declare function unary_prec(op as string) as integer
declare sub next_tok

dim as string e  'the string to evaluate
dim as double r  'the number returned if eval successful

? "I am a simple EVALuator, I do operations in the same order as FreeBASIC:"
? "- (Negate), then: * / + -, in that order - see"
? "http://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence for reference."
? "You can also use parenthesis."
?

while 1
   input "Enter a string to evaluate - spaces do not matter > "; e
   if e = "" then end
   r = evaluate(e)
   if eval_error <> "" then print "Error: "; eval_error else print "Expression = "; r
   ?
wend

function evaluate(e as string) as double
   input_str = e
   next_tok()
   return expr(0)
end function

'------ Parser routines ------------------------------------------------

' process binary operators
function expr(p as integer) as double
   dim n as double

   n = primary()
   while is_binary_operator(tok) and binary_prec(tok) >= p
       dim op as string
       dim q as integer
       dim n2 as double
       op = tok

       next_tok()
       select case associativity(op)
           case right_assoc : q = binary_prec(op)
           case left_assoc  : q = 1 + binary_prec(op)
       end select

       n2 = expr(q)
       select case op
           case "*": n = n * n2
           case "/": if n2 = 0 then eval_error = "divide by 0" else n = n / n2
           case "+": n = n + n2
           case "-": n = n - n2
       end select
   wend

   return n
end function

' process unary operators and operands
function primary() as double
   dim op as string
   dim n as double

   if is_unary_operator(tok) then
       op = tok
       next_tok()
       select case op
           case "-" : n = -expr(unary_prec(op))
           case "+" : n =  expr(unary_prec(op))
       end select
   elseif tok = "(" then
       next_tok()
       n = expr(0)
       if tok <> ")" then
           print "expecting ')'"
       else
           next_tok()
       end if
   elseif is_digit(left(tok, 1)) then
       n = val(tok)
       next_tok()
   else
       eval_error = "syntax error: expecting a primary, but found: " & tok
       n = 0
   end if
   return n
end function

'------ Expression helper routines -------------------------------------

function is_unary_operator(op as string) as boolean
   return op = "+" or op = "-"
end function

' should be boolean, but compiler generates a "Type mismatch in..." if so.
function is_binary_operator(op as string) as integer
   return instr("+-*/", op) > 0
end function

' as per: http://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence
function unary_prec(op as string) as integer
   if op = "+" or op = "-" then return 50 else return 0
end function

' as per: http://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence
function binary_prec(op as string) as integer
   select case op
       case "*":  return 40
       case "/":  return 40
       case "+":  return 30
       case "-":  return 30
       case else: return 0
   end select
end function

' as per: http://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence
function associativity(op as string) as integer
   return left_assoc
end function

'------ Scanner --------------------------------------------------------

' find the next operator or operand in input_str, remove it, and store in tok
sub next_tok
   tok = ""
   input_str = trim(input_str)

   while is_digit(left(input_str, 1)) or left(input_str, 1) = "."
       tok = tok + left(input_str, 1)
       input_str = mid(input_str, 2)
   wend

   if tok = "" then
       if instr("()+-*/", left(input_str, 1)) > 0 then
           tok = left(input_str, 1)
           input_str = mid(input_str, 2)
       elseif input_str <> "" then
           eval_error = "unrecognized character: " & left(input_str, 1)
       endif
   endif
end sub

'------ General utility routines ---------------------------------------

function is_digit(ch as string) as integer
   return ch >= "0" and ch <= "9"
end function

/////////// RECURSIVE DESCENT //////////////////////////////////////////////

' Simple expression evaluator utilizing recursive descent.
' Ed Davis - works with FreeBasic.
'  test cases:
'  2*-3--4+-0.25 : returns -2.25
'  1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10 : returns 71

'screen setup
Const XMAX = 1200
Const YMAX = 720
ScreenRes XMAX, YMAX
Width XMAX\8, YMAX\16      ' Use 8*16 font

common shared as string eval_error, tok, input_str
const right_assoc=0, left_assoc=1

declare function evaluate(e as string) as double
declare function expr as double
declare function term as double
declare function factor as double
declare function is_digit(ch as string) as integer
declare sub next_tok

dim as string e  'the string to evaluate
dim as double r  'the number returned if eval successful

? "I am a simple EVALuator, I do operations in the same order as FreeBASIC:"
? "- (Negate), then: * / + -, in that order - see"
? "http://www.freebasic.net/wiki/wikka.php?wakka=OpPrecedence for reference."
? "You can also use parenthesis."
?

while 1
   input "Enter a string to evaluate - spaces do not matter > "; e
   if e = "" then end
   r = evaluate(e)
   if eval_error <> "" then print "Error: "; eval_error else print "Expression = "; r
   ?
wend

function evaluate(e as string) as double
   input_str = e
   next_tok()
   return expr()
end function

'------ Parser routines ------------------------------------------------

function expr as double
   dim n as double

   n = term()
   while tok = "+" or tok = "-"
       dim op as string
       dim n2 as double
       op = tok

       next_tok()

       n2 = term()
       select case op
           case "+": n = n + n2
           case "-": n = n - n2
       end select
   wend

   return n
end function

function term as double
   dim n as double

   n = factor()
   while tok = "*" or tok = "/"
       dim op as string
       dim n2 as double
       op = tok

       next_tok()

       n2 = factor()
       select case op
           case "*": n = n * n2
           case "/": if n2 = 0 then eval_error = "divide by 0" else n = n / n2
       end select
   wend

   return n
end function

' process unary operators and operands
function factor() as double
   dim op as string
   dim n as double

   if tok = "+" or tok = "-" then
       op = tok
       next_tok()
       select case op
           case "-" : n = -factor()
           case "+" : n =  factor()
       end select
   elseif tok = "(" then
       next_tok()
       n = expr()
       if tok <> ")" then
           print "expecting ')'"
       else
           next_tok()
       end if
   elseif is_digit(left(tok, 1)) then
       n = val(tok)
       next_tok()
   else
       eval_error = "syntax error: expecting a primary, but found: " & tok
       n = 0
   end if
   return n
end function

'------ Scanner --------------------------------------------------------

' find the next operator or operand in input_str, remove it, and store in tok
sub next_tok
   tok = ""
   input_str = trim(input_str)

   while is_digit(left(input_str, 1)) or left(input_str, 1) = "."
       tok = tok + left(input_str, 1)
       input_str = mid(input_str, 2)
   wend

   if tok = "" then
       if instr("()+-*/", left(input_str, 1)) > 0 then
           tok = left(input_str, 1)
           input_str = mid(input_str, 2)
       elseif input_str <> "" then
           eval_error = "unrecognized character: " & left(input_str, 1)
       endif
   endif
end sub

'------ General utility routines ---------------------------------------

function is_digit(ch as string) as integer
   return ch >= "0" and ch <= "9"
end function
Reply
#22
I post about this on my forum too..
http://basicpro.mipropia.com/smf/index.php?topic=26.0
Reply
#23
Hi Aurel,

I checked out your forum last night and was pleasantly shocked to see how much it had grown since last I looked! Smile

I was just plain shocked to see Tomaaz there asking for help.

Wasn't he the one who mocked your English ever harder than easy? Wink
B += x
Reply
#24
Yes Mark ..yes
tomek is such a jerk but i show to him that i am better man
f***
he need his config file for geany editor ,he also says that he delete most
accounts on other forums...????
but who cares
he he
Reply
#25
Thanks to mr Richard Russell who give me this code
so i tried in LBBooster,he says that folow pcp method
work fine but without parens.

Code:
' Test of expression evaluator

      !*KEY 1 2^3*2^3+4|M
      !*KEY 2 1-2-3-4-5-6|M
      !*KEY 3 1/2/3/4/5/6|M
      !*KEY 4 1+2-3*4/5^6/7*8-9+10|M
      !*KEY 5 1^2/3*4-5+6-7*8/9^10|M
      !*KEY 6 2^3*2+4|M
      !*KEY 7 1+2^3*4|M
      !*KEY 8 3.14159|M
      !*KEY 9 -5^2|M

      print "Use function keys for preset expressions"
      print

      do
        input "Enter a numeric expression (+,-,*,/,^ operators only): "; E$
        result1 = eval(E$)
        print "BASIC's evaluator gives: ";result1
        op = 0 : pr = 1
        result2 = evaluate(E$, op, pr, 99)
        print "Test evaluator gives: ";result2
        if result1 <> result2 then print "ERROR!!!!"
      loop until 0

function evaluate(byref E$, byref O, byref o, ecxedx)
      dim p(5)
      p(1) = 1 : p(2) = 1 : p(3) = 2 : p(4) = 2 : p(5) = 3

      do
        P = O
        p = o
        eaxebx = ecxedx
        ecxedx = val(E$)
        do
          E$ = mid$(E$,2)
          O = instr("+-*/^", left$(E$,1))
        loop until O<>0 or E$=""
        E$ = mid$(E$,2) ' Skip past operator
        o = p(O)

        while o > p : ecxedx = evaluate(E$, O, o, ecxedx) : wend

        temp = eaxebx : eaxebx = ecxedx : ecxedx = temp
        select case P
          case 0: ecxedx = eaxebx
          case 1: ecxedx = ecxedx + eaxebx
          case 2: ecxedx = ecxedx - eaxebx
          case 3: ecxedx = ecxedx * eaxebx
          case 4: ecxedx = ecxedx / eaxebx
          case 5: ecxedx = ecxedx^eaxebx
        end select

      loop until o < p
      evaluate = ecxedx
end function
Reply
#26
Hi Aurel,

He has posted a very sweet, simple one with () at JB forum.



Append:

Oops! Someone just deleted the whole thread "Basic in a Basic". What????

Oh well, a very interesting post at Retrogamecoding.
B += x
Reply
#27
Yes and do you know who might be that ?
I think that i know probably narcisoide moderator Rod,
I must tell bim to delete precedence climbing topic to
such a schmak, that is why i dont like that place .
Do you rememver what that freakk says;JB forum is place for
old fartss and young zombie kids.
I really dont know why you wasting your time posting on that
ugly forum.

what interesting topic on retroB ?
Reply
#28
(07-19-2017, 05:09 PM)Aurel Wrote: Yes and do you know who might be that ?
I think that i know probably narcisoide moderator Rod,
I must tell bim to delete precedence climbing topic to
such a schmak, that is why i dont like that place .
Do you rememver what that freakk says;JB forum is place for
old fartss and young zombie kids.
I really dont know why you wasting your time posting on that
ugly forum.

what interesting topic on retroB ?
Hi Aurel,

You know hanging out with you is dangerous to my reputation, whatever might be left of it. I mean look what you have done to another common acquaintance of ours? Good BOT man!

Now I think I know why Rod might be deleting my posts, at least when I am hanging out with a certain element.

Nutz, I say, totally nutz but look what it does to viewership ratings!

My BOT, what ratings we get when we battle!

Name calling OK so long as it is not members of this forum?

Distorting what people say also OK so long as not members of this forum?

So what is narcisoide? I am unfamiliar with the term is it from the Portuguese language?

I think it is like narcissist of which I know many including myself. After all isn't in our human nature to look out for (and at) #1?
(Just maybe perverse to admit to it!)

(Disposable item Just For Walter Captain Kirk A.I Chat Bot :))

EDIT: Spelling errors, sorry no spellchecker in Notepad.
(Append again): It really sucks when you accidently spell another word correctly but not the one you intended!
(Append once more): It really, really sucks when the unintended correctly spelled word looks like you are insulting another, especially when you are campaigning against such lousy tactics. Yikes!

APPEND: It is certainly perverse if #1 is ALL you look out for (or at).
B += x
Reply
#29
Mark
My friendly advice to you or to anyone ...
stop to be a mouse and be a man
what kind of reputation...?
is that reputation have anything with your real life?
i think no ..because all this is on internet and who care about reputation?
another thing ..stop to think that anything on internet is important
then you will be free..
i hope that you understand very well what i am talking about..
Reply
#30
(07-20-2017, 01:27 AM)bplus Wrote:
(07-19-2017, 05:09 PM)Aurel Wrote: Yes and do you know who might be that ?
I think that i know probably narcisoide moderator Rod,
I must tell bim to delete precedence climbing topic to
such a schmak, that is why i dont like that place .
Do you rememver what that freakk says;JB forum is place for
old fartss and young zombie kids.
I really dont know why you wasting your time posting on that
ugly forum.

what interesting topic on retroB ?
Hi Aurel,

You know hanging out with you is dangerous to my reputation, whatever might be left of it. I mean look what you have done to another common acquaintance of ours? Good BOT man!

Now I think I know why Rod might be deleting my posts, at least when I am hanging out with a certain element.

Nutz, I say, totally nutz but look what it does to viewership ratings!

My BOT, what ratings we get when we battle!

Name calling OK so long as it is not members of this forum?

Distorting what people say also OK so long as not members of this forum?

So what is narcisoide? I am unfamiliar with the term is it from the Portuguese language?

I think it is like narcissist of which I know many including myself. After all isn't in our human nature to look out for (and at) #1?
(Just maybe perverse to admit to it!)

(Disposable item Just For Walter Captain Kirk A.I Chat Bot :))

EDIT: Spelling errors, sorry no spellchecker in Notepad.
(Append again): It really sucks when you accidently spell another word correctly but not the one you intended!
(Append once more): It really, really sucks when the unintended correctly spelled word looks like you are insulting another, especially when you are campaigning against such lousy tactics. Yikes!

APPEND: It is certainly perverse if #1 is ALL you look out for (or at).

(07-20-2017, 03:24 AM)Aurel Wrote: Mark
My friendly advice to you or to anyone ...
stop to be a mouse and be a man
what kind of reputation...?
is that reputation have anything with your real life?
i think no ..because all this is on internet and who care about reputation?
another thing ..stop to think that anything on internet is important
then you will be free..
i hope that you understand very well what i am talking about..
Ah yes! This is why I hang out with you.

If I were free, who cares if I am mouse or man?
(maybe the mice?)


Append: Oh my! I only wanted to quote the last post. Must be my crappy browser again!
BOT forgive me for continuing to use such a crappy tool.
B += x
Reply
#31
oh i forgot
execuse me my majesty i am just poor BOT
and i cannot forgive you ..he he
if you really mean that your reputation worth something on that forum
then i dont have nothing to add.... beeep


oups ...maybe hidden agenda ?
maybe you want to be new moderator on that sucky place
oh,,,,oups ..sorry...
Reply
#32
(07-20-2017, 06:04 AM)Aurel Wrote: oh i forgot
execuse me my majesty i am just poor BOT
and i cannot forgive you ..he he
if you really mean that your reputation worth something on that forum
then i dont have nothing to add.... beeep


oups ...maybe hidden agenda ?
maybe you want to be new moderator on that sucky place
oh,,,,oups ..sorry...
No moderator, just wondering why threads I post in are disappearing with no explanation.

I think it's because I reply to Richard or talk about his code, totally taboo there?

How is your PCP quest going? Have you tried Rosetta?
B += x
Reply
#33
-- How is your PCP quest going? Have you tried Rosetta? 

its ok but i'm little busy with other things
what about rosetta ?
well if you mean on pcp example in RCode hmmm there is no
concrete example about this.
Reply
#34
http://rosettacode.org/wiki/Arithmetic_evaluation

Oh, right this topic was "messed up" by the AST stuff. I had forgotten.
B += x
Reply