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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTUxODY4MDAzOWE1NjFkYzc5NGFjYzNhZWIxMTRjMmY5NzA4Zjg3Yw==
4
+ YzFjODYyODc0MDUzODcwNDlmYWI0ODhkNTAxNDJjZmVlNTUwMTdiNg==
5
5
  data.tar.gz: !binary |-
6
- ZTRlN2M4ZjUyZDE2MTVkMzBlODdjNjdkZWFjMzk5NjI0ZDI1MjNkZA==
6
+ N2QxZWZlODFjNTBlMzM4NzgzMWMwYzY4YWUzZDI4MTk1ODAwZmY4Nw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MWE4NTFmODdjMjk3YTU0NjY5YTFmMmI3ZjRmYzNjMDdlYjYwN2FkOTE1YTc3
10
- ZmE1YjY2MTAwNGIwZTcyMThiOTQ5MjVjZWIzZDM4NTE3YzA4NWY5ZTMyM2Y2
11
- YTQ0YTdkZWE2YjVmYzA3MDE5MjJjNmM1YzE0YzUyMDY0NjBlNDc=
9
+ ZDI3YjJmMjA0Mzg1NjhhNWJhMWZjNGIyNjE5OTg2NGYwMzNhNmUwMDA4ODM5
10
+ ZWI2M2Q5NjAyMGIyODlkOTYxZTMyMjg3NjdkMjgzZDJlNjJmYmJiNTc3MDli
11
+ OTcyZWIwOWFjY2UzMzRlMDA1OWU5ZTlhMDc4MGE0Yzc2MmRmYzE=
12
12
  data.tar.gz: !binary |-
13
- YTFiMTNkZWVjYjVjYzNiMzg4N2E0ZDY0MWFkYWY5OWE0NGI1YjUyYTlkMjRj
14
- YTU2NWM0ZDIwYTE2YWU2MmVjOTg2OTRhZTU0Njk1YjNmNTA0NjVjNDIzNDI2
15
- NDkyMzBiYTc2MWI1ZmVhYTcyMjVkNzVjNTVjMTlmZjMyOTU5YjI=
13
+ NjMzOGViZTZmOTIwMTAwM2FjYTMyZjAyYjYzMmIyMjY0OTM4OTk0NDM3MzAw
14
+ YTEyNzE2NjA0OTA0NTVmZDRkYTJiNDAxMDY1NTE2NjlhM2M2YzNhZTA0OWIy
15
+ NWJkNTQ2M2RjMjAxZmUxMjQ3MmY5OGQ1ZmE2ZjMyYzUwMzhhNDA=
@@ -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.
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Rley # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.1.05'
6
+ Version = '0.1.06'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Ruby implementation of the Earley's parsing algorithm"
@@ -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
@@ -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
- attr_writer(:token)
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 '../../../lib/rley/syntax/grammar_builder'
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 = Syntax::GrammarBuilder.new
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.05
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-10 00:00:00.000000000 Z
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