rley 0.0.11 → 0.0.12

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MTE3MWVhNjUzOTkzNjM3N2E3MjdjYzE5MWE1MDEyMmNkZGM3NGJiYw==
4
+ YWJmOTI2YmJiNWQwNDY5YjM3ZTdmMzdlZmEyMDE0ODRiM2Q1N2Y4YQ==
5
5
  data.tar.gz: !binary |-
6
- NGM4ZGI2NTY2ZDU1NDU5YzQxMjFiNWVlZmU0YWU3MDhjMGMxYTQ5OA==
6
+ ZjNmODNiOWZlYTc3MzcyNGUzZDhiNWVhMTBjNDRjZmU2OTg3NTM4Yg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NDA1NzYzZTU2NjY5MDdlMGJkYjZiZGEzZGY5YTkxMzYxZTk3NTNmNDlhZGRl
10
- NTUwZjRkYTZlZGIyYTAxYWI2NGE2MWVmMWNiN2JjYTY4MDU2ZDgwYjIyNDY1
11
- Y2E3ZjViZTkyM2Q5ZTY1ZjJiMmViNmNlZGFlODE3MzE5YjhiM2Y=
9
+ OWRiMmM1NzQ3ZjdjZjAwYTZlNWFlYzgxMjliY2M2YzQ2MzZjMTNlMmE2NjI5
10
+ YTAxNWNhMGMxMjY1ODU3NzI4YTFhNmNmNzkxMzAzNjUyMjZjZjBlM2U5ZDhi
11
+ ZmY0MmU3ZTgxNmJjYTk3ZTc3MTg1MmFlYWNhYjhiMjJjOTljOTU=
12
12
  data.tar.gz: !binary |-
13
- NzUxNmMzMjZkMWM2Y2NmMzJmY2U3ZTA3ZDYyYmVkZDI2MjAxYTc2MWIxYmRj
14
- NzYyMzRjOGQxZWIxOTFlN2U4OGUzMTMzMzU5ZjNhMTU0OTkwMDk2MmMzMmU5
15
- NTZiNTMwZjc4MjBlZWJjOWJmOWE4MWFmZDcyYWQyZWZlZTdmN2U=
13
+ NzQyYmYyNzc5ZmIyNTVjMWJkOTVjNzI5NzM2N2Y5N2ZkN2Y1NmRlODcwNjAz
14
+ MzRiNGIyNGIxNGExMGJlNjY4ZjYxYTc5YTc4Mjg1ODEyZGEyNGExOTM3N2Iw
15
+ ODFkMGU4MjIxNTZmZjczNWNiYjUzMjYwYTZhZjkxNTRmZjg2MmU=
@@ -1,3 +1,7 @@
1
+ ### 0.0.12 / 2014-11-17
2
+ * [CHANGE] Classes `Terminal` and `NonTerminal` added new method nullable?
3
+
4
+
1
5
  ### 0.0.11 / 2014-11-16
2
6
  * [CHANGE] Usage of `GrammarBuilder`simplified: the call to method `GrammarBuilder#add_non_terminal` isn't necessary. Method is removed
3
7
  * [CHANGE] Updated the `examples` folder accordingly.
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Rley # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.0.11'
6
+ Version = '0.0.12'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Ruby implementation of the Earley's parsing algorithm"
@@ -19,7 +19,8 @@ module Rley # This module is used as a namespace
19
19
  # The list of grammar symbols in the language.
20
20
  attr_reader(:symbols)
21
21
 
22
- # @param theProduction [Array of Production]
22
+ # @param theProduction [Array of Production] the list of productions
23
+ # of the grammar.
23
24
  def initialize(theProductions)
24
25
  @rules = []
25
26
  @symbols = []
@@ -27,6 +28,12 @@ module Rley # This module is used as a namespace
27
28
  # TODO: use topological sorting
28
29
  @start_symbol = valid_productions[0].lhs
29
30
  valid_productions.each { |prod| add_production(prod) }
31
+ compute_nullable
32
+ end
33
+
34
+ # @return [Array] The list of non-terminals in the grammar.
35
+ def non_terminals()
36
+ return symbols.select { |s| s.kind_of?(NonTerminal) }
30
37
  end
31
38
 
32
39
  private
@@ -49,6 +56,25 @@ module Rley # This module is used as a namespace
49
56
  @symbols << symb
50
57
  end
51
58
  end
59
+
60
+ # For each non-terminal determine whether it is nullable or not.
61
+ def compute_nullable()
62
+ # Do the obvious cases
63
+ rules.each do |prod|
64
+ next unless prod.rhs.empty?
65
+ prod.lhs.nullable = true
66
+ end
67
+ end
68
+ =begin
69
+ prods4nonterm = productions.group_by { |prod| prod.lhs }
70
+ prods4nonterm.each_pair do |(lhs, prods)|
71
+
72
+
73
+ to_process = non_terminals.select { |nt| nt.nullable?.nil? }
74
+
75
+ until to_process.empty? do
76
+
77
+ =end
52
78
  end # class
53
79
  end # module
54
80
  end # module
@@ -2,13 +2,16 @@ module Rley # This module is used as a namespace
2
2
  module Syntax # This module is used as a namespace
3
3
  # Abstract class for grammar symbols.
4
4
  # A grammar symbol is an element that appears in grammar rules.
5
- class GrmSymbol
5
+ class GrmSymbol
6
6
  # The name of the grammar symbol
7
7
  attr_reader(:name)
8
8
 
9
+ # Constructor.
10
+ # aName [String] The name of the grammar symbol.
9
11
  def initialize(aName)
10
12
  @name = aName.dup
11
13
  end
14
+
12
15
  end # class
13
16
  end # module
14
17
  end # module
@@ -5,9 +5,31 @@ module Rley # This module is used as a namespace
5
5
  # A non-terminal symbol (sometimes called a syntactic variable) represents
6
6
  # a composition of terminal or non-terminal symbols
7
7
  class NonTerminal < GrmSymbol
8
+
9
+ # Constructor.
10
+ # @param aName [String] The name of the grammar symbol.
8
11
  def initialize(aName)
9
12
  super(aName)
10
13
  end
14
+
15
+ public
16
+
17
+ # @return [false/true] Return true if the symbol derives
18
+ # the empty string. As non-terminal symbol is nullable when it can
19
+ # can match to zero input token.
20
+ # The "nullability" of a non-terminal can practically be determined once
21
+ # all the production rules of the grammar are specified.
22
+ def nullable?()
23
+ return @nullable
24
+ end
25
+
26
+ # Set the nullable flag.
27
+ # @param aBoolean [true/false]
28
+ def nullable=(aBoolean)
29
+ @nullable = aBoolean
30
+ end
31
+
32
+
11
33
  end # class
12
34
  end # module
13
35
  end # module
@@ -7,9 +7,16 @@ module Rley # This module is used as a namespace
7
7
  # defined the grammar.
8
8
  class Terminal < GrmSymbol
9
9
 
10
+ # Constructor.
11
+ # aName [String] The name of the grammar symbol.
10
12
  def initialize(aName)
11
13
  super(aName)
12
14
  end
15
+
16
+ # @return [false] Return true if the symbol derives
17
+ # the empty string. As terminal symbol corresponds to a input token
18
+ # it is by definition non-nullable.
19
+ def nullable?() false; end
13
20
  end # class
14
21
 
15
22
  end # module
@@ -3,6 +3,7 @@ require_relative '../../spec_helper'
3
3
  require_relative '../../../lib/rley/syntax/verbatim_symbol'
4
4
  require_relative '../../../lib/rley/syntax/non_terminal'
5
5
  require_relative '../../../lib/rley/syntax/production'
6
+ require_relative '../../../lib/rley/syntax/grammar_builder'
6
7
  require_relative '../../../lib/rley/parser/token'
7
8
  # Load the class under test
8
9
  require_relative '../../../lib/rley/parser/earley_parser'
@@ -344,6 +345,36 @@ module Rley # Open this namespace to avoid module qualifier prefixes
344
345
  ]
345
346
  compare_state_set(parse_result.chart[5], expectations)
346
347
  end
348
+
349
+
350
+ it 'should parse an ambiguous grammar' do
351
+ # Grammar 3: A ambiguous arithmetic expression language
352
+ # (based on example in article on Earley's algorithm in Wikipedia)
353
+ # P ::= S.
354
+ # S ::= S "+" S.
355
+ # S ::= S "*" S.
356
+ # S ::= T.
357
+ # T ::= an integer number token.
358
+ t_int = Syntax::Literal.new('integer', /[-+]?\d+/)
359
+ t_plus = Syntax::VerbatimSymbol.new('+')
360
+ t_star = Syntax::VerbatimSymbol.new('*')
361
+
362
+ builder = Syntax::GrammarBuilder.new
363
+ builder.add_terminals(t_int, t_plus, t_star)
364
+ builder.add_production('P' => 'S')
365
+ builder.add_production('S' => %w(S + S))
366
+ builder.add_production('S' => %w(S * S))
367
+ builder.add_production('S' => 'L')
368
+ builder.add_production('L' => 'integer')
369
+ tokens = [
370
+ Token.new('2', t_int),
371
+ Token.new('+', t_plus),
372
+ Token.new('3', t_int),
373
+ Token.new('*', t_star),
374
+ Token.new('4', t_int)
375
+ ]
376
+ parse_result = subject.parse(tokens)
377
+ end
347
378
 
348
379
 
349
380
  it 'should parse an invalid simple input' do
@@ -138,6 +138,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
138
138
  it 'should know all its symbols' do
139
139
  expect(subject.symbols).to eq([nt_S, nt_A, a_, c_, b_])
140
140
  end
141
+
142
+ it 'should know all its non-terminal symbols' do
143
+ expect(subject.non_terminals).to eq([nt_S, nt_A])
144
+ end
141
145
  end # context
142
146
 
143
147
  end # describe
@@ -19,6 +19,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
19
19
  end
20
20
  end # context
21
21
 
22
+
23
+ context 'Provided services:' do
24
+ it 'should know whether it is nullable' do
25
+ expect(subject.nullable?).to be_nil
26
+ subject.nullable = true
27
+ expect(subject).to be_nullable
28
+ subject.nullable = false
29
+ expect(subject).not_to be_nullable
30
+ end
31
+ end # context
32
+
22
33
  end # describe
23
34
  end # module
24
35
  end # module
@@ -17,6 +17,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
17
17
  it 'should know its name' do
18
18
  expect(subject.name).to eq(sample_name)
19
19
  end
20
+
21
+ it "should know that isn't nullable" do
22
+ expect(subject).not_to be_nullable
23
+ end
20
24
  end # context
21
25
 
22
26
  end # describe
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-16 00:00:00.000000000 Z
11
+ date: 2014-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake