parsanol 1.3.13-arm-linux

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 (100) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.txt +98 -0
  3. data/LICENSE +23 -0
  4. data/README.adoc +905 -0
  5. data/Rakefile +141 -0
  6. data/lib/parsanol/3.2/parsanol_native.so +0 -0
  7. data/lib/parsanol/3.3/parsanol_native.so +0 -0
  8. data/lib/parsanol/3.4/parsanol_native.so +0 -0
  9. data/lib/parsanol/4.0/parsanol_native.so +0 -0
  10. data/lib/parsanol/ast_visitor.rb +122 -0
  11. data/lib/parsanol/atoms/alternative.rb +123 -0
  12. data/lib/parsanol/atoms/base.rb +208 -0
  13. data/lib/parsanol/atoms/can_flatten.rb +194 -0
  14. data/lib/parsanol/atoms/capture.rb +38 -0
  15. data/lib/parsanol/atoms/context.rb +357 -0
  16. data/lib/parsanol/atoms/context_optimized.rb +38 -0
  17. data/lib/parsanol/atoms/custom.rb +110 -0
  18. data/lib/parsanol/atoms/cut.rb +66 -0
  19. data/lib/parsanol/atoms/dsl.rb +96 -0
  20. data/lib/parsanol/atoms/dynamic.rb +39 -0
  21. data/lib/parsanol/atoms/entity.rb +75 -0
  22. data/lib/parsanol/atoms/ignored.rb +37 -0
  23. data/lib/parsanol/atoms/infix.rb +167 -0
  24. data/lib/parsanol/atoms/lookahead.rb +85 -0
  25. data/lib/parsanol/atoms/named.rb +74 -0
  26. data/lib/parsanol/atoms/re.rb +83 -0
  27. data/lib/parsanol/atoms/repetition.rb +277 -0
  28. data/lib/parsanol/atoms/scope.rb +35 -0
  29. data/lib/parsanol/atoms/sequence.rb +195 -0
  30. data/lib/parsanol/atoms/str.rb +109 -0
  31. data/lib/parsanol/atoms/visitor.rb +91 -0
  32. data/lib/parsanol/atoms.rb +46 -0
  33. data/lib/parsanol/buffer.rb +133 -0
  34. data/lib/parsanol/builder_callbacks.rb +353 -0
  35. data/lib/parsanol/cause.rb +122 -0
  36. data/lib/parsanol/context.rb +39 -0
  37. data/lib/parsanol/convenience.rb +36 -0
  38. data/lib/parsanol/edit_tracker.rb +111 -0
  39. data/lib/parsanol/error_reporter/contextual.rb +99 -0
  40. data/lib/parsanol/error_reporter/deepest.rb +120 -0
  41. data/lib/parsanol/error_reporter/tree.rb +63 -0
  42. data/lib/parsanol/error_reporter.rb +100 -0
  43. data/lib/parsanol/expression/treetop.rb +154 -0
  44. data/lib/parsanol/expression.rb +106 -0
  45. data/lib/parsanol/fast_mode.rb +187 -0
  46. data/lib/parsanol/first_set.rb +79 -0
  47. data/lib/parsanol/grammar_builder.rb +179 -0
  48. data/lib/parsanol/incremental_parser.rb +182 -0
  49. data/lib/parsanol/interval_tree.rb +226 -0
  50. data/lib/parsanol/lazy_result.rb +179 -0
  51. data/lib/parsanol/mermaid.rb +142 -0
  52. data/lib/parsanol/native/batch_decoder.rb +255 -0
  53. data/lib/parsanol/native/dynamic.rb +238 -0
  54. data/lib/parsanol/native/parser.rb +102 -0
  55. data/lib/parsanol/native/serializer.rb +252 -0
  56. data/lib/parsanol/native/transformer.rb +604 -0
  57. data/lib/parsanol/native/types.rb +29 -0
  58. data/lib/parsanol/native.rb +223 -0
  59. data/lib/parsanol/optimizer.rb +85 -0
  60. data/lib/parsanol/optimizers/choice_optimizer.rb +78 -0
  61. data/lib/parsanol/optimizers/cut_inserter.rb +182 -0
  62. data/lib/parsanol/optimizers/lookahead_optimizer.rb +56 -0
  63. data/lib/parsanol/optimizers/quantifier_optimizer.rb +60 -0
  64. data/lib/parsanol/optimizers/sequence_optimizer.rb +97 -0
  65. data/lib/parsanol/options/zero_copy.rb +127 -0
  66. data/lib/parsanol/options.rb +21 -0
  67. data/lib/parsanol/parallel.rb +128 -0
  68. data/lib/parsanol/parser.rb +242 -0
  69. data/lib/parsanol/parslet.rb +151 -0
  70. data/lib/parsanol/pattern/binding.rb +91 -0
  71. data/lib/parsanol/pattern.rb +162 -0
  72. data/lib/parsanol/pool.rb +219 -0
  73. data/lib/parsanol/pools/array_pool.rb +75 -0
  74. data/lib/parsanol/pools/buffer_pool.rb +182 -0
  75. data/lib/parsanol/pools/position_pool.rb +92 -0
  76. data/lib/parsanol/pools/slice_pool.rb +64 -0
  77. data/lib/parsanol/position.rb +94 -0
  78. data/lib/parsanol/resettable.rb +29 -0
  79. data/lib/parsanol/result.rb +46 -0
  80. data/lib/parsanol/result_builder.rb +208 -0
  81. data/lib/parsanol/result_stream.rb +266 -0
  82. data/lib/parsanol/rig/rspec.rb +71 -0
  83. data/lib/parsanol/rope.rb +81 -0
  84. data/lib/parsanol/scope.rb +104 -0
  85. data/lib/parsanol/slice.rb +160 -0
  86. data/lib/parsanol/source/line_cache.rb +102 -0
  87. data/lib/parsanol/source.rb +185 -0
  88. data/lib/parsanol/source_location.rb +167 -0
  89. data/lib/parsanol/streaming_parser.rb +124 -0
  90. data/lib/parsanol/string_view.rb +198 -0
  91. data/lib/parsanol/transform.rb +226 -0
  92. data/lib/parsanol/version.rb +5 -0
  93. data/lib/parsanol/wasm/README.md +80 -0
  94. data/lib/parsanol/wasm/package.json +51 -0
  95. data/lib/parsanol/wasm/parsanol.js +252 -0
  96. data/lib/parsanol/wasm/parslet.d.ts +129 -0
  97. data/lib/parsanol/wasm_parser.rb +240 -0
  98. data/lib/parsanol.rb +278 -0
  99. data/parsanol.gemspec +67 -0
  100. metadata +279 -0
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Literal string matcher. Matches an exact sequence of characters.
4
+ #
5
+ # @example Match literal text
6
+ # str('hello') # matches exactly 'hello'
7
+ #
8
+ module Parsanol
9
+ module Atoms
10
+ class Str < Parsanol::Atoms::Base
11
+ # @return [String] the literal to match
12
+ attr_reader :str
13
+
14
+ # Creates a new string matcher.
15
+ #
16
+ # @param text [String, Object] the literal string to match
17
+ def initialize(text)
18
+ super()
19
+ @str = text.to_s
20
+ @byte_size = @str.bytesize
21
+ @char_count = @str.length
22
+
23
+ # Pre-built error messages (frozen)
24
+ @early_eof_msg = "Unexpected end of input"
25
+ @mismatch_msg = "Expected #{@str.inspect}, but got "
26
+
27
+ # Optimization: single-char fast path
28
+ @single_char = (@str if @char_count == 1)
29
+ end
30
+
31
+ # Attempts to match the literal at current position.
32
+ #
33
+ # @param source [Parsanol::Source] input
34
+ # @param context [Parsanol::Atoms::Context] context
35
+ # @param _consume_all [Boolean] ignored
36
+ # @return [Array(Boolean, Object)] result
37
+ def try(source, context, _consume_all)
38
+ # Single-character optimization
39
+ return single_char_match(source, context) if @single_char
40
+
41
+ # Multi-character matching
42
+ multi_char_match(source, context)
43
+ end
44
+
45
+ # String representation.
46
+ #
47
+ # @param _prec [Integer] unused
48
+ # @return [String]
49
+ def to_s_inner(_prec)
50
+ "'#{@str}'"
51
+ end
52
+
53
+ # Simple atoms don't benefit from caching.
54
+ #
55
+ # @return [Boolean]
56
+ def cached?
57
+ false
58
+ end
59
+
60
+ # Produces flat results (Slice).
61
+ #
62
+ # @return [Boolean]
63
+ def flat?
64
+ true
65
+ end
66
+
67
+ # FIRST set is this atom itself.
68
+ #
69
+ # @return [Set]
70
+ def compute_first_set
71
+ Set.new([self])
72
+ end
73
+
74
+ private
75
+
76
+ # Fast path for single-character strings.
77
+ def single_char_match(source, context)
78
+ if source.chars_left < 1
79
+ return context.err(self, source,
80
+ @early_eof_msg)
81
+ end
82
+
83
+ pos = source.pos
84
+ slice = source.consume(1)
85
+
86
+ return ok(slice) if slice.content == @single_char
87
+
88
+ source.bytepos = pos
89
+ context.err_at(self, source, [@mismatch_msg, slice], pos)
90
+ end
91
+
92
+ # Standard path for multi-character strings.
93
+ def multi_char_match(source, context)
94
+ if source.chars_left < @char_count
95
+ return context.err(self, source,
96
+ @early_eof_msg)
97
+ end
98
+
99
+ pos = source.pos
100
+ slice = source.consume(@char_count)
101
+
102
+ return ok(slice) if slice.content == @str
103
+
104
+ source.bytepos = pos
105
+ context.err_at(self, source, [@mismatch_msg, slice], pos)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Visitor pattern for traversing parser atom trees.
4
+ # Each atom type dispatches to a corresponding visitor method.
5
+ module Parsanol
6
+ module Atoms
7
+ class Base
8
+ # Accepts visitor and dispatches to type-specific method.
9
+ # Override in subclasses.
10
+ #
11
+ # @param visitor [Object] implements visit_* methods
12
+ # @raise [NotImplementedError] if not overridden
13
+ def accept(visitor)
14
+ raise NotImplementedError,
15
+ "Missing #accept in #{self.class.name}"
16
+ end
17
+ end
18
+
19
+ class Str
20
+ # Dispatches to visitor's visit_str.
21
+ #
22
+ # @param visitor [Object] visitor object
23
+ def accept(visitor)
24
+ visitor.visit_str(str)
25
+ end
26
+ end
27
+
28
+ class Entity
29
+ # Dispatches to visitor's visit_entity.
30
+ #
31
+ # @param visitor [Object] visitor object
32
+ def accept(visitor)
33
+ visitor.visit_entity(rule_name, @body)
34
+ end
35
+ end
36
+
37
+ class Named
38
+ # Dispatches to visitor's visit_named.
39
+ #
40
+ # @param visitor [Object] visitor object
41
+ def accept(visitor)
42
+ visitor.visit_named(name, parslet)
43
+ end
44
+ end
45
+
46
+ class Sequence
47
+ # Dispatches to visitor's visit_sequence.
48
+ #
49
+ # @param visitor [Object] visitor object
50
+ def accept(visitor)
51
+ visitor.visit_sequence(parslets)
52
+ end
53
+ end
54
+
55
+ class Repetition
56
+ # Dispatches to visitor's visit_repetition.
57
+ #
58
+ # @param visitor [Object] visitor object
59
+ def accept(visitor)
60
+ visitor.visit_repetition(result_tag, min, max, parslet)
61
+ end
62
+ end
63
+
64
+ class Alternative
65
+ # Dispatches to visitor's visit_alternative.
66
+ #
67
+ # @param visitor [Object] visitor object
68
+ def accept(visitor)
69
+ visitor.visit_alternative(alternatives)
70
+ end
71
+ end
72
+
73
+ class Lookahead
74
+ # Dispatches to visitor's visit_lookahead.
75
+ #
76
+ # @param visitor [Object] visitor object
77
+ def accept(visitor)
78
+ visitor.visit_lookahead(positive, bound_parslet)
79
+ end
80
+ end
81
+
82
+ class Re
83
+ # Dispatches to visitor's visit_re.
84
+ #
85
+ # @param visitor [Object] visitor object
86
+ def accept(visitor)
87
+ visitor.visit_re(match)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Parser atoms - the building blocks for grammars.
4
+ # Each atom type handles a specific parsing primitive or combinator.
5
+ module Parsanol
6
+ module Atoms
7
+ # Precedence levels for pretty-printing.
8
+ # Higher values bind more loosely.
9
+ module Precedence
10
+ ATOM = 1 # literals, entities
11
+ LOOKAHEAD = 2 # &expr, !expr
12
+ REPETITION = 3 # expr*, expr+, expr?
13
+ SEQUENCE = 4 # expr expr
14
+ CHOICE = 5 # expr | expr
15
+ TOP = 6 # outer level
16
+
17
+ # Backward-compatible aliases
18
+ BASE = ATOM
19
+ ALTERNATE = CHOICE
20
+ OUTER = TOP
21
+ end
22
+
23
+ # Load atom implementations
24
+ require "parsanol/atoms/can_flatten"
25
+ require "parsanol/atoms/context"
26
+ require "parsanol/atoms/dsl"
27
+ require "parsanol/atoms/base"
28
+ require "parsanol/atoms/custom"
29
+ require "parsanol/atoms/ignored"
30
+ require "parsanol/atoms/named"
31
+ require "parsanol/atoms/lookahead"
32
+ require "parsanol/atoms/cut"
33
+ require "parsanol/atoms/alternative"
34
+ require "parsanol/atoms/sequence"
35
+ require "parsanol/atoms/repetition"
36
+ require "parsanol/atoms/re"
37
+ require "parsanol/atoms/str"
38
+ require "parsanol/atoms/entity"
39
+ require "parsanol/atoms/capture"
40
+ require "parsanol/atoms/dynamic"
41
+ require "parsanol/atoms/scope"
42
+ require "parsanol/atoms/infix"
43
+ # Load visitor pattern (must be after all atom classes)
44
+ require "parsanol/atoms/visitor"
45
+ end
46
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ # A fixed-size buffer for efficient array operations.
5
+ #
6
+ # Buffer wraps an array with a logical size separate from capacity.
7
+ # This allows reusing buffers without reallocating arrays, reducing GC pressure.
8
+ #
9
+ # == Usage
10
+ #
11
+ # buffer = Buffer.new(capacity: 10)
12
+ # buffer.push("a")
13
+ # buffer.push("b")
14
+ # buffer.size # => 2
15
+ # buffer.to_a # => ["a", "b"]
16
+ # buffer.clear!
17
+ # buffer.size # => 0 (but capacity still 10)
18
+ #
19
+ # == Size vs Capacity
20
+ #
21
+ # - Size: Number of elements logically in the buffer
22
+ # - Capacity: Maximum elements before reallocation
23
+ #
24
+ # Reusing buffers maintains capacity while resetting size.
25
+ #
26
+ class Buffer
27
+ include Resettable
28
+
29
+ # @return [Integer] Logical size (number of elements)
30
+ attr_reader :size
31
+
32
+ # @return [Integer] Maximum capacity before growth
33
+ attr_reader :capacity
34
+
35
+ # @return [Array] Underlying array storage
36
+ attr_reader :storage
37
+
38
+ # Initialize a new buffer with specified capacity.
39
+ #
40
+ # @param capacity [Integer] Initial capacity (default: 10)
41
+ #
42
+ def initialize(capacity: 10)
43
+ @capacity = capacity
44
+ @storage = Array.new(capacity)
45
+ @size = 0
46
+ end
47
+
48
+ # Add an element to the buffer.
49
+ #
50
+ # Grows buffer if needed, but this should be rare with proper size classes.
51
+ #
52
+ # @param element [Object] Element to add
53
+ # @return [self] For method chaining
54
+ #
55
+ def push(element)
56
+ grow! if @size >= @capacity
57
+ @storage[@size] = element
58
+ @size += 1
59
+ self
60
+ end
61
+
62
+ alias << push
63
+
64
+ # Get element at index.
65
+ #
66
+ # @param index [Integer] Zero-based index
67
+ # @return [Object] Element at index, or nil if out of bounds
68
+ #
69
+ def [](index)
70
+ return nil if index >= @size
71
+
72
+ @storage[index]
73
+ end
74
+
75
+ # Set element at index.
76
+ #
77
+ # @param index [Integer] Zero-based index
78
+ # @param value [Object] Value to set
79
+ #
80
+ def []=(index, value)
81
+ @storage[index] = value if index < @size
82
+ end
83
+
84
+ # Convert buffer to array (creates new array slice of logical size).
85
+ #
86
+ # @return [Array] Array containing elements [0...size]
87
+ #
88
+ def to_a
89
+ @storage[0...@size]
90
+ end
91
+
92
+ # Clear the buffer (reset logical size, keep capacity).
93
+ #
94
+ # @return [self] For method chaining
95
+ #
96
+ def clear!
97
+ # Clear references for GC (keep capacity)
98
+ @size.upto(@capacity - 1) { |i| @storage[i] = nil }
99
+ @size = 0
100
+ self
101
+ end
102
+
103
+ # Check if buffer is empty.
104
+ #
105
+ # @return [Boolean] true if size is zero
106
+ #
107
+ def empty?
108
+ @size.zero?
109
+ end
110
+
111
+ # Reset protocol for ObjectPool compatibility.
112
+ # Delegates to clear! for buffer cleanup.
113
+ #
114
+ # @return [self] For method chaining
115
+ #
116
+ def reset!
117
+ clear!
118
+ end
119
+
120
+ private
121
+
122
+ # Grow buffer capacity (double it).
123
+ # Should be rare with proper size class selection.
124
+ #
125
+ def grow!
126
+ new_capacity = @capacity * 2
127
+ new_storage = Array.new(new_capacity)
128
+ @storage.each_with_index { |elem, i| new_storage[i] = elem }
129
+ @storage = new_storage
130
+ @capacity = new_capacity
131
+ end
132
+ end
133
+ end