rley 0.1.04 → 0.1.05
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 +4 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/formatter/base_formatter.rb +33 -0
- data/lib/rley/formatter/debug.rb +121 -0
- data/lib/rley/parser/parsing.rb +8 -1
- data/spec/rley/formatter/debug_spec.rb +120 -0
- data/spec/rley/parse_tree_visitor_spec.rb +5 -6
- data/spec/rley/support/grammar_abc_helper.rb +19 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTUxODY4MDAzOWE1NjFkYzc5NGFjYzNhZWIxMTRjMmY5NzA4Zjg3Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTRlN2M4ZjUyZDE2MTVkMzBlODdjNjdkZWFjMzk5NjI0ZDI1MjNkZA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MWE4NTFmODdjMjk3YTU0NjY5YTFmMmI3ZjRmYzNjMDdlYjYwN2FkOTE1YTc3
|
10
|
+
ZmE1YjY2MTAwNGIwZTcyMThiOTQ5MjVjZWIzZDM4NTE3YzA4NWY5ZTMyM2Y2
|
11
|
+
YTQ0YTdkZWE2YjVmYzA3MDE5MjJjNmM1YzE0YzUyMDY0NjBlNDc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTFiMTNkZWVjYjVjYzNiMzg4N2E0ZDY0MWFkYWY5OWE0NGI1YjUyYTlkMjRj
|
14
|
+
YTU2NWM0ZDIwYTE2YWU2MmVjOTg2OTRhZTU0Njk1YjNmNTA0NjVjNDIzNDI2
|
15
|
+
NDkyMzBiYTc2MWI1ZmVhYTcyMjVkNzVjNTVjMTlmZjMyOTU5YjI=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
### 0.1.05 / 2014-12-10
|
2
|
+
* [NEW] New parse tree formatting classes `BaseFormatter` and `Debug`
|
3
|
+
* [CHANGE] Method `Parsing#parse_tree` now add links to Token objects in TerminalNodes.
|
4
|
+
|
1
5
|
### 0.1.04 / 2014-12-08
|
2
6
|
* [CHANGE] File `parse_tree_visitor_spec.rb`. Added step-by-step test of a parse tree visit.
|
3
7
|
|
data/lib/rley/constants.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rley # This module is used as a namespace
|
2
|
+
|
3
|
+
# Namespace dedicated to parse tree formatters.
|
4
|
+
module Formatter
|
5
|
+
|
6
|
+
# Superclass for parse tree formatters.
|
7
|
+
class BaseFormatter
|
8
|
+
# The IO output stream in which the formatter's result will be sent.
|
9
|
+
attr(:output)
|
10
|
+
|
11
|
+
# Constructor.
|
12
|
+
# @param anIO [IO] an output IO where the formatter's result will
|
13
|
+
# be placed.
|
14
|
+
def initialize(anIO)
|
15
|
+
@output = anIO
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
|
20
|
+
# Given a parse tree visitor, perform the visit
|
21
|
+
# and render the visit events in the output stream.
|
22
|
+
# @param aVisitor [ParseTreeVisitor]
|
23
|
+
def render(aVisitor)
|
24
|
+
aVisitor.subscribe(self)
|
25
|
+
aVisitor.start
|
26
|
+
aVisitor.unsubscribe(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # class
|
30
|
+
end # module
|
31
|
+
end # module
|
32
|
+
|
33
|
+
# End of file
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require_relative 'base_formatter'
|
2
|
+
|
3
|
+
|
4
|
+
module Rley # This module is used as a namespace
|
5
|
+
# Namespace dedicated to parse tree formatters.
|
6
|
+
module Formatter
|
7
|
+
|
8
|
+
# A formatter class that renders the visit notification events
|
9
|
+
# from a parse tree visitor
|
10
|
+
# @example
|
11
|
+
# some_grammar = ... # Points to a DynamicGrammar-like object
|
12
|
+
# # Output the result to the standard console output
|
13
|
+
# formatter = Sequitur::Formatter::Debug.new(STDOUT)
|
14
|
+
# # Render the visit notifications
|
15
|
+
# formatter.run(some_grammar.visitor)
|
16
|
+
class Debug < BaseFormatter
|
17
|
+
# Current indentation level
|
18
|
+
attr(:indentation)
|
19
|
+
|
20
|
+
# Constructor.
|
21
|
+
# @param anIO [IO] The output stream to which the rendered grammar
|
22
|
+
# is written.
|
23
|
+
def initialize(anIO)
|
24
|
+
super(anIO)
|
25
|
+
@indentation = 0
|
26
|
+
end
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
31
|
+
# Notification of a visit event: the visitor is about to visit the given
|
32
|
+
# parse tree
|
33
|
+
# @param _ptree [ParseTree]
|
34
|
+
def before_ptree(_ptree)
|
35
|
+
output_event(__method__, indentation)
|
36
|
+
indent
|
37
|
+
end
|
38
|
+
|
39
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
40
|
+
# Notification of a visit event: the visitor is about to visit
|
41
|
+
# a non-terminal node
|
42
|
+
# @param _nonterm [NonTerminalNode]
|
43
|
+
def before_non_terminal(_nonterm)
|
44
|
+
output_event(__method__, indentation)
|
45
|
+
indent
|
46
|
+
end
|
47
|
+
|
48
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
49
|
+
# Notification of a visit event: the visitor is about to visit
|
50
|
+
# the children of a non-terminal node
|
51
|
+
# @param _parent [NonTerminalNode]
|
52
|
+
# @param _children [Array] array of children nodes
|
53
|
+
def before_children(_parent, _children)
|
54
|
+
output_event(__method__, indentation)
|
55
|
+
indent
|
56
|
+
end
|
57
|
+
|
58
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
59
|
+
# Notification of a visit event: the visitor is about to visit
|
60
|
+
# a terminal node
|
61
|
+
# @param _term [TerminalNode]
|
62
|
+
def before_terminal(_term)
|
63
|
+
output_event(__method__, indentation)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
67
|
+
# Notification of a visit event: the visitor completed the visit of
|
68
|
+
# a terminal node.
|
69
|
+
# @param _term [TerminalNode]
|
70
|
+
def after_terminal(_term)
|
71
|
+
output_event(__method__, indentation)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
75
|
+
# Notification of a visit event: the visitor completed the visit of
|
76
|
+
# a non-terminal node
|
77
|
+
# @param _nonterm [NonTerminalNode]
|
78
|
+
def after_non_terminal(_)
|
79
|
+
dedent
|
80
|
+
output_event(__method__, indentation)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
84
|
+
# Notification of a visit event: the visitor completed the visit of
|
85
|
+
# the children of a non-terminal node.
|
86
|
+
# @param _parent [NonTerminalNode]
|
87
|
+
# @param _children [Array] array of children nodes
|
88
|
+
def after_children(_parent, _children)
|
89
|
+
dedent
|
90
|
+
output_event(__method__, indentation)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
95
|
+
# Notification of a visit event: the visitor completed the visit
|
96
|
+
# of the given parse tree
|
97
|
+
# @param _ptree [ParseTree]
|
98
|
+
def after_ptree(_ptree)
|
99
|
+
dedent
|
100
|
+
output_event(__method__, indentation)
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def indent()
|
106
|
+
@indentation += 1
|
107
|
+
end
|
108
|
+
|
109
|
+
def dedent()
|
110
|
+
@indentation -= 1
|
111
|
+
end
|
112
|
+
|
113
|
+
def output_event(anEvent, indentationLevel)
|
114
|
+
output.puts "#{' ' * 2 * indentationLevel}#{anEvent}"
|
115
|
+
end
|
116
|
+
|
117
|
+
end # class
|
118
|
+
end # module
|
119
|
+
end # module
|
120
|
+
|
121
|
+
# End of file
|
data/lib/rley/parser/parsing.rb
CHANGED
@@ -42,7 +42,9 @@ module Rley # This module is used as a namespace
|
|
42
42
|
when Syntax::Terminal
|
43
43
|
state_set_index -= 1
|
44
44
|
ptree.step_back(state_set_index)
|
45
|
-
|
45
|
+
if ptree.current_node.is_a?(PTree::TerminalNode)
|
46
|
+
ptree.current_node.token = tokens[state_set_index]
|
47
|
+
end
|
46
48
|
parse_state = chart[state_set_index].predecessor_state(parse_state)
|
47
49
|
curr_dotted_item = parse_state.dotted_rule
|
48
50
|
|
@@ -147,6 +149,11 @@ module Rley # This module is used as a namespace
|
|
147
149
|
candidate_states = last_chart_entry.states_for(start_production)
|
148
150
|
return candidate_states.find(&:complete?)
|
149
151
|
end
|
152
|
+
|
153
|
+
# Complete the generated parse tree.
|
154
|
+
# Link each terminal node to its corresponding token object.
|
155
|
+
def complete_ptree()
|
156
|
+
end
|
150
157
|
end # class
|
151
158
|
end # module
|
152
159
|
end # module
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
# require_relative '../../../lib/rley/dynamic_grammar'
|
5
|
+
require_relative '../support/grammar_abc_helper'
|
6
|
+
require_relative '../../../lib/rley/parser/token'
|
7
|
+
require_relative '../../../lib/rley/parser/earley_parser'
|
8
|
+
require_relative '../../../lib/rley/ptree/parse_tree'
|
9
|
+
require_relative '../../../lib/rley/parse_tree_visitor'
|
10
|
+
# Load the class under test
|
11
|
+
require_relative '../../../lib/rley/formatter/debug'
|
12
|
+
|
13
|
+
module Rley # Re-open the module to get rid of qualified names
|
14
|
+
module Formatter
|
15
|
+
|
16
|
+
describe Debug do
|
17
|
+
include GrammarABCHelper # Mix-in module with builder for grammar abc
|
18
|
+
|
19
|
+
# Factory method. Build a production with the given sequence
|
20
|
+
# of symbols as its rhs.
|
21
|
+
let(:grammar_abc) do
|
22
|
+
builder = grammar_abc_builder
|
23
|
+
builder.grammar
|
24
|
+
end
|
25
|
+
|
26
|
+
# Variables for the terminal symbols
|
27
|
+
let(:a_) { grammar_abc.name2symbol['a'] }
|
28
|
+
let(:b_) { grammar_abc.name2symbol['b'] }
|
29
|
+
let(:c_) { grammar_abc.name2symbol['c'] }
|
30
|
+
|
31
|
+
# Helper method that mimicks the output of a tokenizer
|
32
|
+
# for the language specified by gramma_abc
|
33
|
+
let(:grm_abc_tokens1) do
|
34
|
+
[
|
35
|
+
Parser::Token.new('a', a_),
|
36
|
+
Parser::Token.new('a', a_),
|
37
|
+
Parser::Token.new('b', b_),
|
38
|
+
Parser::Token.new('c', c_),
|
39
|
+
Parser::Token.new('c', c_)
|
40
|
+
]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Factory method that builds a sample parse tree.
|
44
|
+
# Generated tree has the following structure:
|
45
|
+
# S[0,5]
|
46
|
+
# +- A[0,5]
|
47
|
+
# +- a[0,0]
|
48
|
+
# +- A[1,4]
|
49
|
+
# | +- a[1,1]
|
50
|
+
# | +- A[2,3]
|
51
|
+
# | | +- b[2,3]
|
52
|
+
# | +- c[3,4]
|
53
|
+
# +- c[4,5]
|
54
|
+
# Capital letters represent non-terminal nodes
|
55
|
+
let(:grm_abc_ptree1) do
|
56
|
+
parser = Parser::EarleyParser.new(grammar_abc)
|
57
|
+
parse_result = parser.parse(grm_abc_tokens1)
|
58
|
+
parse_result.parse_tree
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:destination) { StringIO.new('', 'w') }
|
62
|
+
|
63
|
+
context 'Standard creation & initialization:' do
|
64
|
+
|
65
|
+
it 'should be initialized with an IO argument' do
|
66
|
+
expect { Debug.new(StringIO.new('', 'w')) }.not_to raise_error
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should know its output destination' do
|
70
|
+
instance = Debug.new(destination)
|
71
|
+
expect(instance.output).to eq(destination)
|
72
|
+
end
|
73
|
+
end # context
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
context 'Formatting events:' do
|
78
|
+
it 'should support visit events of a parse tree' do
|
79
|
+
instance = Debug.new(destination)
|
80
|
+
visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
|
81
|
+
instance.render(visitor)
|
82
|
+
expectations = <<-SNIPPET
|
83
|
+
before_ptree
|
84
|
+
before_non_terminal
|
85
|
+
before_children
|
86
|
+
before_non_terminal
|
87
|
+
before_children
|
88
|
+
before_terminal
|
89
|
+
after_terminal
|
90
|
+
before_non_terminal
|
91
|
+
before_children
|
92
|
+
before_terminal
|
93
|
+
after_terminal
|
94
|
+
before_non_terminal
|
95
|
+
before_children
|
96
|
+
before_terminal
|
97
|
+
after_terminal
|
98
|
+
after_children
|
99
|
+
after_non_terminal
|
100
|
+
before_terminal
|
101
|
+
after_terminal
|
102
|
+
after_children
|
103
|
+
after_non_terminal
|
104
|
+
before_terminal
|
105
|
+
after_terminal
|
106
|
+
after_children
|
107
|
+
after_non_terminal
|
108
|
+
after_children
|
109
|
+
after_non_terminal
|
110
|
+
after_ptree
|
111
|
+
SNIPPET
|
112
|
+
expect(destination.string).to eq(expectations)
|
113
|
+
end
|
114
|
+
end # context
|
115
|
+
end # describe
|
116
|
+
|
117
|
+
end # module
|
118
|
+
end # module
|
119
|
+
|
120
|
+
# End of file
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
require_relative './support/grammar_abc_helper'
|
4
5
|
require_relative '../../lib/rley/parser/token'
|
5
6
|
require_relative '../../lib/rley/parser/earley_parser'
|
6
7
|
# Load the class under test
|
@@ -8,12 +9,10 @@ require_relative '../../lib/rley/parse_tree_visitor'
|
|
8
9
|
|
9
10
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
10
11
|
describe ParseTreeVisitor do
|
12
|
+
include GrammarABCHelper # Mix-in module with builder for grammar abc
|
13
|
+
|
11
14
|
let(:grammar_abc) do
|
12
|
-
builder =
|
13
|
-
builder.add_terminals('a', 'b', 'c')
|
14
|
-
builder.add_production('S' => ['A'])
|
15
|
-
builder.add_production('A' => %w(a A c))
|
16
|
-
builder.add_production('A' => ['b'])
|
15
|
+
builder = grammar_abc_builder
|
17
16
|
builder.grammar
|
18
17
|
end
|
19
18
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Load the builder class
|
2
|
+
require_relative '../../../lib/rley/syntax/grammar_builder'
|
3
|
+
|
4
|
+
|
5
|
+
module GrammarABCHelper
|
6
|
+
|
7
|
+
# Factory method. Creates a grammar builder for a simple grammar.
|
8
|
+
# (based on example in N. Wirth "Compiler Construction" book, p. 6)
|
9
|
+
def grammar_abc_builder()
|
10
|
+
builder = Rley::Syntax::GrammarBuilder.new
|
11
|
+
builder.add_terminals('a', 'b', 'c')
|
12
|
+
builder.add_production('S' => ['A'])
|
13
|
+
builder.add_production('A' => %w(a A c))
|
14
|
+
builder.add_production('A' => ['b'])
|
15
|
+
|
16
|
+
return builder
|
17
|
+
end
|
18
|
+
end # module
|
19
|
+
|
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.1.
|
4
|
+
version: 0.1.05
|
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-12-
|
11
|
+
date: 2014-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -89,6 +89,8 @@ files:
|
|
89
89
|
- examples/grammars/grammar_L0.rb
|
90
90
|
- lib/rley.rb
|
91
91
|
- lib/rley/constants.rb
|
92
|
+
- lib/rley/formatter/base_formatter.rb
|
93
|
+
- lib/rley/formatter/debug.rb
|
92
94
|
- lib/rley/parser/chart.rb
|
93
95
|
- lib/rley/parser/dotted_item.rb
|
94
96
|
- lib/rley/parser/earley_parser.rb
|
@@ -111,6 +113,7 @@ files:
|
|
111
113
|
- lib/rley/syntax/symbol_seq.rb
|
112
114
|
- lib/rley/syntax/terminal.rb
|
113
115
|
- lib/rley/syntax/verbatim_symbol.rb
|
116
|
+
- spec/rley/formatter/debug_spec.rb
|
114
117
|
- spec/rley/parser/chart_spec.rb
|
115
118
|
- spec/rley/parser/dotted_item_spec.rb
|
116
119
|
- spec/rley/parser/earley_parser_spec.rb
|
@@ -123,6 +126,7 @@ files:
|
|
123
126
|
- spec/rley/ptree/parse_tree_node_spec.rb
|
124
127
|
- spec/rley/ptree/parse_tree_spec.rb
|
125
128
|
- spec/rley/ptree/token_range_spec.rb
|
129
|
+
- spec/rley/support/grammar_abc_helper.rb
|
126
130
|
- spec/rley/syntax/grammar_builder_spec.rb
|
127
131
|
- spec/rley/syntax/grammar_spec.rb
|
128
132
|
- spec/rley/syntax/grm_symbol_spec.rb
|
@@ -165,6 +169,7 @@ signing_key:
|
|
165
169
|
specification_version: 4
|
166
170
|
summary: Ruby implementation of the Earley's parsing algorithm
|
167
171
|
test_files:
|
172
|
+
- spec/rley/formatter/debug_spec.rb
|
168
173
|
- spec/rley/parser/chart_spec.rb
|
169
174
|
- spec/rley/parser/dotted_item_spec.rb
|
170
175
|
- spec/rley/parser/earley_parser_spec.rb
|