Author Topic: The Recursive Descent Parser  (Read 9693 times)

0 Members and 1 Guest are viewing this topic.

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #15 on: March 19, 2019, 11:36:50 am »
hi jack
Yes you have right IF we use this program as finished or completed
but if you wish to add more operation under factor() function then makes no sense to use
ELSE...
so probably should be better to use ELSEIF method
but that is another story.
In fact match just operate under parens () in another word if parens exists.
hmmm is that ok ?
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline Ed Davis

  • Newbie
  • Posts: 40
    • View Profile
Re: The Recursive Descent Parser
« Reply #16 on: March 19, 2019, 12:09:06 pm »
As we can see this few functions are really simple.

Try this expression: 1+2+3

The answer should be 6, but the evaluator returns 3.  I think recursion in qb64 is broken.

Hmmm.  Searching old messages, only broken if 0 arguments.  I changed expr# and term# to take a single argument, changed the calls to the same, and now it works fine.

Will this be fixed one day, or is it for backwards compatibility or something and thus will remain as it is?

Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: The Recursive Descent Parser
« Reply #17 on: March 19, 2019, 12:51:19 pm »
@Ed Davis
would you post the code please?

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #18 on: March 19, 2019, 01:26:50 pm »
Quote
I think recursion in qb64 is broken

no ..is not
it is problem in evaluator because i get same error in o2 version ..too
I don't understand exatly what you mean under single argument?
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: The Recursive Descent Parser
« Reply #19 on: March 19, 2019, 01:57:55 pm »
Quote
I think recursion in qb64 is broken

no ..is not
it is problem in evaluator because i get same error in o2 version ..too
I don't understand exatly what you mean under single argument?

Read the issue and a fix here: https://www.qb64.org/forum/index.php?topic=704.msg5802#msg5802

Basically, the following is broken:

Code: QB64: [Select]
  1. X = 5
  2.  
  3. IF X = 0 THEN F = 1 ELSE PRINT "*": X = X - 1: F = F

Luke was going to try and sort out a solution to the issue in the evaltype routine, but has been busy with life in general and hasn’t gotten around to it yet.  If you use zero-argument recursion a lot, you might want to apply my patch to QB64.bas and recompile the EXE.  If not, and it’s a once-in-a-bluemoon issue, just pass a dummy parameter to the function.

Instead of:

FUNCTION foo
   Foo = foo
END FUNCTION

Use:

Function Foo (dummy)
   Foo = Foo (Whatever)
END FUNCTION
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Ed Davis

  • Newbie
  • Posts: 40
    • View Profile
Re: The Recursive Descent Parser
« Reply #20 on: March 19, 2019, 02:01:28 pm »
Quote
I think recursion in qb64 is broken

no ..is not
it is problem in evaluator because i get same error in o2 version ..too
I don't understand exatly what you mean under single argument?

Original version, but with a different expression - should show 6, but it shows 3:
Code: QB64: [Select]
  1. 'recursive descent token evaluator - original version
  2. DIM SHARED tokens(8) AS STRING * 1
  3.  
  4. tc = 0
  5. tokens(1) = "1"
  6. tokens(2) = "+"
  7. tokens(3) = "2"
  8. tokens(4) = "+"
  9. tokens(5) = "3"
  10.  
  11. 'execute---------------
  12. CALL gettok 'start
  13. res = expr#
  14. PRINT res
  15.  
  16. SUB gettok ()
  17.     tc = tc + 1
  18.     token = tokens(tc)
  19.  
  20. FUNCTION expr# ()
  21.     DIM v AS DOUBLE
  22.     v = term#
  23.     IF token = "+" THEN
  24.         gettok
  25.         v = v + term#
  26.     END IF
  27.     IF token = "-" THEN
  28.         gettok
  29.         v = v - term#
  30.     END IF
  31.     expr# = v
  32.  
  33. FUNCTION term# ()
  34.     DIM v AS DOUBLE
  35.     v = factor#
  36.     IF token = "*" THEN
  37.         gettok
  38.         v = v * factor#
  39.     END IF
  40.     IF token = "/" THEN
  41.         gettok
  42.         v = v / factor#
  43.     END IF
  44.     term# = v
  45.  
  46. FUNCTION factor# ()
  47.     DIM v AS DOUBLE
  48.     IF ASC(token) > 47 AND ASC(token) < 58 THEN 'nums
  49.         v = VAL(token)
  50.         gettok
  51.     END IF
  52.     IF ASC(token) = 40 AND ASC(token) <> 41 THEN 'match (...)
  53.         gettok
  54.         v = expr#
  55.         gettok
  56.     END IF
  57.     factor# = v
  58.  

