walrus 0.2 → 0.3

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.
Files changed (93) hide show
  1. data/bin/walrus +19 -12
  2. data/lib/walrus.rb +27 -70
  3. data/lib/walrus/additions/string.rb +21 -35
  4. data/lib/walrus/compile_error.rb +19 -16
  5. data/lib/walrus/compiler.rb +66 -55
  6. data/lib/walrus/contrib/spec/walruscloth_spec.rb +21 -17
  7. data/lib/walrus/contrib/walruscloth.rb +19 -11
  8. data/lib/walrus/document.rb +41 -33
  9. data/lib/walrus/grammar.rb +474 -162
  10. data/lib/walrus/grammar/assignment_expression.rb +33 -0
  11. data/lib/walrus/grammar/block_directive.rb +37 -0
  12. data/lib/walrus/grammar/comment.rb +33 -0
  13. data/lib/walrus/grammar/def_directive.rb +80 -0
  14. data/lib/walrus/grammar/echo_directive.rb +56 -0
  15. data/lib/walrus/grammar/escape_sequence.rb +33 -0
  16. data/lib/walrus/grammar/import_directive.rb +54 -0
  17. data/lib/walrus/grammar/include_directive.rb +36 -0
  18. data/lib/walrus/grammar/instance_variable.rb +33 -0
  19. data/lib/walrus/grammar/literal.rb +33 -0
  20. data/lib/walrus/grammar/message_expression.rb +34 -0
  21. data/lib/walrus/grammar/multiline_comment.rb +70 -0
  22. data/lib/walrus/grammar/placeholder.rb +47 -0
  23. data/lib/walrus/grammar/raw_directive.rb +50 -0
  24. data/lib/walrus/grammar/raw_text.rb +56 -0
  25. data/lib/walrus/grammar/ruby_directive.rb +41 -0
  26. data/lib/walrus/grammar/ruby_expression.rb +42 -0
  27. data/lib/walrus/grammar/set_directive.rb +34 -0
  28. data/lib/walrus/grammar/silent_directive.rb +51 -0
  29. data/lib/walrus/grammar/slurp_directive.rb +36 -0
  30. data/lib/walrus/grammar/super_directive.rb +34 -0
  31. data/lib/walrus/parser.rb +26 -408
  32. data/lib/walrus/runner.rb +37 -20
  33. data/lib/walrus/template.rb +34 -25
  34. data/lib/walrus/version.rb +24 -1
  35. metadata +57 -71
  36. data/ext/extconf.rb +0 -16
  37. data/ext/jindex.c +0 -92
  38. data/lib/walrus/diff.rb +0 -95
  39. data/lib/walrus/grammar/additions/proc.rb +0 -26
  40. data/lib/walrus/grammar/additions/regexp.rb +0 -27
  41. data/lib/walrus/grammar/additions/string.rb +0 -58
  42. data/lib/walrus/grammar/additions/symbol.rb +0 -49
  43. data/lib/walrus/grammar/and_predicate.rb +0 -46
  44. data/lib/walrus/grammar/array_result.rb +0 -25
  45. data/lib/walrus/grammar/continuation_wrapper_exception.rb +0 -34
  46. data/lib/walrus/grammar/left_recursion_exception.rb +0 -33
  47. data/lib/walrus/grammar/location_tracking.rb +0 -115
  48. data/lib/walrus/grammar/match_data_wrapper.rb +0 -71
  49. data/lib/walrus/grammar/memoizing.rb +0 -47
  50. data/lib/walrus/grammar/memoizing_cache.rb +0 -103
  51. data/lib/walrus/grammar/node.rb +0 -66
  52. data/lib/walrus/grammar/not_predicate.rb +0 -46
  53. data/lib/walrus/grammar/parse_error.rb +0 -45
  54. data/lib/walrus/grammar/parser_state.rb +0 -187
  55. data/lib/walrus/grammar/parslet.rb +0 -34
  56. data/lib/walrus/grammar/parslet_choice.rb +0 -128
  57. data/lib/walrus/grammar/parslet_combination.rb +0 -32
  58. data/lib/walrus/grammar/parslet_combining.rb +0 -160
  59. data/lib/walrus/grammar/parslet_merge.rb +0 -94
  60. data/lib/walrus/grammar/parslet_omission.rb +0 -63
  61. data/lib/walrus/grammar/parslet_repetition.rb +0 -106
  62. data/lib/walrus/grammar/parslet_repetition_default.rb +0 -64
  63. data/lib/walrus/grammar/parslet_sequence.rb +0 -214
  64. data/lib/walrus/grammar/predicate.rb +0 -63
  65. data/lib/walrus/grammar/proc_parslet.rb +0 -58
  66. data/lib/walrus/grammar/regexp_parslet.rb +0 -79
  67. data/lib/walrus/grammar/skipped_substring_exception.rb +0 -42
  68. data/lib/walrus/grammar/string_enumerator.rb +0 -53
  69. data/lib/walrus/grammar/string_parslet.rb +0 -81
  70. data/lib/walrus/grammar/string_result.rb +0 -30
  71. data/lib/walrus/grammar/symbol_parslet.rb +0 -69
  72. data/lib/walrus/no_parameter_marker.rb +0 -25
  73. data/lib/walrus/walrus_grammar/assignment_expression.rb +0 -30
  74. data/lib/walrus/walrus_grammar/block_directive.rb +0 -34
  75. data/lib/walrus/walrus_grammar/comment.rb +0 -30
  76. data/lib/walrus/walrus_grammar/def_directive.rb +0 -72
  77. data/lib/walrus/walrus_grammar/echo_directive.rb +0 -50
  78. data/lib/walrus/walrus_grammar/escape_sequence.rb +0 -30
  79. data/lib/walrus/walrus_grammar/import_directive.rb +0 -50
  80. data/lib/walrus/walrus_grammar/include_directive.rb +0 -33
  81. data/lib/walrus/walrus_grammar/instance_variable.rb +0 -30
  82. data/lib/walrus/walrus_grammar/literal.rb +0 -30
  83. data/lib/walrus/walrus_grammar/message_expression.rb +0 -31
  84. data/lib/walrus/walrus_grammar/multiline_comment.rb +0 -60
  85. data/lib/walrus/walrus_grammar/placeholder.rb +0 -46
  86. data/lib/walrus/walrus_grammar/raw_directive.rb +0 -48
  87. data/lib/walrus/walrus_grammar/raw_text.rb +0 -51
  88. data/lib/walrus/walrus_grammar/ruby_directive.rb +0 -35
  89. data/lib/walrus/walrus_grammar/ruby_expression.rb +0 -37
  90. data/lib/walrus/walrus_grammar/set_directive.rb +0 -30
  91. data/lib/walrus/walrus_grammar/silent_directive.rb +0 -50
  92. data/lib/walrus/walrus_grammar/slurp_directive.rb +0 -31
  93. data/lib/walrus/walrus_grammar/super_directive.rb +0 -33
