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.
- data/lib/harby.rb +17 -0
- data/lib/harby/concerns/delegation.rb +7 -0
- data/lib/harby/ext/compiled_parser.rb +16 -0
- data/lib/harby/ext/syntax_node.rb +16 -0
- data/lib/harby/grammar/arguments.treetop +30 -0
- data/lib/harby/grammar/command.treetop +29 -0
- data/lib/harby/grammar/numeric.treetop +29 -0
- data/lib/harby/grammar/regex.treetop +25 -0
- data/lib/harby/grammar/string.treetop +39 -0
- data/lib/harby/null_delegate.rb +5 -0
- data/lib/harby/parser.rb +35 -0
- metadata +77 -0
data/lib/harby.rb
ADDED
@@ -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,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
|
data/lib/harby/parser.rb
ADDED
@@ -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
|
+
|