rley 0.1.05 → 0.1.06
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/formatter/debug.rb +0 -6
- data/lib/rley/formatter/json.rb +125 -0
- data/lib/rley/parser/parsing.rb +4 -6
- data/lib/rley/ptree/terminal_node.rb +1 -1
- data/spec/rley/formatter/debug_spec.rb +0 -1
- data/spec/rley/formatter/json_spec.rb +112 -0
- data/spec/rley/ptree/parse_tree_spec.rb +5 -6
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzFjODYyODc0MDUzODcwNDlmYWI0ODhkNTAxNDJjZmVlNTUwMTdiNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
N2QxZWZlODFjNTBlMzM4NzgzMWMwYzY4YWUzZDI4MTk1ODAwZmY4Nw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDI3YjJmMjA0Mzg1NjhhNWJhMWZjNGIyNjE5OTg2NGYwMzNhNmUwMDA4ODM5
|
10
|
+
ZWI2M2Q5NjAyMGIyODlkOTYxZTMyMjg3NjdkMjgzZDJlNjJmYmJiNTc3MDli
|
11
|
+
OTcyZWIwOWFjY2UzMzRlMDA1OWU5ZTlhMDc4MGE0Yzc2MmRmYzE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjMzOGViZTZmOTIwMTAwM2FjYTMyZjAyYjYzMmIyMjY0OTM4OTk0NDM3MzAw
|
14
|
+
YTEyNzE2NjA0OTA0NTVmZDRkYTJiNDAxMDY1NTE2NjlhM2M2YzNhZTA0OWIy
|
15
|
+
NWJkNTQ2M2RjMjAxZmUxMjQ3MmY5OGQ1ZmE2ZjMyYzUwMzhhNDA=
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
### 0.1.06 / 2014-12-13
|
2
|
+
* [NEW] New parse tree formatting class `JSON` for parse tree rendition in JSON.
|
3
|
+
* [FIX] Method `Parsing#parse_tree` now add link to Token object for last TerminalNode in tree.
|
4
|
+
|
1
5
|
### 0.1.05 / 2014-12-10
|
2
6
|
* [NEW] New parse tree formatting classes `BaseFormatter` and `Debug`
|
3
7
|
* [CHANGE] Method `Parsing#parse_tree` now add links to Token objects in TerminalNodes.
|
data/lib/rley/constants.rb
CHANGED
data/lib/rley/formatter/debug.rb
CHANGED
@@ -7,12 +7,6 @@ module Rley # This module is used as a namespace
|
|
7
7
|
|
8
8
|
# A formatter class that renders the visit notification events
|
9
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
10
|
class Debug < BaseFormatter
|
17
11
|
# Current indentation level
|
18
12
|
attr(:indentation)
|
@@ -0,0 +1,125 @@
|
|
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 a parse tree in JSON format
|
9
|
+
class Json < BaseFormatter
|
10
|
+
# Current indentation level
|
11
|
+
attr(:indentation)
|
12
|
+
|
13
|
+
# Array of booleans (one per indentation level).
|
14
|
+
# Set to true after first child was visited.
|
15
|
+
attr(:sibling_flags)
|
16
|
+
|
17
|
+
# Constructor.
|
18
|
+
# @param anIO [IO] The output stream to which the rendered grammar
|
19
|
+
# is written.
|
20
|
+
def initialize(anIO)
|
21
|
+
super(anIO)
|
22
|
+
@indentation = 0
|
23
|
+
@sibling_flags = [ false ]
|
24
|
+
end
|
25
|
+
|
26
|
+
public
|
27
|
+
|
28
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
29
|
+
# Notification of a visit event: the visitor is about to visit the given
|
30
|
+
# parse tree
|
31
|
+
# @param _ptree [ParseTree]
|
32
|
+
def before_ptree(_ptree)
|
33
|
+
print_text('', "{\n")
|
34
|
+
indent
|
35
|
+
print_text('', "\"root\":")
|
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_node)
|
44
|
+
separator = sibling_flags[-1] ? ",\n" : "\n"
|
45
|
+
name = nonterm_node.symbol.name
|
46
|
+
print_text(separator, "{ \"#{name}\": ")
|
47
|
+
sibling_flags[-1] = true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
51
|
+
# Notification of a visit event: the visitor is about to visit
|
52
|
+
# the children of a non-terminal node
|
53
|
+
# @param _parent [NonTerminalNode]
|
54
|
+
# @param _children [Array] array of children nodes
|
55
|
+
def before_children(_parent, _children)
|
56
|
+
print_text('[', nil)
|
57
|
+
indent
|
58
|
+
sibling_flags.push(false)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
62
|
+
# Notification of a visit event: the visitor is about to visit
|
63
|
+
# a terminal node
|
64
|
+
# @param _term [TerminalNode]
|
65
|
+
def before_terminal(term_node)
|
66
|
+
separator = sibling_flags[-1] ? ",\n" : "\n"
|
67
|
+
name = term_node.symbol.name
|
68
|
+
lexeme = term_node.token.lexeme
|
69
|
+
print_text(separator, "{\"#{name}\": \"#{lexeme}\"}")
|
70
|
+
sibling_flags[-1] = true
|
71
|
+
end
|
72
|
+
|
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
|
+
# the children of a non-terminal node.
|
77
|
+
# @param _parent [NonTerminalNode]
|
78
|
+
# @param _children [Array] array of children nodes
|
79
|
+
def after_children(_parent, _children)
|
80
|
+
sibling_flags.pop
|
81
|
+
print_text("\n", ']')
|
82
|
+
dedent
|
83
|
+
print_text("\n", '}')
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
88
|
+
# Notification of a visit event: the visitor completed the visit of
|
89
|
+
# a non-terminal node
|
90
|
+
# @param _nonterm [NonTerminalNode]
|
91
|
+
def after_non_terminal(_)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# Method called by a ParseTreeVisitor to which the formatter subscribed.
|
96
|
+
# Notification of a visit event: the visitor completed the visit
|
97
|
+
# of the given parse tree
|
98
|
+
# @param _ptree [ParseTree]
|
99
|
+
def after_ptree(_ptree)
|
100
|
+
dedent
|
101
|
+
#print_text("\n", ']')
|
102
|
+
dedent
|
103
|
+
print_text("\n", '}')
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def indent()
|
109
|
+
@indentation += 1
|
110
|
+
end
|
111
|
+
|
112
|
+
def dedent()
|
113
|
+
@indentation -= 1
|
114
|
+
end
|
115
|
+
|
116
|
+
def print_text(aSeparator, aText)
|
117
|
+
output.print aSeparator
|
118
|
+
output.print "#{' ' * 2 * @indentation}#{aText}" unless aText.nil?
|
119
|
+
end
|
120
|
+
|
121
|
+
end # class
|
122
|
+
end # module
|
123
|
+
end # module
|
124
|
+
|
125
|
+
# End of file
|
data/lib/rley/parser/parsing.rb
CHANGED
@@ -57,6 +57,10 @@ module Rley # This module is used as a namespace
|
|
57
57
|
ptree.current_node.range = { low: parse_state.origin }
|
58
58
|
node_range = ptree.current_node.range
|
59
59
|
ptree.add_children(curr_dotted_item.production, node_range)
|
60
|
+
if ptree.current_node.is_a?(PTree::TerminalNode)
|
61
|
+
curr_node = ptree.current_node
|
62
|
+
curr_node.token = tokens[state_set_index-1] unless curr_node.token
|
63
|
+
end
|
60
64
|
|
61
65
|
when NilClass
|
62
66
|
lhs = curr_dotted_item.production.lhs
|
@@ -70,7 +74,6 @@ module Rley # This module is used as a namespace
|
|
70
74
|
break if ptree.root == ptree.current_node
|
71
75
|
end
|
72
76
|
end
|
73
|
-
|
74
77
|
return ptree
|
75
78
|
end
|
76
79
|
|
@@ -149,11 +152,6 @@ module Rley # This module is used as a namespace
|
|
149
152
|
candidate_states = last_chart_entry.states_for(start_production)
|
150
153
|
return candidate_states.find(&:complete?)
|
151
154
|
end
|
152
|
-
|
153
|
-
# Complete the generated parse tree.
|
154
|
-
# Link each terminal node to its corresponding token object.
|
155
|
-
def complete_ptree()
|
156
|
-
end
|
157
155
|
end # class
|
158
156
|
end # module
|
159
157
|
end # module
|
@@ -4,7 +4,7 @@ module Rley # This module is used as a namespace
|
|
4
4
|
module PTree # This module is used as a namespace
|
5
5
|
class TerminalNode < ParseTreeNode
|
6
6
|
# Link to the input token
|
7
|
-
|
7
|
+
attr(:token, true)
|
8
8
|
|
9
9
|
def initialize(aTerminalSymbol, aRange)
|
10
10
|
super(aTerminalSymbol, aRange)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
2
|
require 'stringio'
|
3
3
|
|
4
|
-
# require_relative '../../../lib/rley/dynamic_grammar'
|
5
4
|
require_relative '../support/grammar_abc_helper'
|
6
5
|
require_relative '../../../lib/rley/parser/token'
|
7
6
|
require_relative '../../../lib/rley/parser/earley_parser'
|
@@ -0,0 +1,112 @@
|
|
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/json'
|
12
|
+
|
13
|
+
module Rley # Re-open the module to get rid of qualified names
|
14
|
+
module Formatter
|
15
|
+
|
16
|
+
describe Json 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 { Json.new(StringIO.new('', 'w')) }.not_to raise_error
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should know its output destination' do
|
70
|
+
instance = Json.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 render a parse tree in JSON' do
|
79
|
+
instance = Json.new(destination)
|
80
|
+
visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
|
81
|
+
instance.render(visitor)
|
82
|
+
expectations = <<-SNIPPET
|
83
|
+
{
|
84
|
+
"root":
|
85
|
+
{ "S": [
|
86
|
+
{ "A": [
|
87
|
+
{"a": "a"},
|
88
|
+
{ "A": [
|
89
|
+
{"a": "a"},
|
90
|
+
{ "A": [
|
91
|
+
{"b": "b"}
|
92
|
+
]
|
93
|
+
},
|
94
|
+
{"c": "c"}
|
95
|
+
]
|
96
|
+
},
|
97
|
+
{"c": "c"}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
]
|
101
|
+
}
|
102
|
+
}
|
103
|
+
SNIPPET
|
104
|
+
expect(destination.string).to eq(expectations.chomp)
|
105
|
+
end
|
106
|
+
end # context
|
107
|
+
end # describe
|
108
|
+
|
109
|
+
end # module
|
110
|
+
end # module
|
111
|
+
|
112
|
+
# End of file
|
@@ -1,18 +1,17 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative '../support/grammar_abc_helper'
|
4
|
+
|
4
5
|
# Load the class under test
|
5
6
|
require_relative '../../../lib/rley/ptree/parse_tree'
|
6
7
|
|
7
8
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
8
9
|
module PTree # Open this namespace to avoid module qualifier prefixes
|
9
10
|
describe ParseTree do
|
11
|
+
include GrammarABCHelper # Mix-in module with builder for grammar abc
|
12
|
+
|
10
13
|
let(:sample_grammar) do
|
11
|
-
builder =
|
12
|
-
builder.add_terminals('a', 'b', 'c')
|
13
|
-
builder.add_production('S' => ['A'])
|
14
|
-
builder.add_production('A' => %w(a A c))
|
15
|
-
builder.add_production('A' => ['b'])
|
14
|
+
builder = grammar_abc_builder
|
16
15
|
builder.grammar
|
17
16
|
end
|
18
17
|
|
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.06
|
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-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/rley/constants.rb
|
92
92
|
- lib/rley/formatter/base_formatter.rb
|
93
93
|
- lib/rley/formatter/debug.rb
|
94
|
+
- lib/rley/formatter/json.rb
|
94
95
|
- lib/rley/parser/chart.rb
|
95
96
|
- lib/rley/parser/dotted_item.rb
|
96
97
|
- lib/rley/parser/earley_parser.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- lib/rley/syntax/terminal.rb
|
115
116
|
- lib/rley/syntax/verbatim_symbol.rb
|
116
117
|
- spec/rley/formatter/debug_spec.rb
|
118
|
+
- spec/rley/formatter/json_spec.rb
|
117
119
|
- spec/rley/parser/chart_spec.rb
|
118
120
|
- spec/rley/parser/dotted_item_spec.rb
|
119
121
|
- spec/rley/parser/earley_parser_spec.rb
|
@@ -170,6 +172,7 @@ specification_version: 4
|
|
170
172
|
summary: Ruby implementation of the Earley's parsing algorithm
|
171
173
|
test_files:
|
172
174
|
- spec/rley/formatter/debug_spec.rb
|
175
|
+
- spec/rley/formatter/json_spec.rb
|
173
176
|
- spec/rley/parser/chart_spec.rb
|
174
177
|
- spec/rley/parser/dotted_item_spec.rb
|
175
178
|
- spec/rley/parser/earley_parser_spec.rb
|