Skip to content

Instantly share code, notes, and snippets.

@rgchris
Last active February 13, 2018 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgchris/944a5972c56fcc1f7a4aef82434b7e14 to your computer and use it in GitHub Desktop.
Save rgchris/944a5972c56fcc1f7a4aef82434b7e14 to your computer and use it in GitHub Desktop.
Incremental Parser in Ren-C
Rebol [
Title: "Parser"
Author: "Christopher Ross-Gill"
Date: 13-Feb-2018
Home: https://github.com/rgchris/Scripts
File: %parser.reb
Version: 0.1.0
Purpose: {Incremental Parser}
Rights: http://opensource.org/licenses/Apache-2.0
Type: module
Name: rgchris.parser
Exports: [parser]
]
parser: make object! [
index: _
emit: report: state-rules: rule: _
is-paused: is-done: false
state: prior-state: return-state: state-rule: active-rule: _
use: func ['target [word!] /until end-tag [string!] /return][
prior-state: :state
if return [return-state: :state]
state: target
state-rule: active-rule: any [
select state-rules :target
do make error! rejoin ["No Such Parser State: " uppercase spelling-of target]
]
]
return: has [rule][
rule: use :return-state
return-state: _
rule
]
process: [while [index: active-rule]]
new: func [
"Initialize the tokenization process"
source [string!] "Source to tokenize"
states [block! map!] "Parser States"
][
make self [
index: :source
state-rules: :states
state: prior-state: return-state: state-rule: active-rule: _
is-paused: is-done: false
]
]
start: func [
"Start the parser process"
][
case [
not string? index [
fail "Parser not initialized correctly"
]
not state [
fail "No active parser state"
]
]
parse/case index process
]
pause: func [
"Pause the parser process"
][
is-paused: true
active-rule: [fail]
]
resume: func [
"Resume the parser process"
][
case [
not string? index [
fail "Parser not initialized correctly"
]
not state [
fail "No active parser state"
]
]
is-paused: false
active-rule: :state-rule
parse/case index process
]
]
#!/usr/local/bin/ren-c
Rebol [
Title: "Test Parser Module"
Date: 13-Feb-2018
Author: "Christopher Ross-Gill"
Needs: [%parser.reb]
]
states: [
is-a: [
#"a" (print "A in A")
| #"b" (print "B in A" abba-parser/use is-b)
| end (print "End in A") fail
]
is-b: [
mark: #"a" (print "A in B" abba-parser/use is-a) :mark
| #"b" (print "B in B")
| end (print "End in B" abba-parser/use is-a)
]
]
abba-parser: parser/new "aba" states
abba-parser/use is-a
abba-parser/start
print ""
abba-parser: parser/new "bab" states
abba-parser/use is-a
abba-parser/start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment