rley 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
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