haydari

所属分类:工具库
开发工具:Crystal
文件大小:0KB
下载次数:0
上传日期:2016-03-11 19:43:57
上 传 者sh-1993
说明:  晶体编程语言的解析器组合子库。,
(Parser combinator library for crystal programming language.,)

文件列表:
.travis.yml (18, 2016-03-11)
LICENSE (1077, 2016-03-11)
samples/ (0, 2016-03-11)
samples/brainfuck.cr (1063, 2016-03-11)
samples/json.cr (1593, 2016-03-11)
samples/tutorial/ (0, 2016-03-11)
samples/tutorial/1-char.cr (207, 2016-03-11)
samples/tutorial/2-many-chars.cr (219, 2016-03-11)
shard.yml (88, 2016-03-11)
spec/ (0, 2016-03-11)
spec/dummy_classes/ (0, 2016-03-11)
spec/dummy_classes/input_parser.cr (1183, 2016-03-11)
spec/haydari/ (0, 2016-03-11)
spec/haydari/parser_input_spec.cr (1033, 2016-03-11)
spec/haydari/parser_spec.cr (803, 2016-03-11)
spec/haydari/parsers/ (0, 2016-03-11)
spec/haydari/parsers/char_spec.cr (957, 2016-03-11)
spec/haydari/parsers/many_spec.cr (562, 2016-03-11)
spec/haydari/parsers/not_spec.cr (331, 2016-03-11)
spec/haydari/parsers/or_spec.cr (848, 2016-03-11)
spec/haydari/parsers/plus_spec.cr (705, 2016-03-11)
spec/haydari/parsers/recurse_spec.cr (946, 2016-03-11)
spec/haydari/parsers/return_spec.cr (512, 2016-03-11)
spec/haydari/parsers/satisfy_char_spec.cr (582, 2016-03-11)
spec/haydari/parsers/satisfy_string_spec.cr (574, 2016-03-11)
spec/haydari/parsers/string_spec.cr (511, 2016-03-11)
spec/haydari/parsers/then_spec.cr (1063, 2016-03-11)
spec/haydari_spec.cr (49, 2016-03-11)
spec/spec_helper.cr (146, 2016-03-11)
src/ (0, 2016-03-11)
src/haydari.cr (2449, 2016-03-11)
src/haydari/ (0, 2016-03-11)
src/haydari/parser.cr (1927, 2016-03-11)
src/haydari/parser_error.cr (187, 2016-03-11)
src/haydari/parser_generator.cr (94, 2016-03-11)
src/haydari/parser_input.cr (1131, 2016-03-11)
src/haydari/parsers/ (0, 2016-03-11)
src/haydari/parsers/char_parser.cr (432, 2016-03-11)
... ...

# haydari (WIP) Parser combinator library for crystal-lang, ## Installation Add this to your application's `shard.yml`: ```yaml dependencies: haydari: github: umurgdk/haydari ``` ## TODO - [ ] Support `IO` as `ParserInput` ## Usage Parser combinators make easy to build complex parsers without dealing with so much hassle. Instead of trying to build one big monolithic parser, making small and composeable parsers and combining them together is way of writing parsers in parser combinators. Haydari gives you smallest parsers like *parse a character*, *parse a whitespace*, etc. and tons of combinators like *many*, *not*, *then* to give them a meaning. ### 1. Creating a parser Let's start writing with simplest parser. Our parser going to read one **space** character and done. ```crystal # samples/tutorial/1-char.cr require "haydari" class MyParser include Haydari defparser space, Char do char(' ') end end my_parser = MyParser.new.space my_parser.run(" ") puts "'#{my_parser.output}'" # prints a space character => ' ' ``` Here `defparser` takes a **name** and a **type** of the value we're going to parse. Since we're using char parser it results in char value. As you can see calling space method is not running the parser, instead it builds a parser instance to run later on. But why we get only **one** space character even we pass a string which has more than one space characters? `char` parser reads a character from it's input and then success or fail. `char` parser don't know anything about how many times it should try to parse or what to do next. But **combinators** does. There are lots of combinators builtin Haydari but most known one is called `many`. `many` takes a parser and tries to run that parser until it fails. Let's parse multiple space characters. ```crystal # samples/tutorial/2-many-chars.cr # notice Array(Char) defparser space, Array(Char) do many char(' ') end ``` Now if we run our parser again output will be `'[' ', ' ', ' ']'`. First thing you should notice our parser's type is changed to `Array(Char)`. This is result of *many* combinator. *many* combinator takes a parser and run that parser until it fails and collect all the results. Because of that its value going to be array of values. You may expect `many char(' ')` to be resulted in `String`, but that's not true. Since *many* combinator could take any kind of parser, the parser you gave may not result into character. ### 2. Parsing comma separated array of strings TBD ### JSON Parser ```crystal require "haydari" class JSONParser include Haydari alias JValue = String | Int32 | Bool | Nil | Array(JValue) | Hash(String, JValue) alias KeyValue = {String, JValue} defparser string_lit, String do string("\"") >> none_of("\"\n").many.text << string("\"") end defparser bool_lit, Bool do string("true").return(true) | string("false").return(false) end defparser contents, JValue do string_lit | array_lit | object_lit | bool_lit | number end defparser comma, String do ws.many >> string(",") << ws.many end defparser array_lit, Array(JValue) do string("[") >> ws.many >> contents.sep(comma) << ws.many << string("]") end defparser key_value, KeyValue do string_lit.then { |key| ws.many >> string(":") >> ws.many >> contents.select { |value| {key, value} } } end defparser object_lit, Hash(String, JValue) do string("{") >> ws.many >> key_value.sep(comma).select { |kvs| hash = Hash(String, JValue).new kvs.each do |kv| hash[kv[0]] = kv[1] end hash } << ws.many << string("}") end def run(input) puts typeof(object_lit) parser = object_lit if parser.run(input) parser.output else raise "Failed!" end end end json_parser = JSONParser.new hash = json_parser.run("{\"hello\" : \"world\", \"arr\":\n [1, 2, 3, true, {\"sub\" : \"gell\"}]}") puts hash.inspect ``` ## Development TODO: Write development instructions here ## Contributing 1. Fork it ( https://github.com/umurgdk/haydari/fork ) 2. Create your feature branch (git checkout -b my-new-feature) 3. Commit your changes (git commit -am 'Add some feature') 4. Push to the branch (git push origin my-new-feature) 5. Create a new Pull Request ## Contributors - umurgdk(https://github.com/umurgdk) Umur Gedik - creator, maintainer

近期下载者

相关文件


收藏者