rley 0.8.08 → 0.8.11

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: 55b425fac78001960b95935a8dc8de88d1c0826bea5fba5fae72455f53cb084a
4
- data.tar.gz: fdf0f9ed39985923134cd3ecc4bdd9325c9aab783437ab1d61a07e333ad3f2eb
3
+ metadata.gz: f7ad228834b0f81ead8bc7ba0276c46b15d1d26e6c041bca00737bc5e224642b
4
+ data.tar.gz: 8877d597137a6aa3548abe6bdeeb5c51d9e94479094c78db377680657131a7d2
5
5
  SHA512:
6
- metadata.gz: e63b7a5df081fa326b48f7f2e2cedbaf877ed377927e408278e3c8078a30fdcc69714ff234ba98dccc1eb3b05eaea53ebb39846a43e2cb794b883d91ce1c6953
7
- data.tar.gz: e60bc7b045fe8d7203ddf26ecd603646137d43cbbbe79b533b2088c0f7d15bb46bc1dd58ae4d811ba8d78327fdcb0045cfddec4d708a76968d33c1602bf71cf4
6
+ metadata.gz: b7f4da7fafc790cd5c737310b811b4b5e51d5f37c37373ce04089c73e8ade7c318d3638ee1b345e165b7cbd59cc7636038ad866f19352f8208d8de759c47006d
7
+ data.tar.gz: 611344a1d84c111e3280cac654082670eecc27f4da781e9f32e5bfdc21f52a1ff3c17cb812de2b346cfbf29247c5976321368cebcf55e0463860f5f7281ab61a
data/.rubocop.yml CHANGED
@@ -5,6 +5,9 @@ AllCops:
5
5
  Gemspec/DateAssignment:
6
6
  Enabled: true
7
7
 
8
+ Gemspec/RequireMFA: # new in 1.23
9
+ Enabled: false
10
+
8
11
  Layout/ArgumentAlignment:
9
12
  Enabled: false
10
13
 
@@ -130,6 +133,9 @@ Lint/RaiseException:
130
133
 
131
134
  Lint/RedundantDirGlobSort:
132
135
  Enabled: true
136
+
137
+ Lint/RefinementImportMethods: # new in 1.27
138
+ Enabled: true
133
139
 
134
140
  Lint/RequireRelativeSelfPath:
135
141
  Enabled: true
@@ -161,6 +167,9 @@ Lint/UnusedMethodArgument:
161
167
  Lint/UselessAccessModifier:
162
168
  Enabled: true
163
169
 
170
+ Lint/UselessRuby2Keywords: # new in 1.23
171
+ Enabled: true
172
+
164
173
  Lint/Void:
165
174
  Enabled: false
166
175
 
@@ -200,6 +209,9 @@ Metrics/ModuleLength:
200
209
  Metrics/PerceivedComplexity:
201
210
  Enabled: false
202
211
 
212
+ Naming/BlockForwarding: # new in 1.24
213
+ Enabled: true
214
+
203
215
  Naming/ConstantName:
204
216
  Enabled: false
205
217
 
@@ -278,6 +290,12 @@ Style/ExpandPathArguments:
278
290
  Style/ExponentialNotation:
279
291
  Enabled: true
280
292
 
293
+ Style/FileRead: # new in 1.24
294
+ Enabled: true
295
+
296
+ Style/FileWrite: # new in 1.24
297
+ Enabled: true
298
+
281
299
  Style/GuardClause:
282
300
  Enabled: false
283
301
 
@@ -302,6 +320,9 @@ Style/InPatternThen:
302
320
  Style/InverseMethods:
303
321
  Enabled: false
304
322
 
323
+ Style/MapToHash: # new in 1.24
324
+ Enabled: true
325
+
305
326
  Style/MissingRespondToMissing:
306
327
  Enabled: false
307
328
 
@@ -310,6 +331,9 @@ Style/MultilineInPatternThen:
310
331
 
311
332
  Style/NegatedIfElseCondition:
312
333
  Enabled: true
334
+
335
+ Style/NestedFileDirname: # new in 1.26
336
+ Enabled: true
313
337
 
314
338
  Style/Next:
315
339
  Enabled: false
@@ -326,6 +350,9 @@ Style/NumberedParametersLimit:
326
350
  Style/NumericLiterals:
327
351
  Enabled: false
328
352
 
353
+ Style/OpenStructUse: # new in 1.23
354
+ Enabled: true
355
+
329
356
  Style/QuotedSymbols:
330
357
  Enabled: true
331
358
 
@@ -334,6 +361,9 @@ Style/RaiseArgs:
334
361
 
335
362
  Style/RedundantArgument:
336
363
  Enabled: true
364
+
365
+ Style/RedundantInitialize: # new in 1.27
366
+ Enabled: true
337
367
 
338
368
  Style/RedundantReturn:
339
369
  Enabled: false
@@ -349,9 +379,9 @@ Style/RegexpLiteral:
349
379
 
350
380
  Style/PercentLiteralDelimiters:
351
381
  Enabled: false
352
-
382
+
353
383
  Style/SelectByRegexp:
354
- Enabled: true
384
+ Enabled: true
355
385
 
356
386
  Style/StderrPuts:
357
387
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,7 +1,18 @@
1
+ ### 0.8.10 / 2022-04-08
2
+ - Refactoring of `RGN::Tokenizer` class.
3
+ * [CHANGE] Class `RGN::Tokenizer` changes.
4
+
5
+ ### 0.8.09 / 2022-01-28
6
+ - Added code for coming tutorial
7
+
8
+ * [NEW] Folder `tutorial` contains code used in tutorial (in wiki)
9
+ * [NEW] Folders `TOML\iter_1` .. `TOML\iter_2` contains code for a TOML parser
10
+ * [CHANGE] File `.rubocop.yml` updated to take into account new 1.25 cops.
11
+ * [CHANGE] File `.rubocop.yml` updated to take into account new 1.25 cops.
12
+
1
13
  ### 0.8.08 / 2021-10-31
2
14
  - Fixes in example files, Refactored module `Notation` renamed `to `RGN´
3
15
 
4
-
5
16
  * [CHANGE] Module `Notation` changed to `RGN`.
6
17
 
7
18
  * [FIX] `examples/general/calc_iter1/CalcLexer#initialize` now strips whitespaces at end of expression to parse.
@@ -21,7 +32,7 @@
21
32
 
22
33
  * [NEW] Folder `example\tokenizer` contains an example with a scanner that was generated.
23
34
  * [NEW] Class `Rley::Lexical::Literal` a specialization of Token class for literal tokens.
24
- * [CHANGE] File `.rubocp.yml` updated to take into account new 1.21 and 1.22 cops.
35
+ * [CHANGE] File `.rubocop.yml` updated to take into account new 1.21 and 1.22 cops.
25
36
  * [DELETED] Class `Rley::Parser::ParserTracer` this class was no more in use.
26
37
  * [DELETED] Class `Rley::Syntax::Literal` this class was unused.
27
38
  * [DELETED] Class `Rley::Syntax::VerbatimSymbol` this class was unused.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2021 Dimitri Geshef
1
+ Copyright (c) 2014-2022 Dimitri Geshef
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -458,5 +458,5 @@ standard parser textbooks. Here are a few references (and links) of papers on GF
458
458
 
459
459
  Copyright
460
460
  ---------
461
- Copyright (c) 2014-2020, Dimitri Geshef.
461
+ Copyright (c) 2014-2022, Dimitri Geshef.
462
462
  __Rley__ is released under the MIT License see [LICENSE.txt](https://github.com/famished-tiger/Rley/blob/master/LICENSE.txt) for details.
@@ -5,7 +5,7 @@
5
5
 
6
6
  module Rley # Module used as a namespace
7
7
  # The version number of the gem.
8
- Version = '0.8.08'
8
+ Version = '0.8.11'
9
9
 
10
10
  # Brief description of the gem.
11
11
  Description = "Ruby implementation of the Earley's parsing algorithm"
@@ -36,7 +36,7 @@ module Rley
36
36
 
37
37
  # Abstract method (must be overriden in subclasses).
38
38
  # Part of the 'visitee' role in Visitor design pattern.
39
- # @param _visitor [LoxxyTreeVisitor] the visitor
39
+ # @param _visitor [ASTVisitor] the visitor
40
40
  def accept(_visitor)
41
41
  raise NotImplementedError
42
42
  end
@@ -35,9 +35,9 @@ module Rley
35
35
  @engine.use_grammar(Rley::RGN::RGNGrammar)
36
36
  end
37
37
 
38
- # Parse the given Lox program into a parse tree.
39
- # @param source [String] Lox program to parse
40
- # @return [Rley::ParseTree] A parse tree equivalent to the Lox input.
38
+ # Parse the given RGN snippet into a parse tree.
39
+ # @param source [String] Snippet to parse
40
+ # @return [Rley::ParseTree] A parse tree equivalent to the RGN input.
41
41
  def parse(source)
42
42
  lexer = Tokenizer.new(source)
43
43
  result = engine.parse(lexer.tokens)
@@ -28,7 +28,7 @@ module Rley
28
28
 
29
29
  # Abstract method (must be overriden in subclasses).
30
30
  # Part of the 'visitee' role in Visitor design pattern.
31
- # @param visitor [LoxxyTreeVisitor] the visitor
31
+ # @param visitor [RGN::ASTVisitor] the visitor
32
32
  def accept(visitor)
33
33
  visitor.visit_symbol_node(self)
34
34
  end
@@ -14,6 +14,13 @@ module Rley
14
14
  # Delimiters: e.g. parentheses '(', ')'
15
15
  # Separators: e.g. comma
16
16
  class Tokenizer
17
+ PATT_KEY = /[a-zA-Z_][a-zA-Z_0-9]*:/.freeze
18
+ PATT_INTEGER = /\d+/.freeze
19
+ PATT_NEWLINE = /(?:\r\n)|\r|\n/.freeze
20
+ PATT_STRING_START = /"|'/.freeze
21
+ PATT_SYMBOL = /[^?*+,:(){}\s]+/.freeze
22
+ PATT_WHITESPACE = /[ \t\f]+/.freeze
23
+
17
24
  # @return [StringScanner] Low-level input scanner
18
25
  attr_reader(:scanner)
19
26
 
@@ -24,7 +31,7 @@ module Rley
24
31
  attr_reader(:line_start)
25
32
 
26
33
  # One or two special character tokens.
27
- @@lexeme2name = {
34
+ Lexeme2name = {
28
35
  '(' => 'LEFT_PAREN',
29
36
  ')' => 'RIGHT_PAREN',
30
37
  '{' => 'LEFT_BRACE',
@@ -39,21 +46,21 @@ module Rley
39
46
  # Here are all the implemented Rley notation keywords
40
47
  @@keywords = %w[
41
48
  match_closest repeat
42
- ].map { |x| [x, x] }.to_h
49
+ ].to_h { |x| [x, x] }
43
50
 
44
- # Constructor. Initialize a tokenizer for Lox input.
45
- # @param source [String] Lox text to tokenize.
51
+ # Constructor. Initialize a tokenizer for RGN input.
52
+ # @param source [String] RGN text to tokenize.
46
53
  def initialize(source = nil)
47
- @scanner = StringScanner.new('')
48
- start_with(source) if source
54
+ reset
55
+ input = source || ''
56
+ @scanner = StringScanner.new(input)
49
57
  end
50
58
 
51
59
  # Reset the tokenizer and make the given text, the current input.
52
- # @param source [String] Lox text to tokenize.
60
+ # @param source [String] RGN text to tokenize.
53
61
  def start_with(source)
62
+ reset
54
63
  @scanner.string = source
55
- @lineno = 1
56
- @line_start = 0
57
64
  end
58
65
 
59
66
  # Scan the source and return an array of tokens.
@@ -65,47 +72,64 @@ module Rley
65
72
  tok_sequence << token unless token.nil?
66
73
  end
67
74
 
68
- return tok_sequence
75
+ tok_sequence
69
76
  end
70
77
 
71
78
  private
72
79
 
73
- def _next_token
74
- pos_before = scanner.pos
75
- skip_intertoken_spaces
76
- ws_found = true if scanner.pos > pos_before
77
- curr_ch = scanner.peek(1)
78
- return nil if curr_ch.nil? || curr_ch.empty?
80
+ def reset
81
+ @lineno = 1
82
+ @line_start = 0
83
+ end
79
84
 
85
+ def _next_token
80
86
  token = nil
87
+ ws_found = false
81
88
 
82
- if '(){},'.include? curr_ch
83
- # Single delimiter, separator or character
84
- token = build_token(@@lexeme2name[curr_ch], scanner.getch)
85
- elsif '?*+,'.include? curr_ch # modifier character
86
- # modifiers without prefix text are symbols
87
- symb = ws_found ? 'SYMBOL' : @@lexeme2name[curr_ch]
88
- token = build_token(symb, scanner.getch)
89
- elsif (lexeme = scanner.scan(/\.\./))
90
- # One or two special character tokens
91
- token = build_token(@@lexeme2name[lexeme], lexeme)
92
- elsif scanner.check(/"|'/) # Start of string detected...
93
- token = build_string_token
94
- elsif (lexeme = scanner.scan(/\d+/))
95
- token = build_token('INT_LIT', lexeme)
96
- elsif (lexeme = scanner.scan(/[a-zA-Z_][a-zA-Z_0-9]*:/))
97
- keyw = @@keywords[lexeme.chop!]
98
- token = build_token('KEY', lexeme) if keyw
99
- # ... error case
100
- elsif (lexeme = scanner.scan(/[^?*+,:(){}\s]+/))
101
- token = build_token('SYMBOL', lexeme)
102
- else # Unknown token
103
- col = scanner.pos - @line_start + 1
104
- _erroneous = curr_ch.nil? ? '' : scanner.scan(/./)
105
- raise ScanError, "Error: [line #{lineno}:#{col}]: Unexpected character."
106
- end
89
+ # Loop until end of input reached or token found
90
+ until token || scanner.eos?
107
91
 
108
- return token
92
+ nl_found = scanner.skip(PATT_NEWLINE)
93
+ if nl_found
94
+ next_line_scanned
95
+ next
96
+ end
97
+ if scanner.skip(PATT_WHITESPACE) # Skip whitespaces
98
+ ws_found = true
99
+ next
100
+ end
101
+
102
+ curr_ch = scanner.peek(1)
103
+
104
+ if '(){},'.include? curr_ch
105
+ # Single delimiter, separator or character
106
+ token = build_token(Lexeme2name[curr_ch], scanner.getch)
107
+ elsif '?*+,'.include? curr_ch # modifier character
108
+ # modifiers without prefix text are symbols
109
+ symb = (ws_found || nl_found) ? 'SYMBOL' : Lexeme2name[curr_ch]
110
+ token = build_token(symb, scanner.getch)
111
+ elsif (lexeme = scanner.scan(/\.\./))
112
+ # One or two special character tokens
113
+ token = build_token(Lexeme2name[lexeme], lexeme)
114
+ elsif scanner.check(PATT_STRING_START) # Start of string detected...
115
+ token = build_string_token
116
+ elsif (lexeme = scanner.scan(PATT_INTEGER))
117
+ token = build_token('INT_LIT', lexeme)
118
+ elsif (lexeme = scanner.scan(PATT_KEY))
119
+ keyw = @@keywords[lexeme.chop!]
120
+ token = build_token('KEY', lexeme) if keyw
121
+ # ... error case
122
+ elsif (lexeme = scanner.scan(PATT_SYMBOL))
123
+ token = build_token('SYMBOL', lexeme)
124
+ else # Unknown token
125
+ col = scanner.pos - @line_start + 1
126
+ _erroneous = curr_ch.nil? ? '' : scanner.scan(/./)
127
+ raise ScanError, "Error: [line #{lineno}:#{col}]: Unexpected character."
128
+ end
129
+ ws_found = false
130
+ end # until
131
+
132
+ token
109
133
  end
110
134
 
111
135
  def build_token(aSymbolName, aLexeme)
@@ -154,24 +178,8 @@ module Rley
154
178
  Rley::Lexical::Token.new(literal, 'STR_LIT', pos)
155
179
  end
156
180
 
157
- # Skip non-significant whitespaces and comments.
158
- # Advance the scanner until something significant is found.
159
- def skip_intertoken_spaces
160
- loop do
161
- ws_found = scanner.skip(/[ \t\f]+/) ? true : false
162
- nl_found = scanner.skip(/(?:\r\n)|\r|\n/)
163
- if nl_found
164
- ws_found = true
165
- next_line
166
- end
167
-
168
- break unless ws_found
169
- end
170
-
171
- scanner.pos
172
- end
173
-
174
- def next_line
181
+ # Event: next line detected.
182
+ def next_line_scanned
175
183
  @lineno += 1
176
184
  @line_start = scanner.pos
177
185
  end
@@ -8,10 +8,6 @@ module Rley # This module is used as a namespace
8
8
  # @return [String] The name of the grammar symbol
9
9
  attr_reader(:name)
10
10
 
11
- # An indicator that tells whether the grammar symbol can generate a
12
- # non-empty string of terminals.
13
- attr_writer(:generative)
14
-
15
11
  # Constructor.
16
12
  # aName [String] The name of the grammar symbol.
17
13
  def initialize(aName)
@@ -7,6 +7,10 @@ module Rley # This module is used as a namespace
7
7
  # A non-terminal symbol (sometimes called a syntactic variable) represents
8
8
  # a composition of terminal or non-terminal symbols
9
9
  class NonTerminal < GrmSymbol
10
+ # An indicator that tells whether the grammar symbol can generate a
11
+ # non-empty string of terminals.
12
+ attr_writer(:generative)
13
+
10
14
  # A non-terminal symbol is nullable if it can match an empty string.
11
15
  attr_writer(:nullable)
12
16
 
@@ -7,25 +7,29 @@ module Rley # This module is used as a namespace
7
7
  # A terminal symbol represents a class of words in the language
8
8
  # defined the grammar.
9
9
  class Terminal < GrmSymbol
10
- # Constructor.
11
- # @param aName [String] The name of the grammar symbol.
12
- def initialize(aName)
13
- super(aName)
14
- self.generative = true
10
+ # An indicator that tells whether the grammar symbol can generate a
11
+ # non-empty string of terminals.
12
+ # @return [TrueClass]
13
+ def generative?
14
+ true
15
15
  end
16
16
 
17
17
  # Return true iff the symbol is a terminal
18
+ # @return [TrueClass]
18
19
  def terminal?
19
- return true
20
+ true
20
21
  end
21
22
 
22
23
  # @return [false] Return true if the symbol derives
23
24
  # the empty string. As terminal symbol corresponds to a input token
24
25
  # it is by definition non-nullable.
26
+ # @return [FalseClass]
25
27
  def nullable?
26
28
  false
27
29
  end
28
30
 
31
+ # Return a readable text representation of the instance
32
+ # @return [String] The symbol name
29
33
  def to_s
30
34
  name
31
35
  end
@@ -22,7 +22,6 @@ require_relative '../support/expectation_helper'
22
22
  require_relative '../../../lib/rley/parser/gfg_earley_parser'
23
23
 
24
24
  module Rley # Open this namespace to avoid module qualifier prefixes
25
- # rubocop: disable Metrics/BlockLength
26
25
  module Parser # Open this namespace to avoid module qualifier prefixes
27
26
  describe GFGEarleyParser do
28
27
  include GrammarABCHelper # Mix-in module with builder for grammar abc
@@ -1038,6 +1037,5 @@ MSG
1038
1037
  end # context
1039
1038
  end # describe
1040
1039
  end # module
1041
- # rubocop: enable Metrics/BlockLength
1042
1040
  end # module
1043
1041
  # End of file
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.08
4
+ version: 0.8.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-31 00:00:00.000000000 Z
11
+ date: 2022-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prime
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -296,14 +310,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
296
310
  requirements:
297
311
  - - ">="
298
312
  - !ruby/object:Gem::Version
299
- version: 2.5.0
313
+ version: 2.6.0
300
314
  required_rubygems_version: !ruby/object:Gem::Requirement
301
315
  requirements:
302
316
  - - ">="
303
317
  - !ruby/object:Gem::Version
304
318
  version: '0'
305
319
  requirements: []
306
- rubygems_version: 3.1.4
320
+ rubygems_version: 3.3.7
307
321
  signing_key:
308
322
  specification_version: 4
309
323
  summary: Ruby implementation of the Earley's parsing algorithm
@@ -330,14 +344,6 @@ test_files:
330
344
  - spec/rley/lexical/literal_spec.rb
331
345
  - spec/rley/lexical/token_range_spec.rb
332
346
  - spec/rley/lexical/token_spec.rb
333
- - spec/rley/parser/dangling_else_spec.rb
334
- - spec/rley/parser/error_reason_spec.rb
335
- - spec/rley/parser/gfg_chart_spec.rb
336
- - spec/rley/parser/gfg_earley_parser_spec.rb
337
- - spec/rley/parser/gfg_parsing_spec.rb
338
- - spec/rley/parser/parse_entry_set_spec.rb
339
- - spec/rley/parser/parse_entry_spec.rb
340
- - spec/rley/parser/parse_walker_factory_spec.rb
341
347
  - spec/rley/parse_forest_visitor_spec.rb
342
348
  - spec/rley/parse_rep/ambiguous_parse_spec.rb
343
349
  - spec/rley/parse_rep/ast_builder_spec.rb
@@ -347,6 +353,14 @@ test_files:
347
353
  - spec/rley/parse_rep/parse_forest_factory_spec.rb
348
354
  - spec/rley/parse_rep/parse_tree_factory_spec.rb
349
355
  - spec/rley/parse_tree_visitor_spec.rb
356
+ - spec/rley/parser/dangling_else_spec.rb
357
+ - spec/rley/parser/error_reason_spec.rb
358
+ - spec/rley/parser/gfg_chart_spec.rb
359
+ - spec/rley/parser/gfg_earley_parser_spec.rb
360
+ - spec/rley/parser/gfg_parsing_spec.rb
361
+ - spec/rley/parser/parse_entry_set_spec.rb
362
+ - spec/rley/parser/parse_entry_spec.rb
363
+ - spec/rley/parser/parse_walker_factory_spec.rb
350
364
  - spec/rley/ptree/non_terminal_node_spec.rb
351
365
  - spec/rley/ptree/parse_tree_node_spec.rb
352
366
  - spec/rley/ptree/parse_tree_spec.rb