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