• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

type-ruby / t-ruby / 20560974963

28 Dec 2025 11:21PM UTC coverage: 79.076% (+1.7%) from 77.331%
20560974963

push

github

web-flow
refactor: migrate parser from regex to token-based parser combinator (#29)

* refactor: migrate parser from regex to token-based parser combinator

- Replace monolithic parser_combinator.rb (2833 lines) with modular architecture
- Add Scanner for tokenization with regex literal support
- Create IR::InterpolatedString for string interpolation parsing
- Fix type inference for interpolated strings (returns String)
- Add TRuby::ParseError for unified error handling
- Organize parsers into primitives/, combinators/, and token/ directories
- Each file contains exactly one class (snake_case filename matches PascalCase class)

* fix: enhance parser to support ternary, splat args, and statement expressions

- Add ternary operator (? :) parsing in ExpressionParser
- Support double splat (**opts) and single splat (*args) in method calls
- Support keyword arguments (name: value) in method calls
- Allow case/if/unless/begin as assignment right-hand side values
- Improve generic type compatibility (Array[untyped] with Array[T])

Fixes type inference errors in keyword_args samples.

* style: fix RuboCop violations and adjust metrics limits

* fix: require set for Ruby 3.1 compatibility

1849 of 2098 new or added lines in 53 files covered. (88.13%)

6 existing lines in 2 files now uncovered.

6644 of 8402 relevant lines covered (79.08%)

908.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.0
/lib/t_ruby/parser_combinator/token/token_parser.rb
1
# frozen_string_literal: true
2

3
module TRuby
1✔
4
  module ParserCombinator
1✔
5
    # Base class for token parsers
6
    class TokenParser
1✔
7
      def parse(tokens, position = 0)
1✔
NEW
8
        raise NotImplementedError
×
9
      end
10

11
      # Sequence: run this parser, then the other
12
      def >>(other)
1✔
13
        TokenSequence.new(self, other)
24✔
14
      end
15

16
      # Alternative: try this parser, if it fails try the other
17
      def |(other)
1✔
18
        TokenAlternative.new(self, other)
6✔
19
      end
20

21
      # Map: transform the result
22
      def map(&block)
1✔
23
        TokenMap.new(self, block)
1✔
24
      end
25

26
      # Many: zero or more repetitions
27
      def many
1✔
28
        TokenMany.new(self)
2✔
29
      end
30

31
      # Many1: one or more repetitions
32
      def many1
1✔
NEW
33
        TokenMany1.new(self)
×
34
      end
35

36
      # Optional: zero or one
37
      def optional
1✔
38
        TokenOptional.new(self)
4✔
39
      end
40

41
      # Separated by: parse items separated by delimiter
42
      def sep_by(delimiter)
1✔
43
        TokenSepBy.new(self, delimiter)
3✔
44
      end
45

46
      # Separated by 1: at least one item
47
      def sep_by1(delimiter)
1✔
NEW
48
        TokenSepBy1.new(self, delimiter)
×
49
      end
50

51
      # Skip right: parse both, keep left result
52
      def <<(other)
1✔
53
        TokenSkipRight.new(self, other)
1✔
54
      end
55

56
      # Label: add a descriptive label for error messages
57
      def label(name)
1✔
NEW
58
        TokenLabel.new(self, name)
×
59
      end
60
    end
61
  end
62
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc