r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Parse] Discussion of PARSE dialect

BrianH
30-Sep-2009
[4251x2]
Assuming yo are using the PARSE stack and not rolling your own.
I wonder if a PARSE optimizer could be written, to reduce use of 
stack and other resources by automatically rewriting the rules.
Maxim
30-Sep-2009
[4253x2]
rollback would be neet as a parse keyword  :-)  it would allow us 
to break several levels at once... something I would have needed 
when I did my XML schema validation engine.
brian, wait a few hours, Gabriele will pop up saying he has one, 
but unfinished and slightly buggy, somewhere on his HD   ;-D
BrianH
30-Sep-2009
[4255x3]
Gabriele always has something like this. His stuff can be difficult 
for mere mortals like me to understand though :(
I swear, it seems like he writes his code using a literate encoding 
engine so that he can remember what it does. Write-only code.
Great code though :)
Steeve
30-Sep-2009
[4258]
With R2

paren: [#"(" paren #")"]

can be replaced by the rule

p: 0
cont: none
start: [#"(" (p: p + 1)]

rule: [start any [
	start
	| #")" (cont: if zero? p: p - 1 ['break]) cont
]]

But i wonder if it's faster
BrianH
30-Sep-2009
[4259]
Likely not. The question isn't faster, it's whether it runs at all.
Steeve
30-Sep-2009
[4260x2]
i'm a little worried now, i'm afraid we can't bound our own words 
with commands in R3
such trick:
(cont: if zero? p: p - 1 ['break]) cont
doesn't work anymore IIRC
Maxim
30-Sep-2009
[4262]
try without the '
Steeve
30-Sep-2009
[4263x3]
i guess not, but i will try
it doesn't work
it's a broblem specificaly for the BREAK command, because it can't 
be encaped in a block, it has to be on the same level than the ANY/SOME 
block to be effective
Maxim
30-Sep-2009
[4266]
yeah, cause it just breaks the block its in.
Steeve
30-Sep-2009
[4267]
but with the IF command it should not be too much worrying
Maxim
30-Sep-2009
[4268x2]
some rules will definitely need to be changed with the three hacks 
he now made officially "illegal"
but that should only affect.... hackers...  ;-)
BrianH
30-Sep-2009
[4270x2]
; R3 style
rule: [(p: 0) any [
    #"(" (++ p) |
    #")" if (1 >= -- p) then break | none
] if (p = 0)]
On one line:

rule: [(p: 0) any [#"(" (++ p) | #")" if (1 >= -- p) then break | 
none] if (p = 0)]
Steeve
30-Sep-2009
[4272]
As i thought, we are saved :-)
BrianH
30-Sep-2009
[4273]
Needs some tweaking though.
Maxim
30-Sep-2009
[4274]
the   [IF () THEN rule | rule ]  reads nicely when used in parse 
rules. I find.
Steeve
30-Sep-2009
[4275]
a smell of old BASIC
Maxim
30-Sep-2009
[4276]
hehe  yeah... that's it  ;-)
Steeve
30-Sep-2009
[4277]
what's that if (p=0) at the tail ?
BrianH
30-Sep-2009
[4278]
Checks to see if the counter is even. Badly, I'm afraid, needs tweaking 
(which I'm doing now).
Maxim
30-Sep-2009
[4279]
why not use  'EVEN?
Steeve
30-Sep-2009
[4280x2]
EVEN? you mean negative ?
it can't be...
BrianH
30-Sep-2009
[4282]
Even, meaning the ( and ) are balanced. p starts as 0, and should 
end as 0.
Steeve
30-Sep-2009
[4283x4]
yep, it can't exit the loop without equality
except if it's the end. So,  your final condition is [not end]
not enough....
yep, you have to check that for
BrianH
30-Sep-2009
[4287x5]
rule: [(p: 0) any [#"(" (++ p) | #")" if (1 <= -- p) then none | 
break] if (p = 0)]
That works. If there is remaining input when you run out of rules, 
that coounts as failure.
It took reversing the if then condition to do it.
>> parse "(()" [(p: 0) any [#"(" (++ p) | #")" if (1 <= -- p) then 
none | break] if (p = 0)]
== false

>> parse "(())" [(p: 0) any [#"(" (++ p) | #")" if (1 <= -- p) then 
none | break] if (p = 0)]
== true

>> parse "())" [(p: 0) any [#"(" (++ p) | #")" if (1 <= -- p) then 
none | break] if (p = 0)]
== false

>> parse ")(" [(p: 0) any [#"(" (++ p) | #")" if (1 <= -- p) then 
none | break] if (p = 0)]
== false
This kind of thing is why I suggested IF (as CHECK) 5 years ago :)
Steeve
30-Sep-2009
[4292x2]
to optimize a little, i would prevent from useless entering in the 
any loop:

[#"(" (p: 1) some  [#"(" (++ p) | #")" if (1 <= -- p) then none | 
break] if (p = 0)]
but now, the  (1 <= -- p) condition is false i mean
BrianH
30-Sep-2009
[4294x2]
[(p: 0) some [#"(" (++ p) | #")" if (1 <= -- p) then none | break] 
if (p = 0)]

Handles the empty string. Given the | break alternate, ANY and SOME 
are equivalent.
Yours would work, but wouldn't recognize an empty string.
Steeve
30-Sep-2009
[4296x2]
still, aren't the condition (1 <= -- p) wrong ?
-- decrements but returns previous value
BrianH
30-Sep-2009
[4298]
You want the condition to be false, so the break is chosen.
Steeve
30-Sep-2009
[4299]
if p = 1 then it must break
BrianH
30-Sep-2009
[4300]
No, you want to break when p is 0 or less.