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 +8 -8
- data/CHANGELOG.md +4 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/syntax/grammar.rb +27 -1
- data/lib/rley/syntax/grm_symbol.rb +4 -1
- data/lib/rley/syntax/non_terminal.rb +22 -0
- data/lib/rley/syntax/terminal.rb +7 -0
- data/spec/rley/parser/earley_parser_spec.rb +31 -0
- data/spec/rley/syntax/grammar_spec.rb +4 -0
- data/spec/rley/syntax/non_terminal_spec.rb +11 -0
- data/spec/rley/syntax/terminal_spec.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWJmOTI2YmJiNWQwNDY5YjM3ZTdmMzdlZmEyMDE0ODRiM2Q1N2Y4YQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjNmODNiOWZlYTc3MzcyNGUzZDhiNWVhMTBjNDRjZmU2OTg3NTM4Yg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWRiMmM1NzQ3ZjdjZjAwYTZlNWFlYzgxMjliY2M2YzQ2MzZjMTNlMmE2NjI5
|
10
|
+
YTAxNWNhMGMxMjY1ODU3NzI4YTFhNmNmNzkxMzAzNjUyMjZjZjBlM2U5ZDhi
|
11
|
+
ZmY0MmU3ZTgxNmJjYTk3ZTc3MTg1MmFlYWNhYjhiMjJjOTljOTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzQyYmYyNzc5ZmIyNTVjMWJkOTVjNzI5NzM2N2Y5N2ZkN2Y1NmRlODcwNjAz
|
14
|
+
MzRiNGIyNGIxNGExMGJlNjY4ZjYxYTc5YTc4Mjg1ODEyZGEyNGExOTM3N2Iw
|
15
|
+
ODFkMGU4MjIxNTZmZjczNWNiYjUzMjYwYTZhZjkxNTRmZjg2MmU=
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
data/lib/rley/constants.rb
CHANGED
data/lib/rley/syntax/grammar.rb
CHANGED
@@ -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
|
data/lib/rley/syntax/terminal.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2014-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|