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

World: r3wp

[Parse] Discussion of PARSE dialect

Geocaching
15-Mar-2011
[5540x2]
>> expr: parse-expression "2**3**4"
== [power 2.0 power 3.0 4.0]

It works :)
hehehe... It has been a long time since I had to implement such a 
challenging problem. It is so fun!
Steeve
15-Mar-2011
[5542]
Must have something like yours somewhere, I used the stack approach 
though
Geocaching
15-Mar-2011
[5543]
like the HP48... I would like to see your stack approach. Should 
be interesting.
Steeve
15-Mar-2011
[5544x2]
Lot of sources everywhere.
But I will look for it tomorrow.
I used this way
http://www.programmersheaven.com/2/Art_Expressions_p1
Geocaching
15-Mar-2011
[5546]
Thanks for the link. Seems like I did some kind of tree way...
Ladislav
15-Mar-2011
[5547x2]
>> std [1 ** - 2 / 3] translate
== [divide power 1 negate 2 3]
, i.e. you could as well "consult" the %evaluate.r script
Geocaching
16-Mar-2011
[5549]
A new version (0.9.5) of parse-expression.r is available on rebol.org 
(http://www.rebol.org/view-script.r?script=parse-expression.r). This 
fixes two bugs I found when writing the documentation, which is also 
available on rebol.org
Gregg
16-Mar-2011
[5550]
Francois, don't forget to post update notices to the Announce group 
as well.
Maxim
19-Apr-2011
[5551x2]
in R2 is there a single word which terminates all depths of parse 
rules?  I can't remember
hehe... I've been trying things for 15 minutes and just as I write 
this... I finally get it... hehehe   'END.
BrianH
19-Apr-2011
[5553]
That triggers a backtrack to an alternate if there is one.
Maxim
19-Apr-2011
[5554x3]
yeah... I just did a few tests, and it doesn't work in my case, which 
generates and endless rule   :-(
anything else?
I'm parsing code and I want to stop at any syntax error... right 
now I have no clue what to do!
BrianH
19-Apr-2011
[5557]
END means end-of-input, not end-of-rule. If you really want to break 
out, try putting the parse call in a LOOP 1 and then BREAK in a paren, 
or in a function and RETURN or EXIT.
Maxim
19-Apr-2011
[5558x2]
ah, loop 1 [] ... good idea   


I guess I can also force the end of the string... by using this old 
trick...
[here: (here: tail here) :here] 

though using break in a loop is much easier in my case.
thx for the tip... its odd  that I've never had to solve this case 
before , after all these years of parsing   :-)
BrianH
19-Apr-2011
[5560]
If you want to fail to an alternate, you can assign the block [end 
skip] to a variable that would normally be set to none, and then 
make references to that variable whenever you want to trigger a failure 
condition.
Maxim
19-Apr-2011
[5561]
yeah.. I've already done that one, that's what I usually need... 
but in this case, there is only one success and many failures... 
so its much more work to include the exit rule everywhere.
BrianH
19-Apr-2011
[5562x2]
opt-fail: none

parse "abc" [some [["a" | "b" | (opt-fail: [end skip])] opt-fail]]
If there is only one success and many failures, you can make failure 
the default and set it to something non-failing in the success case. 
If you need to distinguish between failures, set a local variable 
with some distinguishing data. Remember, a predictable failure is 
just an unwanted success.
Maxim
19-Apr-2011
[5564]
yeah but I still need to put opt-fail in all rules so its a burden 
I don't need, in fact its even going to slow down the parsing, so 
i'd rather just use a loop   :-)

loop 1 [    parse "abc"   [some [["a" | "b" |  (err-msg: "failed!" 
break)] ]]    ]
BrianH
19-Apr-2011
[5565x2]
BREAK/return is your friend for distinguishing failures :)
Watch out when porting to R3 though, as PARSE itself is considered 
a loop there for BREAK in parens.
Maxim
19-Apr-2011
[5567x2]
ah yes... forgot about that, even better.
in R3, does ( BREAK ) return the whole parse?
BrianH
19-Apr-2011
[5569]
(BREAK) breaks out of the whole parse, as does RETURN; BREAK breaks 
out of an interation, which all enclosing rules are, so it will break 
out of any block, not just ANY, SOME and WHILE blocks.
onetom
26-Apr-2011
[5570]
what's the best practice for recognizing words with certain syntax? 
(besides using the various word variants)

i was thinking about using the datatype notation or similar pre-/postfix 
characters
Geomol
26-Apr-2011
[5571x3]
Can you give us examples of these words, you want to get recognized 
by parse? Then it may be easier to give opinions.
If you mean things like "word!", then this is a way:

alfa: charset [#"a" - #"z" #"A" - #"Z"]
numeric: charset [#"0" - #"9"]
alfa-numeric: union alfa numeric

parse "word!" [copy word [some alfa any alfa-numeric "!"] (probe 
word)]
Will also parse "word2!, but not "1word!".
onetom
26-Apr-2011
[5574x2]
i was not talking about matching string input. that's obvious
parse [some word! other* stuff']
Geomol
26-Apr-2011
[5576]
I'm not sure, I understand, but maybe you mean something like:


>> parse [a few words of type word! "string" 1] [some word! string! 
integer!]
== true

Else it would be easier with an actual example.
onetom
26-Apr-2011
[5577x3]
this was an actual example.

i can match it with [some word!] but i would like to differentiate 
between the words based on what is their last character
i know it's suboptimal, just wondering if still possible somehow 
to reject a matching rule later somehow
parse [xxx*] [set w word! (unless #"*" = last to-string w [doesnt-match])]
Geomol
26-Apr-2011
[5580x2]
Ah ok, then you need to convert the word to a series, for example 
a string, and check on last letter:


parse [some word! other* stuff'] [some [set word word! (print last 
form word)]]
It's tricky to reject a rule later, and PARSE has changed over time, 
so I'm not sure.
onetom
26-Apr-2011
[5582]
ok, this is how i imagine a solution would look like:
>> parse [normal-word  word-with-star*] [word! starred-word!]
== true
Geomol
26-Apr-2011
[5583]
I would use string parsing in this case.
onetom
26-Apr-2011
[5584]
i would rather use a separate word as a modifier then. makes things 
a lot simpler. maybe i would do a pre-processing 1st to break up 
these words into separate ones
Maxim
26-Apr-2011
[5585]
is this in R2 or R3?
onetom
26-Apr-2011
[5586]
doesn't matter, since im just curious.
Maxim
26-Apr-2011
[5587x3]
in R2,  the best way is to set a word to the value you're evaluating, 
and conditional to that value's pass/fail, you switch the following 
rule to allow it to continue or track back, so it matches another 
rule.


here is a rather verbose example.  note that this can be tweaked 
to be a shorter rule, but it becomes hard to map out how each part 
of the rules relate.. here, each part is clearly layed out.

rebol []


pass-rule: [none]
fail-rule: [thru end]

condition-rule: pass-rule



parse [
	word-a
	"ere"
	835
	word-b
	15
	word
	86
	bullshit
	#doglieru3
	word-c
][
	any [
		
		[
			; this rule only matches words ending with "-?"
			set val word! 
			[
				[
					(
						val: to-string val
						either #"-" = pick (back back tail val) 1  [
							condition-rule: pass-rule
						][
							condition-rule: fail-rule
						]
					)
					condition-rule
					(print ["PATTERN WORD:" val])
				]
				|[
					(print ["Arbitrary word: " val])
				]
			]
		]
		
		| skip
	]
]

ask ""
in R3 there are some new Parse ops which allow to make this almost 
a one-liner
(I just don't have time to build you an example... :-p  )