Skip to content

Instantly share code, notes, and snippets.

@9214
Last active January 28, 2018 06:47
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 9214/cd41fa91c83511e78e1ad31b04e5c02d to your computer and use it in GitHub Desktop.
Save 9214/cd41fa91c83511e78e1ad31b04e5c02d to your computer and use it in GitHub Desktop.
👽
Red [
Title: "crudely hacked together example DSL"
Link: https://stackoverflow.com/questions/48454538/how-to-parse-and-translate-dsl-using-red-or-rebol
Author: 9214
]
;;; example input
DSL: [
RULE TooYoung
IF [Person.Age < 15]
WRITE MESSAGE TO LOG "too young to earn an income"
SET DATA Person.Income = 0
ELSE
WRITE MESSAGE TO LOG "old enough"
ENDIF
ENDRULE
]
;;; expected output
TooYoung: function [][
either Person.Age < 15 [
WriteMessageToLog "too young to earn an income"
Person.Income: 0
][
WriteMessageToLog "old enough"
]
]
;;; PEG
parser: context [
func-name:
if-expr: true-block: false-block:
word: expr:
none
rule: [
'rule set func-name word!
any statement
'endrule
]
statement: [if* | log | set*] ; * is used to avoid clash with parse keywords
if*: [
'if set if-expr expression
collect set true-block any statement
[
'else collect set false-block any statement
| (false-block: none)
]
thru 'endif
]
log: [
'write 'message 'to 'log set expr expression
keep ('write-to-log)
keep (expr)
]
set*: [
'set 'data set word data '= set expr expression
keep (to set-word! word)
keep (expr)
]
expression: [block! | string! | integer!]
data: ['person.income | 'person.age]
;;; code emitter
emit-rule: does [
compose/deep [
(to set-word! func-name) function [][
either (if-expr) [
(true-block)
][
(false-block)
]
]
]
]
]
;;; release the kraken
probe code: parse DSL bind [
collect any [
rule keep (emit-rule)
| statement ; tbd if necessary
]
] parser
;;; is it working?
reduce first code
write-to-log: :print
person.age: 0 tooyoung
person.age: 1337 tooyoung
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment