tcepsni 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83d6d7256e483e7259f7ca6a630969fdea2b00a94674130f33af6fc8992d50e1
4
- data.tar.gz: a4c891f49b92e1fa79fc36759665357eb47e5de1fe774f6a9e4c6c1e904d2a89
3
+ metadata.gz: f68a9bde443479e50e62f0f201a17c986eaad09e686e48adb24fa6a600ce38cb
4
+ data.tar.gz: 2e718d175261eb10ded9c3fbcad4926b6c98e5072d0a81d148aa1f40c6f04571
5
5
  SHA512:
6
- metadata.gz: 584b8d5ca524b82d8b1ff0e0ba04a8b76768c9ca64488699f2ad737bf337790c50fc9c938bdad75fe0630480b24c125bff80629e820e26a556c11d13e599463b
7
- data.tar.gz: 678dd3a11bdcaacc47f7a26d545dd5b4466b2e1f471b4b8f233c23c816658c25bc01a1c0bae2b688eb411f68518718fe571863917bccc108b8fa51b230d6da3d
6
+ metadata.gz: 232ff2963d9bca49cea25eb7cc90bc6fc08815808058289e61b6ffae5dc8ee1516b43a2d56b64fde23c707034b7d1d1c068c417fc66a1e21503327f32237d5bb
7
+ data.tar.gz: aadf113b5b26b20fc9d648ead1b43bf29f1c48eddd977348f0ef195af98dc0ab5fed4654dfd79a7b4f3009411b47a3d97e4834143c3ee99f6dab0b724300135c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.1 - 2023-10-02
6
+
7
+ ### Changed
8
+
9
+ - Object's memory reference attribute has changed to integer from string
10
+
11
+ ### Fixed
12
+
13
+ - String scanner parser now supports string with quotes
14
+
5
15
  ## 0.1.0 - 2023-10-01
6
16
 
7
17
  - Initial release
@@ -1,3 +1,3 @@
1
1
  module Tcepsni
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
data/lib/tcepsni.rb CHANGED
@@ -12,32 +12,41 @@ module Tcepsni
12
12
  class << self
13
13
  private
14
14
 
15
+ # If it returned nil when failed, it collides with normal nil value.
15
16
  def parse_expression(scanner)
16
- if (integer = scanner.scan(/\d+/))
17
- Integer(integer)
18
- elsif scanner.skip('nil')
17
+ if scanner.skip('nil')
19
18
  nil
20
19
  elsif scanner.skip('true')
21
20
  true
22
21
  elsif scanner.skip('false')
23
22
  false
24
- elsif scanner.skip(/:(?<name>[A-Za-z_][A-Za-z0-9_]*)/)
25
- scanner[:name].intern
23
+ elsif scanner.skip(':')
24
+ parse_identifier(scanner)
26
25
  elsif scanner.skip('"')
27
26
  parse_string(scanner)
28
27
  elsif scanner.skip('[')
29
28
  parse_array(scanner)
30
29
  elsif scanner.skip('{')
31
30
  parse_hash(scanner)
32
- elsif (name = scanner.scan(/[A-Z][A-Za-z0-9_]*/))
33
- parse_class(scanner, name: name.intern)
34
31
  elsif scanner.skip('#<')
35
32
  parse_object(scanner)
36
33
  else
37
- raise Error, "invalid format: #{ scanner.inspect }"
34
+ parse_integer(scanner) or parse_class(scanner)
38
35
  end
39
36
  end
40
37
 
38
+ # Returns nil if it's not integer.
39
+ # This doesn't raise error for convenience.
40
+ def parse_integer(scanner)
41
+ int = scanner.scan(/\d+/) or return
42
+ Integer(int)
43
+ end
44
+
45
+ def parse_identifier(scanner)
46
+ id = scanner.scan(/[A-Za-z_][A-Za-z0-9_]*/) or raise Error, 'no identifier'
47
+ id.intern
48
+ end
49
+
41
50
  def parse_string(scanner)
42
51
  result = ''
43
52
  until scanner.eos?
@@ -76,37 +85,45 @@ module Tcepsni
76
85
  result
77
86
  end
78
87
 
79
- def parse_class(scanner, name: nil)
80
- unless name
81
- name = scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, 'no class name'
82
- name = name.intern
83
- end
84
- namespaces = [name]
88
+ def parse_class(scanner)
89
+ namespaces = [parse_capitalized_identifier(scanner)]
85
90
  until scanner.eos?
86
91
  scanner.skip('::') or break
87
92
  scanner.eos? and raise Error, 'incomplete class'
88
- namespace = scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, 'no namespace'
89
- namespaces << namespace.intern
93
+ namespaces << parse_capitalized_identifier(scanner)
90
94
  end
91
95
  *namespaces, name = namespaces
92
96
  Tcepsni::Class.new(name: name, namespaces: namespaces)
93
97
  end
94
98
 
99
+ def parse_capitalized_identifier(scanner)
100
+ id = scanner.scan(/[A-Z][A-Za-z0-9_]*/) or raise Error, 'no capitalized identifier'
101
+ id.intern
102
+ end
103
+
95
104
  def parse_object(scanner)
96
105
  klass = parse_class(scanner)
97
106
  if klass.string_scanner?
98
- scanner.skip(%r{ (?<pos>\d+)/(?<total>\d+) "(?<scanned>[^"]+)" @ "(?<rest>[^"]+)">}) or raise Error, 'invalid string scanner'
99
- Tcepsni::StringScanner.new(pos: Integer(scanner[:pos]), total: Integer(scanner[:total]), scanned: scanner[:scanned], rest: scanner[:rest])
107
+ scanner.skip(' ') or raise Error, 'no space after string scanner class name'
108
+ pos = parse_integer(scanner) or raise Error, 'no string scanner pos'
109
+ scanner.skip('/') or raise Error, 'no string scanner progress delimiter slash'
110
+ total = parse_integer(scanner) or raise Error, 'no string scanner total size'
111
+ scanner.skip(' "') or raise Error, 'no space after string scanner progress'
112
+ scanned = parse_string(scanner)
113
+ scanner.skip(' @ "') or raise Error, "no string scanner mark in string: #{scanner.inspect}"
114
+ rest = parse_string(scanner)
115
+ scanner.skip('>') or raise Error, 'no string scanner closer'
116
+ Tcepsni::StringScanner.new(pos: pos, total: total, scanned: scanned, rest: rest)
100
117
  else
101
118
  scanner.skip(/:(?<memory_reference>0x[0-9a-f]{16})/) or raise Error, "no memory reference: #{scanner.inspect}"
102
- memory_reference = scanner[:memory_reference]
119
+ memory_reference = Integer(scanner[:memory_reference])
103
120
  attributes = {}
104
121
  unless scanner.skip('>')
105
122
  until scanner.eos?
106
- scanner.skip(/ @(?<key>[A-Za-z_][A-Za-z_0-9]*)=/) or break
107
- key = scanner[:key].intern
108
- value = parse_expression(scanner)
109
- attributes[key] = value
123
+ scanner.skip(' @') or break
124
+ key = parse_identifier(scanner)
125
+ scanner.skip('=') or raise Error, 'no attribute keyval equal char'
126
+ attributes[key.intern] = parse_expression(scanner)
110
127
  scanner.skip(',') or break
111
128
  end
112
129
  end
data/sig/tcepsni.gen.rbs CHANGED
@@ -6,10 +6,13 @@ module Tcepsni
6
6
 
7
7
  # def self.parse: (String str) -> parsed
8
8
  def self.parse_expression: (untyped scanner) -> ((Array[(Array[(Class | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Class | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[(Class | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Class | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?)
9
+ def self.parse_integer: (untyped scanner) -> Integer?
10
+ def self.parse_identifier: (untyped scanner) -> untyped
9
11
  def self.parse_string: (untyped scanner) -> String
10
12
  def self.parse_array: (untyped scanner) -> (Array[(Array[(Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?])
11
13
  def self.parse_hash: (untyped scanner) -> (Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[(Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, (Array[untyped] | Class | Hash[(Class | Integer | Object | String | StringScanner | bool)?, untyped] | Integer | Object | String | StringScanner | bool)?] | Integer | Object | String | StringScanner | bool)?])
12
- def self.parse_class: (untyped scanner, ?name: nil) -> Class
14
+ def self.parse_class: (untyped scanner) -> Class
15
+ def self.parse_capitalized_identifier: (untyped scanner) -> untyped
13
16
  def self.parse_object: (untyped scanner) -> (Object | StringScanner)
14
17
 
15
18
  class Class
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcepsni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - gemmaro
@@ -45,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
47
  requirements: []
48
- rubygems_version: 3.4.10
48
+ rubygems_version: 3.3.26
49
49
  signing_key:
50
50
  specification_version: 4
51
51
  summary: inspected Ruby objects parser