@@ -1,63 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- # Predicates parse input without consuming it.
21
- # On success they throw a subclass-specific symbol (see the AndPredicate and NotPredicate classes).
22
- # On failure they raise a ParseError.
23
- class Predicate
24
-
25
- include Walrus::Grammar::ParsletCombining
26
- include Walrus::Grammar::Memoizing
27
-
28
- attr_reader :hash
29
-
30
- # Raises if parseable is nil.
31
- def initialize(parseable)
32
- raise ArgumentError if parseable.nil?
33
- @parseable = parseable
34
- @hash = @parseable.hash + hash_offset # fixed offset to avoid collisions with @parseable objects
35
- end
36
-
37
- def to_parseable
38
- self
39
- end
40
-
41
- def parse(string, options = {})
42
- raise NotImplementedError # subclass responsibility
43
- end
44
-
45
- def eql?(other)
46
- other.instance_of? self.class and other.parseable.eql? @parseable
47
- end
48
-
49
- protected
50
-
51
- # for equality comparisons
52
- attr_reader :parseable
53
-
54
- private
55
-
56
- def hash_offset
57
- 10
58
- end
59
-
60
- end
61
-
62
- end # class Grammar
63
- end # module Walrus
@@ -1,58 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- class ProcParslet < Parslet
21
-
22
- attr_reader :hash
23
-
24
- def initialize(proc)
25
- raise ArgumentError if proc.nil?
26
- self.expected_proc = proc
27
- end
28
-
29
- def parse(string, options = {})
30
- raise ArgumentError if string.nil?
31
- @expected_proc.call string, options
32
- end
33
-
34
- def eql?(other)
35
- other.instance_of? ProcParslet and other.expected_proc == @expected_proc
36
- end
37
-
38
- protected
39
-
40
- # For equality comparisons.
41
- attr_reader :expected_proc
42
-
43
- private
44
-
45
- def expected_proc=(proc)
46
- @expected_proc = ( proc.clone rescue proc )
47
- update_hash
48
- end
49
-
50
- def update_hash
51
- @hash = @expected_proc.hash + 105 # fixed offset to avoid collisions with @parseable objects
52
- end
53
-
54
- end # class ProcParslet
55
-
56
- end # class Grammar
57
- end # module Walrus
58
-
@@ -1,79 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- class RegexpParslet < Parslet
21
-
22
- attr_reader :hash
23
-
24
- def initialize(regexp)
25
- raise ArgumentError if regexp.nil?
26
- self.expected_regexp = /\A#{regexp}/ # for efficiency, anchor all regexps to the start of the string
27
- end
28
-
29
- def parse(string, options = {})
30
- raise ArgumentError if string.nil?
31
- if (string =~ @expected_regexp)
32
- wrapper = MatchDataWrapper.new($~)
33
- match = $~[0]
34
-
35
- if (line_count = match.scan(/\r\n|\r|\n/).length) != 0 # count number of newlines in match
36
- column_end = match.jlength - match.jrindex(/\r|\n/) - 1 # calculate characters on last line
37
- else # no newlines in match
38
- column_end = match.jlength + (options[:column_start] || 0)
39
- end
40
-
41
- wrapper.start = [options[:line_start], options[:column_start]]
42
- wrapper.end = [wrapper.line_start + line_count, column_end]
43
- wrapper.source_text = match.to_s.clone
44
- wrapper
45
- else
46
- raise ParseError.new('non-matching characters "%s" while parsing regular expression "%s"' % [string, @expected_regexp.inspect],
47
- :line_end => (options[:line_start] || 0), :column_end => (options[:column_start] || 0))
48
- end
49
- end
50
-
51
- def eql?(other)
52
- other.instance_of? RegexpParslet and other.expected_regexp == @expected_regexp
53
- end
54
-
55
- def inspect
56
- '#<%s:0x%x @expected_regexp=%s>' % [self.class.to_s, self.object_id, @expected_regexp.inspect]
57
- end
58
-
59
- protected
60
-
61
- # For equality comparisons.
62
- attr_reader :expected_regexp
63
-
64
- private
65
-
66
- def expected_regexp=(regexp)
67
- @expected_regexp = ( regexp.clone rescue regexp )
68
- update_hash
69
- end
70
-
71
- def update_hash
72
- @hash = @expected_regexp.hash + 15 # fixed offset to avoid collisions with @parseable objects
73
- end
74
-
75
- end # class RegexpParslet
76
-
77
- end # class Grammar
78
- end # module Walrus
79
-
@@ -1,42 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- # I don't really like using Exceptions for non-error situations, but it seems that using throw/catch here would not be adequate (not possible to embed information in the thrown symbol).
21
- class SkippedSubstringException < Exception
22
-
23
- include Walrus::Grammar::LocationTracking
24
-
25
- def initialize(substring, info = {})
26
- super substring
27
-
28
- # TODO: this code is just like the code in ParseError. could save repeating it by setting up inheritance
29
- # but would need to pay careful attention to the ordering of my rescue blocks
30
- # and also change many instances of "kind_of" in my specs to "instance_of "
31
- # alternatively, could look at using a mix-in
32
- self.line_start = info[:line_start]
33
- self.column_start = info[:column_start]
34
- self.line_end = info[:line_end]
35
- self.column_end = info[:column_end]
36
- end
37
-
38
- end # class SkippedSubstringException
39
-
40
- end # class Grammar
41
- end # module Walrus
42
-
@@ -1,53 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'strscan'
16
- require 'walrus'
17
-
18
- module Walrus
19
- class Grammar
20
-
21
- # Unicode-aware (UTF-8) string enumerator.
22
- # For Unicode support $KCODE must be set to 'U' (UTF-8).
23
- class StringEnumerator
24
-
25
- # Returns the char most recently scanned before the last "next" call, or nil if nothing previously scanned.
26
- attr_reader :last
27
-
28
- def initialize(string)
29
- raise ArgumentError if string.nil?
30
- @scanner = StringScanner.new(string)
31
- @current = nil
32
- @last = nil
33
- end
34
-
35
- # This method will only work as expected if $KCODE is set to 'U' (UTF-8).
36
- def next
37
- @last = @current
38
- @current = @scanner.scan(/./m) # must use multiline mode or "." won't match newlines
39
- end
40
-
41
- # Take a peek at the next character without actually consuming it. Returns nil if there is no next character.
42
- # TODO: consider deleting this method as it's not currently used.
43
- def peek
44
- if char = self.next
45
- @scanner.unscan
46
- end
47
- char
48
- end
49
-
50
- end # class StringEnumerator
51
-
52
- end # class Grammar
53
- end # module Walrus
@@ -1,81 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- class StringParslet < Parslet
21
-
22
- attr_reader :hash
23
-
24
- def initialize(string)
25
- raise ArgumentError if string.nil?
26
- self.expected_string = string
27
- end
28
-
29
- def parse(string, options = {})
30
- raise ArgumentError if string.nil?
31
- chars = StringEnumerator.new(string)
32
- parsed = StringResult.new
33
- parsed.start = [options[:line_start], options[:column_start]]
34
- parsed.end = parsed.start
35
- expected_string.each_char do |expected_char|
36
- actual_char = chars.next
37
- if actual_char.nil?
38
- raise ParseError.new('unexpected end-of-string (expected "%s") while parsing "%s"' % [ expected_char, expected_string ],
39
- :line_end => parsed.line_end, :column_end => parsed.column_end)
40
- elsif actual_char != expected_char
41
- raise ParseError.new('unexpected character "%s" (expected "%s") while parsing "%s"' % [ actual_char, expected_char, expected_string],
42
- :line_end => parsed.line_end, :column_end => parsed.column_end)
43
- else
44
- if actual_char == "\r" or (actual_char == "\n" and chars.last != "\r") # catches Mac, Windows and UNIX end-of-line markers
45
- parsed.column_end = 0
46
- parsed.line_end = parsed.line_end + 1
47
- elsif actual_char != "\n" # \n is ignored if it is preceded by an \r (already counted above)
48
- parsed.column_end = parsed.column_end + 1 # everything else gets counted
49
- end
50
- parsed << actual_char
51
- end
52
- end
53
- parsed.source_text = parsed.to_s.clone
54
- parsed
55
- end
56
-
57
- def eql?(other)
58
- other.instance_of? StringParslet and other.expected_string == @expected_string
59
- end
60
-
61
- protected
62
-
63
- # For equality comparisons.
64
- attr_reader :expected_string
65
-
66
- private
67
-
68
- def expected_string=(string)
69
- @expected_string = ( string.clone rescue string )
70
- update_hash
71
- end
72
-
73
- def update_hash
74
- @hash = @expected_string.hash + 20 # fixed offset to avoid collisions with @parseable objects
75
- end
76
-
77
- end # class StringParslet
78
-
79
- end # class Grammar
80
- end # module Walrus
81
-
@@ -1,30 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
- class StringResult < String
20
-
21
- include Walrus::Grammar::LocationTracking
22
-
23
- def initialize(string = "")
24
- self.source_text = string
25
- super
26
- end
27
-
28
- end # class StringResult
29
- end # class Grammar
30
- end # module Walrus
@@ -1,69 +0,0 @@
1
- # Copyright 2007 Wincent Colaiuta
2
- # This program is free software: you can redistribute it and/or modify
3
- # it under the terms of the GNU General Public License as published by
4
- # the Free Software Foundation, either version 3 of the License, or
5
- # (at your option) any later version.
6
- #
7
- # This program is distributed in the hope that it will be useful,
8
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- # GNU General Public License for more details.
11
- #
12
- # You should have received a copy of the GNU General Public License
13
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
-
15
- require 'walrus'
16
-
17
- module Walrus
18
- class Grammar
19
-
20
- # A SymbolParslet allows for evaluation of a parslet to be deferred until runtime (or parse time, to be more precise).
21
- class SymbolParslet < Parslet
22
-
23
- attr_reader :hash
24
-
25
- def initialize(symbol)
26
- raise ArgumentError if symbol.nil?
27
- @symbol = symbol
28
- @hash = @symbol.hash + 20 # fixed offset to avoid collisions with @parseable objects
29
- end
30
-
31
- # SymbolParslets don't actually know what Grammar they are associated with at the time of their definition. They expect the Grammar to be passed in with the options hash under the ":grammar" key.
32
- # Raises if string is nil, or if the options hash does not include a :grammar key.
33
- def parse(string, options = {})
34
- raise ArgumentError if string.nil?
35
- raise ArgumentError unless options.has_key?(:grammar)
36
- grammar = options[:grammar]
37
- augmented_options = options.clone
38
- augmented_options[:rule_name] = @symbol
39
- augmented_options[:skipping_override] = grammar.skipping_overrides[@symbol] if grammar.skipping_overrides.has_key?(@symbol)
40
- result = grammar.rules[@symbol].memoizing_parse(string, augmented_options)
41
- grammar.wrap(result, @symbol)
42
- end
43
-
44
- # We override the to_s method as it can make parsing error messages more readable. Instead of messages like this:
45
- # predicate not satisfied (expected "#<Walrus::Grammar::SymbolParslet:0x10cd504>") while parsing "hello world"
46
- # We can print messages like this:
47
- # predicate not satisfied (expected "rule: end_of_input") while parsing "hello world"
48
- def to_s
49
- 'rule: ' + @symbol.to_s
50
- end
51
-
52
- def ==(other)
53
- eql?(other)
54
- end
55
-
56
- def eql?(other)
57
- other.instance_of? SymbolParslet and other.symbol == @symbol
58
- end
59
-
60
- protected
61
-
62
- # For equality comparisons.
63
- attr_reader :symbol
64
-
65
- end # class SymbolParslet
66
-
67
- end # class Grammar
68
- end # module Walrus
69
-