Skip to content

Yet another class-base parser combinator (monadic parser) library.

License

Notifications You must be signed in to change notification settings

sawaken/parser_combinator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Nov 19, 2022
cbccc43 · Nov 19, 2022

History

7 Commits
Oct 27, 2015
Nov 19, 2022
Oct 27, 2015
Oct 27, 2015
Oct 27, 2015
Oct 27, 2015
Dec 3, 2015
Oct 27, 2015

Repository files navigation

ParserCombinator

Yet another class-base parser combinator (monadic parser) library.

Installation

Add this line to your application's Gemfile:

gem 'parser_combinator'

And then execute:

$ bundle

Or install it yourself as:

$ gem install parser_combinator

Basics

Item class

Abstraction of Char (in Ruby, it is String of 1-length). Parsing charactors through this abstraction, you can handle meta-info of source-string such as file-name, line-number, column-number.

Items class

Abstraction of String. This is Array of Item.

Usage

Basic Example

require 'parser_combinator/string_parser'

class MyParser < ParserCombinator::StringParser
  parser :noun do
    str("I") | str("you") | str("it")
  end

  parser :verb do
    str("love") | str("hate") | str("live") | str("die")
  end

  parser :token do |p|
    many(str("\s")) > p < many(str("\s"))
  end

  parser :sentence_way1 do
    token(noun) >> proc{|n1|
      token(verb) >> proc{|v|
        token(noun) >> proc{|n2|
          ok("You said, '#{n1} #{v} #{n2}'")
        }}}
  end

  parser :sentence_way2 do
    seq(token(noun), token(verb), token(noun)).map do |x|
      "You said, '#{x[0]} #{x[1]} #{x[2]}'"
    end
  end

  parser :sentence_way3 do
    seq(token(noun).name(:a), token(verb).name(:b), token(noun).name(:c)).map do |x|
      "You said, '#{x[:a]} #{x[:b]} #{x[:c]}'"
    end
  end
end

result = MyParser.sentence_way1.parse_from_string("I love you")
puts result.parsed # => You said, 'I love you.'

result = MyParser.sentence_way2.parse_from_string("I love you")
puts result.parsed # => You said, 'I love you.'

result = MyParser.sentence_way3.parse_from_string("I love you")
puts result.parsed # => You said, 'I love you.'

Error Handling

^ is error handling version of |.

require 'parser_combinator/string_parser'

class MyParser < ParserCombinator::StringParser
  parser :love_sentence do
    str("I") > str("\s") > str("love") > str("you").onfail("Who do you love?")
  end

  parser :hate_sentence do
    str("I") > str("\s") > str("hate") > str("you").onfail("Who do you hate?")
  end

  parser :sentence do
    love_sentence ^ hate_sentence
  end
end

result = MyParser.sentence.parse_from_string("I love")
puts result.status.message # => Who do you love?

result = MyParser.sentence.parse_from_string("I hate")
puts result.status.message # => Who do you hate?

result = MyParser.sentence.parse_from_string("I am laughing")
puts result.status == nil # => true

Recursive parsing and Left recursion

require 'parser_combinator/string_parser'

class MyParser < ParserCombinator::StringParser
  parser :expression do
    add_sub
  end

  parser :add_sub do
    add_op = str("+").map{ proc{|l, r| l + r}}
    sub_op = str("-").map{ proc{|l, r| l - r}}
    binopl(mul_div, add_op | sub_op)
  end

  parser :mul_div do
    mul_op = str("*").map{ proc{|l, r| l * r}}
    div_op = str("/").map{ proc{|l, r| l / r}}
    binopl(integer | parenth, mul_op | div_op)
  end

  parser :integer do
    many1(digit).map{|x| x.map{|i| i.item}.join.to_i}
  end

  parser :parenth do
    str("(") > expression < str(")")
  end
end

result = MyParser.expression.parse_from_string("(1+2)*3+10/2")
puts result.parsed # => 14

result = MyParser.expression.parse_from_string("3-2-1")
puts result.parsed # => 0

Contributing

  1. Fork it ( https://github.com/sawaken/parser_combinator/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

About

Yet another class-base parser combinator (monadic parser) library.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages