This is an implementation of Topaz' parse
function for Red.
It includes a compiler that can output Red parse
rules from the topaz-parse
dialect.
$ git clone https://github.com/giesse/red-topaz-parse.git
$ cd red-topaz-parse/
$ red make.red
-
First of all, this version is incomplete and missing lots of stuff like
break
,to
andthru
, and so on. Also only block parsing is currently supported. That's hopefully temporary. -
Rules return a value in addition to matching the input. This can be used with
keep
,set-word!
values,if
andeither
, and so on. It also makesset
unnecessary. Examples:
>> topaz-parse [1 2 3] [integer!]
== 1
>> topaz-parse [1 2 3] [one: integer! two: integer!]
== 2
>> one
== 1
>> two
== 2
>> topaz-parse [1 2 3] [one: integer! if (one > 0) integer!]
== 2
>> topaz-parse [0 2 3] [one: integer! if (one > 0) integer!]
== none
set-word!
values are used to extract data rather than theset
keyword; alsocopy
returns the copy rather than setting a word; note that this solves the problem of automatic locals when usingfunction
>> topaz-parse [foo 1 2 3] ['foo baz: copy some integer!]
== [1 2 3]
>> baz
== [1 2 3]
- To set the current position in the input, because of the above change, the
here
keyword has been added.
>> topaz-parse [1 2 3] [integer! pos: here]
== [2 3]
>> pos
== [2 3]
-
*
is an alias forskip
-
The parsing succeeds if the rules match, even if they don't consume all the input. To achieve the same behavior as
parse
, just addend
to your rules appropriately. -
In addition to
collect
, there is aobject
keyword which will collectset-word!
rules and create amap!
(closer match toobject!
in Topaz) instead of setting the words directly
>> topaz-parse [1 2 3] [object [a: integer! b: * c: quote 3]]
== #(
a: 1
b: 2
c: 3
)
>> a
*** Script Error: a has no value
*** Where: catch
*** Stack:
value: [integer! | word!]
atom: [object [left: value '** op: ('power) right: atom] | value]
item: [object [left: atom ['* op: ('multiply) | '/ op: ('divide)] right: item] | atom]
term: [object [left: item ['+ op: ('add) | '- op: ('subtract)] right: term] | item]
equation: [object [op: ('equal) left: term '= right: term]]
topaz-parse [1 + 3 * x - x ** 2 * 1 / 2 = 2 * y] equation
Results in:
#(
op: equal
left: #(
left: 1
op: add
right: #(
left: #(
left: 3
op: multiply
right: x
)
op: subtract
right: #(
left: #(
left: x
op: power
right: 2
)
op: multiply
right: #(
left: 1
op: divide
right: 2
)
)
)
)
right: #(
left: 2
op: multiply
right: y
)
)