harby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require "polyglot"
4
+ require "treetop"
5
+
6
+ require "harby/concerns/delegation"
7
+ require "harby/ext/compiled_parser"
8
+ require "harby/ext/syntax_node"
9
+
10
+ require "harby/grammar/command"
11
+ require "harby/grammar/numeric"
12
+ require "harby/grammar/regex"
13
+ require "harby/grammar/string"
14
+ require "harby/grammar/arguments"
15
+
16
+ require "harby/null_delegate"
17
+ require "harby/parser"
@@ -0,0 +1,7 @@
1
+ module Harby
2
+ module Concerns
3
+ module Delegation
4
+ attr_accessor :delegate
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Treetop
2
+ module Runtime
3
+ class CompiledParser
4
+ include Harby::Concerns::Delegation
5
+ alias_method :parse_without_reference, :parse
6
+
7
+ def parse(*args)
8
+ result = parse_without_reference(*args)
9
+ if delegate && result.respond_to?(:delegate=)
10
+ result.delegate = delegate
11
+ end
12
+ result
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Treetop
2
+ module Runtime
3
+ class SyntaxNode
4
+ include Harby::Concerns::Delegation
5
+ alias_method :elements_without_reference, :elements
6
+
7
+ def elements(*args)
8
+ elements = elements_without_reference(*args) || []
9
+ @comprehensive_elements = elements.map do |element|
10
+ element.delegate = delegate
11
+ element
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module Harby
2
+ module Grammar
3
+ grammar Arguments
4
+ include Command
5
+ include Numeric
6
+ include Regex
7
+ include String
8
+
9
+ rule arguments
10
+ first_arg:argument rest_args:(" "+ arg:argument)* {
11
+ def args
12
+ [first_arg] + rest_args
13
+ end
14
+
15
+ def parsed_args
16
+ @parsed_args ||= args.map { |arg| arg.parsed_value }
17
+ end
18
+
19
+ def rest_args
20
+ super.elements.map { |space_and_arg| space_and_arg.arg }
21
+ end
22
+ }
23
+ end
24
+
25
+ rule argument
26
+ command / numeric / regex / string
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ module Harby
2
+ module Grammar
3
+ grammar Command
4
+ rule command
5
+ "[" arguments "]" {
6
+ def args
7
+ arguments.parsed_args
8
+ end
9
+
10
+ def name
11
+ args.first
12
+ end
13
+
14
+ def parsed_args
15
+ args[1..-1]
16
+ end
17
+
18
+ def parsed_value
19
+ if delegate.respond_to?(:on_command)
20
+ delegate.on_command(name, parsed_args)
21
+ else
22
+ ""
23
+ end
24
+ end
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Harby
2
+ module Grammar
3
+ grammar Numeric
4
+ rule numeric
5
+ sign? number {
6
+ def parsed_value
7
+ text_value =~ /\./ ? float_value : integer_value
8
+ end
9
+
10
+ def float_value
11
+ text_value.to_f
12
+ end
13
+
14
+ def integer_value
15
+ text_value.to_i
16
+ end
17
+ }
18
+ end
19
+
20
+ rule sign
21
+ [-+]
22
+ end
23
+
24
+ rule number
25
+ [0-9\.]+ ![^0-9\.\] ]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ module Harby
2
+ module Grammar
3
+ grammar Regex
4
+ rule regex
5
+ "/" pattern:("\\/" / !"/" .)+ "/" modifiers:[iIxXmM]* {
6
+ def parsed_value
7
+ Regexp.new(pattern.text_value, modifiers)
8
+ end
9
+
10
+ def modifiers
11
+ @modifiers ||= super.text_value.downcase.split("").map do |letter|
12
+ case letter
13
+ when "i" then Regexp::IGNORECASE
14
+ when "x" then Regexp::EXTENDED
15
+ when "m" then Regexp::MULTILINE
16
+ else nil; end
17
+ end.compact.uniq.inject(0) do |flags, modifier|
18
+ flags |= modifier
19
+ end
20
+ end
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module Harby
2
+ module Grammar
3
+ grammar String
4
+ rule string
5
+ double_quoted / single_quoted / naked
6
+ end
7
+
8
+ rule double_quoted
9
+ '"' value:('\\"' / command / !'"' .)* '"' {
10
+ def parsed_value
11
+ value.elements.map do |element|
12
+ if element.respond_to?(:parsed_value)
13
+ element.parsed_value
14
+ else
15
+ element.text_value.gsub('\\"', '"')
16
+ end
17
+ end.join("")
18
+ end
19
+ }
20
+ end
21
+
22
+ rule single_quoted
23
+ "'" value:("\\'" / !"'" .)* "'" {
24
+ def parsed_value
25
+ value.text_value.gsub("\\'", "'")
26
+ end
27
+ }
28
+ end
29
+
30
+ rule naked
31
+ ("\\ " / !" " !"]" .)+ {
32
+ def parsed_value
33
+ text_value.gsub("\\ ", " ").gsub("\\/", "/")
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ module Harby
2
+ class NullDelegate
3
+ def handle(*args); end
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module Harby
2
+ class Parser
3
+ attr_reader :parser
4
+
5
+ def initialize(delegate = nil)
6
+ @parser = Grammar::ArgumentsParser.new
7
+ @parser.delegate = delegate || NullDelegate.new
8
+ end
9
+
10
+ def parse(input)
11
+ result = @parser.parse(input)
12
+ result ? result.parsed_args : nil
13
+ end
14
+
15
+ def delegate=(delegate)
16
+ @parser.delegate = delegate
17
+ end
18
+
19
+ def delegate
20
+ @parser.delegate
21
+ end
22
+
23
+ def failure_reason
24
+ @parser.failure_reason
25
+ end
26
+
27
+ def self.parse(input, delegate = nil)
28
+ new(delegate).parse(input)
29
+ end
30
+ end
31
+
32
+ def self.parse(input, delegate = nil)
33
+ Parser.parse(input, delegate)
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: harby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Ross Paffett
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-06 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: treetop
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.4.9
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ description: A grammar-based parser for textual commands. Ideal for IRC bots.
28
+ email:
29
+ - ross@rosspaffett.com
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - lib/harby/concerns/delegation.rb
38
+ - lib/harby/ext/compiled_parser.rb
39
+ - lib/harby/ext/syntax_node.rb
40
+ - lib/harby/null_delegate.rb
41
+ - lib/harby/parser.rb
42
+ - lib/harby.rb
43
+ - lib/harby/grammar/arguments.treetop
44
+ - lib/harby/grammar/command.treetop
45
+ - lib/harby/grammar/numeric.treetop
46
+ - lib/harby/grammar/regex.treetop
47
+ - lib/harby/grammar/string.treetop
48
+ has_rdoc: true
49
+ homepage: http://github.com/raws/harby
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.9.2
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.6.2
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Simple textual command parser
76
+ test_files: []
77
+