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
[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
[4300x2]
No, you want to break when p is 0 or less.
Even in your version.
Steeve
30-Sep-2009
[4302]
wait...
BrianH
30-Sep-2009
[4303x2]
The | break is not only the else for the if (), it is also the alternate 
chosen if #"(" or #")" are not matched.
That is what THEN gives us: the ability to overload alternates.
Steeve
30-Sep-2009
[4305]
oh ok, it's not exiting the loop for such case [()()()()]
BrianH
30-Sep-2009
[4306]
Right :)
Steeve
30-Sep-2009
[4307]
Am ok now
BrianH
30-Sep-2009
[4308]
But we *want* to exit the loop in this case: ")("
Steeve
30-Sep-2009
[4309]
yep
BrianH
30-Sep-2009
[4310]
I find myself liking THEN quite a bit :)
Steeve
30-Sep-2009
[4311x3]
But we still have a problem with break not being able encapable in 
a block.
We can't construct reusable rules with such logic.
i mean we can't push the part [if (1 <= -- p) then none | break] 
in a separated rule
we need a parameter for break
BrianH
30-Sep-2009
[4314]
It's tricky, true. There was either a proposal or a bug report to 
make BREAK break out of the closest enclosing ANY or SOME...
Steeve
30-Sep-2009
[4315x3]
break level
break 0
break -1
BrianH
30-Sep-2009
[4318]
Counted back, not negative.
Steeve
30-Sep-2009
[4319]
if you prefer