3 ms·
Ask HN: Rebol/Red parse is great. Has it been re-implemented in other languages?
- macmac 9y agoI mean, how can you not love: expr: [term ["+" | "-"] expr | term] term: [factor ["*" | "/"] term | factor] factor: [primary "**" factor | primary] primary: [some digit | "(" expr ")"] digit: charset "0123456789"
- odonnellryan 9y agoWhat is this? A std library function?
- macmac 9y agoQuoting from the red docs: So, in short, what is Parse? It is an embedded DSL (we call them "dialects" in the Rebol world) for parsing input series using grammar rules.
- dominotw 9y agoIts different from antlr and co in the sense that there is no code generation step?
- macmac 9y agoBecause parse is a embedded DSL you have access to all of rebol/red which lets you easily generate/interpret code. As an example here is a BF interpreter: https://gist.github.com/dockimbel/7713170 https://gist.github.com/dockimbel/7713170
- greggirwin 9y agoCorrect. The grammar is interpreted directly.
- dwohnitmok 9y agoInstaparse in Clojure (https://github.com/Engelberg/instaparse https://github.com/Engelberg/instaparse) seems similar (although I don't know Rebol/Red so I'm purely guessing from looking at parse examples). You can get close-ish results with parser combinator libraries as well.
- jacques_chester 9y agoI think you can find these advertised as PEGs, or Parser Expression Grammars. The first I learned about was Lua's LPeg: http://www.inf.puc-rio.br/~roberto/lpeg/ http://www.inf.puc-rio.br/~roberto/lpeg/
- greggirwin 9y agoYou won't find anything quite like it in any other language, and there's a reason for that. Like Lisp, Redbol langs are homoiconic. Rebol was initially designed as a messaging language, and has a lot of datatypes with literal forms that don't exist in other languages. That's important because the `parse` function can operate at 2 levels: `string` parsing (what you find in other parser toolkits), and `block` parsing. Block parsing means the data has been loaded and tokenized already, and you can parse by high level datatype. I'll try not to get too carried away, but that's tough for me. :^) Example 1. Red's infix operator precedence is strictly left to right. But Red has a built in `math` function that can take an expression like `2 + 4 * 3` and produce the result you expect from many other languages. >> 2 + 4 * 3 == 18 >> math [2 + 4 * 3] == 14 You can see how it works by using `source math` in the REPL. It's about 7 lines of `parse` rules. OK, I got carried away. Here's a little dialect I just whipped up as an example (error handling omitted for brevity). It has some supporting funcs at the top, to show how you trigger actions while parsing. If you look at the rules, you can see that some literal words are used as keywords, then different datatypes are matched according to their action. ; Actions call-phone: func [number [issue!] time][ print ["Call" mold number "at" time] ] send-email: func [dest [email!] data [string!]][ print ["Send" dest length? data "bytes"] ] post-data: func [dest [url!] data [string!] time][ print [ "Post" length? data "bytes to" dest either time? time ['at]['on] time ] ] ; Rules when=: [['at | 'on] set when [date! | time!]] call=: ['call set dest issue! opt when= (call-phone dest any [when now])] email=: ['email set dest email! content= (send-email dest content)] post=: ['post content= 'to set dest url! when= (post-data dest content when)] content=: [ set content [string! | file! | url!] (if not string? content [content: attempt [read content]]) ] contact=: [call= | email= | post=] rules=: [any contact=] ; Entry point (dialected function) contactor: func [input [block!]][ parse input rules= ] ; Sample call contactor [ call #000.555.1212 at 12:34 email user@host.dom "On for lunch?" post %news.txt to http://all-the-news.com/news.txt on 1-jan-2018 ] ; Test run output Call #000.555.1212 at 12:34:00 Send user@host.dom 13 bytes Post 1815 bytes to http://all-the-news.com/news.txt on 1-Jan-2018 Other langs can implement something like it, but the fact that Redbol langs were designed to solve this very problem--the exchange of information between people and machines--provides a big advantage.