rley 0.0.08 → 0.0.09
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 +8 -8
- data/CHANGELOG.md +7 -1
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/parser/earley_parser.rb +2 -2
- data/lib/rley/syntax/grammar_builder.rb +114 -0
- data/lib/rley/syntax/production.rb +15 -1
- data/spec/rley/parser/earley_parser_spec.rb +3 -3
- data/spec/rley/syntax/grammar_builder_spec.rb +142 -0
- data/spec/rley/syntax/production_spec.rb +9 -0
- data/spec/rley/syntax/symbol_seq_spec.rb +7 -1
- metadata +5 -4
- data/spec/rley/support/grammar_abc.rb +0 -22
- data/spec/rley/support/grammar_helper.rb +0 -16
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NjMyOTZiYzU4MjllMDU0NjlmYTZjZWIxNWY1Y2U0YTlmYjQzOWQxMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzlhZDNkZGIwZTMzMzJhZmQyYWVlODE5MzUzODQ4NWNmMzFiY2M2ZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjU2MjE0ZGQwZDE2MjU1OGIzYzRkZjc4ZDZmNzI4ODQ3YmY2NGQ4MWY4YWFk
|
10
|
+
NTQzZGY0YjNhMjUwNWUzOWYwMjM0ZTk2ODRlMjQ3M2RhNWViMWU4ZGEwNjEx
|
11
|
+
ODQzOTk5MzM1NzE3MTY3ZWRiOGNmZWIwOWY2YTE4MzVkM2ViOGU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YzczYTY4Y2FlMWUyZWNhMjEyYjhhM2RkMzk0YzNmNjQ0MTE4NGZiMjQ2MDY2
|
14
|
+
Y2IzOGI1YjNjNzgyZTNlMmMyNzAyYjc3MDQzYjY2YzkzZmVjZDE5OThkZTc5
|
15
|
+
ZTMzMGVmNGUwYjk0Y2QxN2E3OGJjNGI0MWE0ZDRlZTRkYmY2NGM=
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
### 0.0.09 / 2014-11-15
|
2
|
+
* [NEW] New class `GrammarBuilder` added and tested, its purpose is
|
3
|
+
to simplify the construction of grammars.
|
4
|
+
|
5
|
+
|
1
6
|
### 0.0.08 / 2014-11-14
|
2
7
|
* [CHANGE] `EarleyParser#parse` method: Initial API documentation.
|
3
|
-
* [INFO] This version was committed to force Travis CI to execute a complete build
|
8
|
+
* [INFO] This version was committed to force Travis CI to execute a complete build
|
9
|
+
failed because Travis couldn't connect to GitHub)
|
4
10
|
|
5
11
|
### 0.0.07 / 2014-11-14
|
6
12
|
* [CHANGE] spec file of `EarleyParser` class: Test added. Parser works with simple expression grammar.
|
data/lib/rley/constants.rb
CHANGED
@@ -20,8 +20,8 @@ module Rley # This module is used as a namespace
|
|
20
20
|
# after "advancing" the dot
|
21
21
|
attr_reader(:next_mapping)
|
22
22
|
|
23
|
-
# @param aGrammar [Grammar] A context-free grammar that defines the
|
24
|
-
# of the input to be parsed.
|
23
|
+
# @param aGrammar [Grammar] A context-free grammar that defines the
|
24
|
+
# language of the input to be parsed.
|
25
25
|
def initialize(aGrammar)
|
26
26
|
@grammar = aGrammar
|
27
27
|
@dotted_items = build_dotted_items(grammar)
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative 'verbatim_symbol'
|
2
|
+
require_relative 'literal'
|
3
|
+
require_relative 'non_terminal'
|
4
|
+
require_relative 'production'
|
5
|
+
require_relative 'grammar'
|
6
|
+
|
7
|
+
module Rley # This module is used as a namespace
|
8
|
+
module Syntax # This module is used as a namespace
|
9
|
+
# Builder pattern. Builder pattern builds a complex object
|
10
|
+
# (say, a grammar) from simpler objects (terminals and productions)
|
11
|
+
# and using a step by step approach.
|
12
|
+
class GrammarBuilder
|
13
|
+
# The list of symbols of the language.
|
14
|
+
# Grammar symbols are categorized into terminal (symbol)
|
15
|
+
# and non-terminal (symbol).
|
16
|
+
attr_reader(:symbols)
|
17
|
+
|
18
|
+
# The list of production rules for the grammar to build
|
19
|
+
attr_reader(:productions)
|
20
|
+
|
21
|
+
def initialize()
|
22
|
+
@symbols = {}
|
23
|
+
@productions = []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Retrieve a grammar symbol from its name.
|
27
|
+
# Raise an exception if not found.
|
28
|
+
# @param [aSymbolName] the name of a symbol grammar.
|
29
|
+
# @return [GrmSymbol] the retrieved symbol.
|
30
|
+
def [](aSymbolName)
|
31
|
+
return symbols[aSymbolName]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add the terminal symbols of the language
|
35
|
+
# terminalSymbols [String or Terminal] one or more terminal symbols
|
36
|
+
# to add to the grammar.
|
37
|
+
def add_terminals(*terminalSymbols)
|
38
|
+
new_symbs = build_symbols(Terminal, terminalSymbols)
|
39
|
+
symbols.merge!(new_symbs)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Add the non-terminal symbols of the language
|
43
|
+
# nonTerminalSymbols [String or NonTerminal] one or more non-terminal
|
44
|
+
# symbols to add to the grammar.
|
45
|
+
def add_non_terminals(*nonTerminalSymbols)
|
46
|
+
new_symbs = build_symbols(NonTerminal, nonTerminalSymbols)
|
47
|
+
symbols.merge!(new_symbs)
|
48
|
+
end
|
49
|
+
|
50
|
+
# builder.add_production('A' => ['a', 'A', 'c'])
|
51
|
+
def add_production(aProductionRepr)
|
52
|
+
aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
|
53
|
+
lhs = self[lhs_name]
|
54
|
+
case rhs_repr
|
55
|
+
when Array
|
56
|
+
rhs_constituents = rhs_repr.map { |name| self[name] }
|
57
|
+
when String
|
58
|
+
rhs_constituents = [ self[rhs_repr] ]
|
59
|
+
end
|
60
|
+
new_prod = Production.new(lhs, rhs_constituents)
|
61
|
+
productions << new_prod
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Given the grammar symbols and productions added to the builder,
|
66
|
+
# build the resulting grammar.
|
67
|
+
def grammar()
|
68
|
+
fail StandardError, 'No symbol found for grammar' if symbols.empty?
|
69
|
+
if productions.empty?
|
70
|
+
fail StandardError, 'No production found for grammar'
|
71
|
+
end
|
72
|
+
|
73
|
+
return Grammar.new(productions.dup)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Add the given grammar symbols.
|
79
|
+
# @param aClass [Class] The class of grammar symbols to instantiate.
|
80
|
+
# @param aSymbol [Array] array of elements are treated as follows:
|
81
|
+
# if the element is already a grammar symbol, then it added as is,
|
82
|
+
# otherwise it is considered as the name of a grammar symbol
|
83
|
+
# of the specified class to build.
|
84
|
+
def build_symbols(aClass, theSymbols)
|
85
|
+
symbs = {}
|
86
|
+
theSymbols.each do |s|
|
87
|
+
new_symbol = build_symbol(aClass, s)
|
88
|
+
symbs[new_symbol.name] = new_symbol
|
89
|
+
end
|
90
|
+
|
91
|
+
return symbs
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# If the argument is already a grammar symbol object then it is
|
96
|
+
# returned as is. Otherwise, the argument is treated as a name
|
97
|
+
# for a new instance of the given class.
|
98
|
+
# @param aClass [Class] The class of grammar symbols to instantiate
|
99
|
+
# @param aSymbol [GrmSymbol-like or String]
|
100
|
+
# @return [Array] list of grammar symbols
|
101
|
+
def build_symbol(aClass, aSymbolArg)
|
102
|
+
if aSymbolArg.kind_of?(GrmSymbol)
|
103
|
+
a_symbol = aSymbolArg
|
104
|
+
else
|
105
|
+
a_symbol = aClass.new(aSymbolArg)
|
106
|
+
end
|
107
|
+
|
108
|
+
return a_symbol
|
109
|
+
end
|
110
|
+
end # class
|
111
|
+
end # module
|
112
|
+
end # module
|
113
|
+
|
114
|
+
# End of file
|
@@ -22,7 +22,7 @@ module Rley # This module is used as a namespace
|
|
22
22
|
alias_method :head, :lhs
|
23
23
|
|
24
24
|
def initialize(aNonTerminal, theSymbols)
|
25
|
-
@lhs = aNonTerminal
|
25
|
+
@lhs = valid_lhs(aNonTerminal)
|
26
26
|
@rhs = SymbolSeq.new(theSymbols)
|
27
27
|
end
|
28
28
|
|
@@ -31,6 +31,20 @@ module Rley # This module is used as a namespace
|
|
31
31
|
def empty?()
|
32
32
|
return rhs.empty?
|
33
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Validation method. Return the validated input argument or
|
38
|
+
# raise an exception.
|
39
|
+
def valid_lhs(aNonTerminal)
|
40
|
+
unless aNonTerminal.kind_of?(NonTerminal)
|
41
|
+
msg_prefix = 'Left side of production must be a non-terminal symbol'
|
42
|
+
msg_suffix = ", found a #{aNonTerminal.class} instead."
|
43
|
+
fail StandardError, msg_prefix + msg_suffix
|
44
|
+
end
|
45
|
+
|
46
|
+
return aNonTerminal
|
47
|
+
end
|
34
48
|
end # class
|
35
49
|
end # module
|
36
50
|
end # module
|
@@ -282,7 +282,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
282
282
|
{ origin: 0, production: prod_S2, dot: -1 },
|
283
283
|
{ origin: 0, production: prod_M1, dot: 1 },
|
284
284
|
{ origin: 0, production: prod_P, dot: -1 },
|
285
|
-
{ origin: 0, production: prod_S1, dot: 1 }
|
285
|
+
{ origin: 0, production: prod_S1, dot: 1 }
|
286
286
|
]
|
287
287
|
compare_state_set(parse_result.chart[1], expectations)
|
288
288
|
|
@@ -297,7 +297,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
297
297
|
{ origin: 0, production: prod_S1, dot: 2 },
|
298
298
|
{ origin: 2, production: prod_M1, dot: 0 },
|
299
299
|
{ origin: 2, production: prod_M2, dot: 0 },
|
300
|
-
{ origin: 2, production: prod_T, dot: 0 }
|
300
|
+
{ origin: 2, production: prod_T, dot: 0 }
|
301
301
|
]
|
302
302
|
compare_state_set(parse_result.chart[2], expectations)
|
303
303
|
|
@@ -324,7 +324,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
324
324
|
|
325
325
|
expectations = [
|
326
326
|
{ origin: 2, production: prod_M1, dot: 2 },
|
327
|
-
{ origin: 4, production: prod_T, dot: 0 }
|
327
|
+
{ origin: 4, production: prod_T, dot: 0 }
|
328
328
|
]
|
329
329
|
compare_state_set(parse_result.chart[4], expectations)
|
330
330
|
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
# Load the class under test
|
4
|
+
require_relative '../../../lib/rley/syntax/grammar_builder'
|
5
|
+
|
6
|
+
module Rley # Open this namespace to avoid module qualifier prefixes
|
7
|
+
module Syntax # Open this namespace to avoid module qualifier prefixes
|
8
|
+
describe GrammarBuilder do
|
9
|
+
|
10
|
+
context 'Initialization:' do
|
11
|
+
it 'should be created without argument' do
|
12
|
+
expect { GrammarBuilder.new }.not_to raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have no grammar symbols at start' do
|
16
|
+
expect(subject.symbols).to be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have no productions at start' do
|
20
|
+
expect(subject.productions).to be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
end # context
|
24
|
+
|
25
|
+
context 'Adding symbols:' do
|
26
|
+
it 'should build terminals from their names' do
|
27
|
+
subject.add_terminals('a', 'b', 'c')
|
28
|
+
expect(subject.symbols.size).to eq(3)
|
29
|
+
expect(subject.symbols['a']).to be_kind_of(Terminal)
|
30
|
+
expect(subject.symbols['a'].name).to eq('a')
|
31
|
+
expect(subject.symbols['b']).to be_kind_of(Terminal)
|
32
|
+
expect(subject.symbols['b'].name).to eq('b')
|
33
|
+
expect(subject.symbols['c']).to be_kind_of(Terminal)
|
34
|
+
expect(subject.symbols['c'].name).to eq('c')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should accept already built terminals' do
|
38
|
+
a = Terminal.new('a')
|
39
|
+
b = VerbatimSymbol.new('b')
|
40
|
+
c = Literal.new('c', /c/)
|
41
|
+
|
42
|
+
subject.add_terminals(a, b, c)
|
43
|
+
expect(subject.symbols.size).to eq(3)
|
44
|
+
expect(subject.symbols['a']).to eq(a)
|
45
|
+
expect(subject.symbols['b']).to eq(b)
|
46
|
+
expect(subject.symbols['c']).to eq(c)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should build non-terminals from their names' do
|
50
|
+
subject.add_non_terminals('PP', 'VP', 'DT')
|
51
|
+
expect(subject.symbols.size).to eq(3)
|
52
|
+
expect(subject.symbols['PP']).to be_kind_of(NonTerminal)
|
53
|
+
expect(subject.symbols['PP'].name).to eq('PP')
|
54
|
+
expect(subject.symbols['VP']).to be_kind_of(NonTerminal)
|
55
|
+
expect(subject.symbols['VP'].name).to eq('VP')
|
56
|
+
expect(subject.symbols['DT']).to be_kind_of(NonTerminal)
|
57
|
+
expect(subject.symbols['DT'].name).to eq('DT')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should accept already built terminals' do
|
61
|
+
a = Terminal.new('a')
|
62
|
+
b = VerbatimSymbol.new('b')
|
63
|
+
c = Literal.new('c', /c/)
|
64
|
+
|
65
|
+
subject.add_terminals(a, b, c)
|
66
|
+
expect(subject.symbols.size).to eq(3)
|
67
|
+
expect(subject.symbols['a']).to eq(a)
|
68
|
+
expect(subject.symbols['b']).to eq(b)
|
69
|
+
expect(subject.symbols['c']).to eq(c)
|
70
|
+
end
|
71
|
+
end # context
|
72
|
+
|
73
|
+
context 'Adding productions:' do
|
74
|
+
subject do
|
75
|
+
instance = GrammarBuilder.new
|
76
|
+
instance.add_terminals('a', 'b', 'c')
|
77
|
+
instance.add_non_terminals('S', 'A')
|
78
|
+
instance
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should add a valid production' do
|
82
|
+
# case of a rhs representation that consists of one name
|
83
|
+
expect { subject.add_production('S' => 'A') }.not_to raise_error
|
84
|
+
expect(subject.productions.size).to eq(1)
|
85
|
+
new_prod = subject.productions[0]
|
86
|
+
expect(new_prod.lhs).to eq(subject['S'])
|
87
|
+
expect(new_prod.rhs[0]).to eq(subject['A'])
|
88
|
+
|
89
|
+
subject.add_production('A' => %w(a A c))
|
90
|
+
expect(subject.productions.size).to eq(2)
|
91
|
+
new_prod = subject.productions.last
|
92
|
+
expect(new_prod.lhs).to eq(subject['A'])
|
93
|
+
expect_rhs = [ subject['a'], subject['A'], subject['c'] ]
|
94
|
+
expect(new_prod.rhs.members).to eq(expect_rhs)
|
95
|
+
|
96
|
+
subject.add_production('A' => ['b'])
|
97
|
+
expect(subject.productions.size).to eq(3)
|
98
|
+
new_prod = subject.productions.last
|
99
|
+
expect(new_prod.lhs).to eq(subject['A'])
|
100
|
+
expect(new_prod.rhs[0]).to eq(subject['b'])
|
101
|
+
end
|
102
|
+
end # context
|
103
|
+
|
104
|
+
context 'Building grammar:' do
|
105
|
+
subject do
|
106
|
+
instance = GrammarBuilder.new
|
107
|
+
instance.add_terminals('a', 'b', 'c')
|
108
|
+
instance.add_non_terminals('S', 'A')
|
109
|
+
instance.add_production('S' => ['A'])
|
110
|
+
instance.add_production('A' => %w(a A c))
|
111
|
+
instance.add_production('A' => ['b'])
|
112
|
+
instance
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should build a grammar' do
|
116
|
+
expect(subject.grammar).to be_kind_of(Grammar)
|
117
|
+
grm = subject.grammar
|
118
|
+
expect(grm.rules).to eq(subject.productions)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should complain in absence of symbols' do
|
122
|
+
instance = GrammarBuilder.new
|
123
|
+
err = StandardError
|
124
|
+
msg = 'No symbol found for grammar'
|
125
|
+
expect { instance.grammar }.to raise_error(err, msg)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should complain in absence of productions' do
|
129
|
+
instance = GrammarBuilder.new
|
130
|
+
instance.add_terminals('a', 'b', 'c')
|
131
|
+
instance.add_non_terminals('S', 'A')
|
132
|
+
err = StandardError
|
133
|
+
msg = 'No production found for grammar'
|
134
|
+
expect { instance.grammar }.to raise_error(err, msg)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end # describe
|
139
|
+
end # module
|
140
|
+
end # module
|
141
|
+
|
142
|
+
# End of file
|
@@ -39,6 +39,15 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
39
39
|
instance = Production.new(sentence, [])
|
40
40
|
expect(instance).to be_empty
|
41
41
|
end
|
42
|
+
|
43
|
+
it 'should complain if its lhs is not a non-terminal' do
|
44
|
+
err = StandardError
|
45
|
+
msg_prefix = 'Left side of production must be a non-terminal symbol'
|
46
|
+
msg_suffix = ", found a #{String} instead."
|
47
|
+
msg = msg_prefix + msg_suffix
|
48
|
+
expect { Production.new('wrong', sequence) }.to raise_error(err, msg)
|
49
|
+
|
50
|
+
end
|
42
51
|
end # context
|
43
52
|
|
44
53
|
end # describe
|
@@ -41,7 +41,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
41
41
|
|
42
42
|
context 'Provided services:' do
|
43
43
|
it 'should compare compare with itself' do
|
44
|
-
me = subject
|
44
|
+
me = subject # Use another name to please Rubocop
|
45
45
|
expect(subject == me).to eq(true)
|
46
46
|
end
|
47
47
|
|
@@ -55,6 +55,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
55
55
|
unequal_one = SymbolSeq.new([verb, pp, np])
|
56
56
|
expect(subject == unequal_one).not_to eq(true)
|
57
57
|
end
|
58
|
+
|
59
|
+
it 'should complain when unable to compare' do
|
60
|
+
err = StandardError
|
61
|
+
msg = 'Cannot compare a SymbolSeq with a Fixnum'
|
62
|
+
expect { subject == 1 }.to raise_error(err, msg)
|
63
|
+
end
|
58
64
|
end # context
|
59
65
|
|
60
66
|
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.09
|
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-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- lib/rley/parser/state_set.rb
|
95
95
|
- lib/rley/parser/token.rb
|
96
96
|
- lib/rley/syntax/grammar.rb
|
97
|
+
- lib/rley/syntax/grammar_builder.rb
|
97
98
|
- lib/rley/syntax/grm_symbol.rb
|
98
99
|
- lib/rley/syntax/literal.rb
|
99
100
|
- lib/rley/syntax/non_terminal.rb
|
@@ -108,8 +109,7 @@ files:
|
|
108
109
|
- spec/rley/parser/parsing_spec.rb
|
109
110
|
- spec/rley/parser/state_set_spec.rb
|
110
111
|
- spec/rley/parser/token_spec.rb
|
111
|
-
- spec/rley/
|
112
|
-
- spec/rley/support/grammar_helper.rb
|
112
|
+
- spec/rley/syntax/grammar_builder_spec.rb
|
113
113
|
- spec/rley/syntax/grammar_spec.rb
|
114
114
|
- spec/rley/syntax/grm_symbol_spec.rb
|
115
115
|
- spec/rley/syntax/literal_spec.rb
|
@@ -158,6 +158,7 @@ test_files:
|
|
158
158
|
- spec/rley/parser/parsing_spec.rb
|
159
159
|
- spec/rley/parser/state_set_spec.rb
|
160
160
|
- spec/rley/parser/token_spec.rb
|
161
|
+
- spec/rley/syntax/grammar_builder_spec.rb
|
161
162
|
- spec/rley/syntax/grammar_spec.rb
|
162
163
|
- spec/rley/syntax/grm_symbol_spec.rb
|
163
164
|
- spec/rley/syntax/literal_spec.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative '../../../lib/rley/syntax/verbatim_symbol'
|
2
|
-
require_relative '../../../lib/rley/syntax/non_terminal'
|
3
|
-
require_relative '../../../lib/rley/syntax/production'
|
4
|
-
require_relative '../../../lib/rley/parser/token'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# Grammar 1: A very simple language
|
9
|
-
# (based on example in N. Wirth "Compiler Construction" book, p. 6)
|
10
|
-
# S ::= A.
|
11
|
-
# A ::= "a" A "c".
|
12
|
-
# A ::= "b".
|
13
|
-
# Let's create the grammar piece by piece
|
14
|
-
let(:nt_S) { Syntax::NonTerminal.new('S') }
|
15
|
-
let(:nt_A) { Syntax::NonTerminal.new('A') }
|
16
|
-
let(:a_) { Syntax::VerbatimSymbol.new('a') }
|
17
|
-
let(:b_) { Syntax::VerbatimSymbol.new('b') }
|
18
|
-
let(:c_) { Syntax::VerbatimSymbol.new('c') }
|
19
|
-
let(:prod_S) { Syntax::Production.new(nt_S, [nt_A]) }
|
20
|
-
let(:prod_A1) { Syntax::Production.new(nt_A, [a_, nt_A, c_]) }
|
21
|
-
let(:prod_A2) { Syntax::Production.new(nt_A, [b_]) }
|
22
|
-
let(:grammar_abc) { Syntax::Grammar.new([prod_S, prod_A1, prod_A2]) }
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require_relative '../../../lib/rley/syntax/verbatim_symbol'
|
2
|
-
require_relative '../../../lib/rley/syntax/non_terminal'
|
3
|
-
require_relative '../../../lib/rley/syntax/production'
|
4
|
-
require_relative '../../../lib/rley/syntax/grammar'
|
5
|
-
|
6
|
-
module Rley # This module is used as a namespace
|
7
|
-
# Mix-in module that provides factory methods that simplify the construction
|
8
|
-
# of a grammar from its constituents.
|
9
|
-
module GrammarHelper
|
10
|
-
# Create a production
|
11
|
-
def production()
|
12
|
-
end
|
13
|
-
end # module
|
14
|
-
end # module
|
15
|
-
|
16
|
-
# End of file
|