harby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|