Updated version, but using one (dummy) argument for expr and term - gets the right answer:
Code: QB64: [Select]
  1. 'recursive descent token evaluator - added dummy arguments
  2. DIM SHARED tokens(8) AS STRING * 1
  3.  
  4. tc = 0
  5. tokens(1) = "1"
  6. tokens(2) = "+"
  7. tokens(3) = "2"
  8. tokens(4) = "+"
  9. tokens(5) = "3"
  10.  
  11. 'execute---------------
  12. CALL gettok 'start
  13. res = expr#(0)
  14. PRINT res
  15.  
  16. SUB gettok ()
  17.     tc = tc + 1
  18.     token = tokens(tc)
  19.  
  20. FUNCTION expr# (x as integer)
  21.     DIM v AS DOUBLE
  22.     v = term#(0)
  23.     IF token = "+" THEN
  24.         gettok
  25.         v = v + expr#(0)
  26.     ELSEIF token = "-" THEN
  27.         gettok
  28.         v = v - expr#(0)
  29.     END IF
  30.     expr# = v
  31.  
  32. FUNCTION term# (x as integer)
  33.     DIM v AS DOUBLE
  34.     v = factor#
  35.     IF token = "*" THEN
  36.         gettok
  37.         v = v * term#(0)
  38.     ELSEIF token = "/" THEN
  39.         gettok
  40.         v = v / term#(0)
  41.     END IF
  42.     term# = v
  43.  
  44. FUNCTION factor# ()
  45.     DIM v AS DOUBLE
  46.     IF ASC(token) > 47 AND ASC(token) < 58 THEN 'nums
  47.         v = VAL(token)
  48.         gettok
  49.     ELSEIF ASC(token) = 40 AND ASC(token) <> 41 THEN 'match (...)
  50.         gettok
  51.         v = expr#(0)
  52.         gettok
  53.     END IF
  54.     factor# = v
  55.  

See this message: https://www.qb64.org/forum/index.php?topic=676.msg5776#msg5776
for a confirmation of the recursion bug.

Interestingly, FreeBasic, in QB mode, also has the same problem.  However, when compiled in normal FreeBasic mode (some minor changes have to be made to the code), it works fine.



Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #21 on: March 19, 2019, 03:04:58 pm »
Hmm that is interesting and as i said same problem i found in o2 version
I don't look first time what was going on using token one by one (in each step)
then when i look again into my old interpretr i figured that i use
while loop with operators +,-,*,/
so probably this loop add one turn more for "dummy" effect and
now everything work as it should be .
strange thing ..i must try with null too...
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: The Recursive Descent Parser
« Reply #22 on: March 20, 2019, 10:14:36 am »
I don't think you guys have it fixed yet:

Code: QB64: [Select]
  1. _TITLE "Recursive descent token evaluator by Aurel"
  2. 'trenslation by @jack 19.3.2019
  3. ' nope! now use Ed Davis fix: https://www.qb64.org/forum/index.php?topic=33.15
  4. 'mod by B+ 2019-03-20 so that can test any number of expressions
  5.  
  6. 'tc = 0
  7. 'tokens(1) = "2"
  8. 'tokens(2) = "*"
  9. 'tokens(3) = "("
  10. 'tokens(4) = "3"
  11. 'tokens(5) = "+"
  12. 'tokens(6) = "4"
  13. 'tokens(7) = ")"
  14.  
  15.     INPUT "Enter an expression to evaluate: ", eval$
  16.     le = LEN(eval$)
  17.     IF le THEN
  18.         tc = 0
  19.         REDIM SHARED tokens(1 TO le + 1) AS STRING * 1
  20.         FOR i = 1 TO le
  21.             tokens(i) = MID$(eval$, i, 1)
  22.         NEXT
  23.         'execute---------------
  24.         'CALL gettok 'start
  25.         gettok
  26.         res = expr#(0)
  27.         PRINT res
  28.     END IF
  29. LOOP UNTIL le = 0
  30.  
  31. 'recursive descent token evaluator - added dummy arguments  (fixed set? by Ed Davis)
  32. SUB gettok ()
  33.     tc = tc + 1
  34.     token = tokens(tc)
  35.  
  36. FUNCTION expr# (x AS INTEGER)
  37.     DIM v AS DOUBLE
  38.     v = term#(0)
  39.     IF token = "+" THEN
  40.         gettok
  41.         v = v + expr#(0)
  42.     ELSEIF token = "-" THEN
  43.         gettok
  44.         v = v - expr#(0)
  45.     END IF
  46.     expr# = v
  47.  
  48. FUNCTION term# (x AS INTEGER)
  49.     DIM v AS DOUBLE
  50.     v = factor#
  51.     IF token = "*" THEN
  52.         gettok
  53.         v = v * term#(0)
  54.     ELSEIF token = "/" THEN
  55.         gettok
  56.         v = v / term#(0)
  57.     END IF
  58.     term# = v
  59.  
  60. FUNCTION factor# ()
  61.     DIM v AS DOUBLE
  62.     IF ASC(token) > 47 AND ASC(token) < 58 THEN 'nums
  63.         v = VAL(token)
  64.         gettok
  65.     ELSEIF ASC(token) = 40 AND ASC(token) <> 41 THEN 'match (...)
  66.         gettok
  67.         v = expr#(0)
  68.         gettok
  69.     END IF
  70.     factor# = v
  71.  
  72.  
Still not fixed.PNG


Wait this was limited to only single digits? :P
« Last Edit: March 20, 2019, 10:22:19 am by bplus »

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #23 on: March 20, 2019, 10:31:28 am »
Quote
Wait this was limited to only single digits?

No i think NOT limited to one digit.
token should use any number like "12345"
First i will check again o2 version then i try fix qb64 version ok?
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline Ed Davis

  • Newbie
  • Posts: 40
    • View Profile
Re: The Recursive Descent Parser
« Reply #24 on: March 20, 2019, 10:38:07 am »
I don't think you guys have it fixed yet:

Wait this was limited to only single digits? :P

Correct.  There isn't a real scanner - it just assumes single characters, no spaces allowed.  I guess Aurel posted it to "get his feet wet" with QB64?  So it is at best a simple demo, nothing more.

I like your colors, by the way!

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #25 on: March 20, 2019, 11:26:03 am »
In another words
if we wish to enter expression and evaluate it , we need TOKENIZER
to split our expression into tokens( read numbers & operators )
is that ok.
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #26 on: March 20, 2019, 12:14:14 pm »
well i tryed  this without dummy load and with additional while loop
like i do in o2 but nothing ...
token taken are
1
+
2
  0

//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: The Recursive Descent Parser
« Reply #27 on: March 20, 2019, 12:32:03 pm »
Aurel your attempts here have me skimming over Erik's massive and successful undertaking and having me appreciate all over again Erik's effort. :)


Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #28 on: March 20, 2019, 01:59:57 pm »
Yes Mark
Erik really do big work with his SICK engine ...
and is not very easy to follow all what he do in it.
It is great but little bit too complex for me.
He use large amount of string processing which confuses me..
of course i understand them all but as i said is not easy to get what is what(for me
even i have experience in that things)- of course not like Ed ;)
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////

Offline Aurel

  • Forum Regular
  • Posts: 167
    • View Profile
Re: The Recursive Descent Parser
« Reply #29 on: March 21, 2019, 10:55:50 am »
Hi..
I just forund in my old programs one created by author of qb64
i called that program GALEON BASIC.
This program is posted on old forum ..long time ago.
There is a interesting way used for evaluating expression with GOTO command..
so can i publish it here ?
//////////////////////////////////////////////////////////////////
https://aurelsoft.ucoz.com
https://www.facebook.com/groups/470369984111370
//////////////////////////////////////////////////////////////////