dhaka 0.0.4 → 0.0.5
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.
- data/lib/grammar/precedence.rb +4 -0
- data/lib/grammar/production.rb +7 -4
- data/lib/parser/item.rb +6 -2
- data/lib/parser/parser.rb +5 -5
- data/lib/parser/parser_state.rb +2 -2
- data/test/all_tests.rb +2 -1
- data/test/another_lalr_but_not_slr_grammar.rb +16 -0
- data/test/arithmetic_evaluator_test.rb +6 -7
- data/test/arithmetic_precedence_evaluator.rb +4 -0
- data/test/arithmetic_precedence_grammar.rb +2 -0
- data/test/arithmetic_precedence_grammar_test.rb +3 -0
- data/test/arithmetic_precedence_parser_test.rb +20 -17
- data/test/arithmetic_precedence_tokenizer.rb +43 -0
- data/test/arithmetic_test_methods.rb +1 -1
- data/test/compiled_parser_test.rb +6 -6
- data/test/fake_logger.rb +17 -0
- data/test/parser_test.rb +12 -1
- data/test/precedence_grammar.rb +17 -0
- data/test/precedence_grammar_test.rb +10 -0
- metadata +7 -3
- data/test/compiled_arithmetic_parser.rb +0 -243
data/lib/grammar/precedence.rb
CHANGED
data/lib/grammar/production.rb
CHANGED
@@ -2,15 +2,17 @@
|
|
2
2
|
module Dhaka
|
3
3
|
class Production
|
4
4
|
|
5
|
-
attr_reader :symbol, :expansion, :name
|
5
|
+
attr_reader :symbol, :expansion, :name
|
6
6
|
|
7
7
|
def initialize(symbol, expansion, name, precedence = nil)
|
8
8
|
@symbol = symbol
|
9
9
|
@expansion = expansion
|
10
10
|
@name = name
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
@precedence = precedence
|
12
|
+
end
|
13
|
+
|
14
|
+
def precedence
|
15
|
+
unless @precedence
|
14
16
|
@expansion.reverse_each do |symbol|
|
15
17
|
if symbol.terminal
|
16
18
|
@precedence = symbol.precedence
|
@@ -18,6 +20,7 @@ module Dhaka
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
23
|
+
@precedence
|
21
24
|
end
|
22
25
|
|
23
26
|
def to_s
|
data/lib/parser/item.rb
CHANGED
@@ -17,7 +17,7 @@ module Dhaka
|
|
17
17
|
def next_item
|
18
18
|
Item.new(@production, @next_item_index+1)
|
19
19
|
end
|
20
|
-
def to_s
|
20
|
+
def to_s(options = {})
|
21
21
|
expansion_symbols = @production.expansion.collect {|symbol| symbol.name}
|
22
22
|
if @next_item_index < expansion_symbols.size
|
23
23
|
expansion_symbols.insert(@next_item_index, '->')
|
@@ -25,7 +25,11 @@ module Dhaka
|
|
25
25
|
expansion_symbols << '->'
|
26
26
|
end
|
27
27
|
expansion_repr = expansion_symbols.join(' ')
|
28
|
-
|
28
|
+
if options[:hide_lookaheads]
|
29
|
+
"#{@production.symbol} ::= #{expansion_repr}"
|
30
|
+
else
|
31
|
+
"#{@production.symbol} ::= #{expansion_repr} [#{@lookaheadset.collect.sort}]"
|
32
|
+
end
|
29
33
|
end
|
30
34
|
def eql?(other)
|
31
35
|
@production == other.production && @next_item_index==other.next_item_index
|
data/lib/parser/parser.rb
CHANGED
@@ -59,9 +59,9 @@ module Dhaka
|
|
59
59
|
result
|
60
60
|
end
|
61
61
|
|
62
|
-
def to_dot
|
62
|
+
def to_dot(options = {})
|
63
63
|
result = ["digraph x {", "node [fontsize=\"10\" shape=box size=\"5\"]"]
|
64
|
-
result += states.collect { |state| state.to_dot }
|
64
|
+
result += states.collect { |state| state.to_dot(options) }
|
65
65
|
states.each { |state|
|
66
66
|
@transitions[state].each { |symbol, dest_state|
|
67
67
|
result << "#{state.dot_name} -> #{dest_state.dot_name} [label=\"#{symbol.name}\"]"
|
@@ -95,7 +95,7 @@ module Dhaka
|
|
95
95
|
new_action = ReduceAction.new(item.production)
|
96
96
|
if existing_action = state.actions[lookahead.name]
|
97
97
|
if ReduceAction === existing_action
|
98
|
-
|
98
|
+
@logger.error(build_conflict_message(state, lookahead, new_action).join("\n"))
|
99
99
|
else
|
100
100
|
resolve_conflict state, lookahead, new_action
|
101
101
|
end
|
@@ -125,7 +125,7 @@ module Dhaka
|
|
125
125
|
message << "Resolving with right associativity. Choosing shift over reduce."
|
126
126
|
when :nonassoc
|
127
127
|
message << "Resolving with non-associativity. Eliminating action."
|
128
|
-
state.actions
|
128
|
+
state.actions.delete(lookahead.name)
|
129
129
|
end
|
130
130
|
end
|
131
131
|
else
|
@@ -135,7 +135,7 @@ module Dhaka
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def build_conflict_message state, lookahead, new_action
|
138
|
-
message = ["Parser Conflict at State:"] + state.items.values.collect{|it| it.to_s}
|
138
|
+
message = ["Parser Conflict at State:"] + state.items.values.collect{|it| it.to_s(:hide_lookaheads => true)}
|
139
139
|
message << "Existing: #{state.actions[lookahead.name]}"
|
140
140
|
message << "New: #{new_action}"
|
141
141
|
message << "Lookahead: #{lookahead}"
|
data/lib/parser/parser_state.rb
CHANGED
@@ -32,8 +32,8 @@ module Dhaka
|
|
32
32
|
self.to_s
|
33
33
|
end
|
34
34
|
|
35
|
-
def to_dot
|
36
|
-
label = self.items.values.join('\n')
|
35
|
+
def to_dot(options = {})
|
36
|
+
label = self.items.values.collect{|item| item.to_s(options)}.join('\n')
|
37
37
|
"#{dot_name} [label=\"#{label}\"]"
|
38
38
|
end
|
39
39
|
def compile_to_ruby_source
|
data/test/all_tests.rb
CHANGED
@@ -10,4 +10,5 @@ require 'arithmetic_tokenizer_test'
|
|
10
10
|
require 'malformed_grammar_test'
|
11
11
|
require 'brackets_test'
|
12
12
|
require 'arithmetic_precedence_grammar_test'
|
13
|
-
require 'arithmetic_precedence_parser_test'
|
13
|
+
require 'arithmetic_precedence_parser_test'
|
14
|
+
require 'precedence_grammar_test'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../lib/dhaka'
|
2
|
+
|
3
|
+
class AnotherLALRButNotSLRGrammar < Dhaka::Grammar
|
4
|
+
for_symbol(Dhaka::START_SYMBOL_NAME) do
|
5
|
+
assignment ['L', '=', 'R']
|
6
|
+
rhs ['R']
|
7
|
+
end
|
8
|
+
for_symbol('L') do
|
9
|
+
contents ['*', 'R']
|
10
|
+
identifier ['id']
|
11
|
+
end
|
12
|
+
for_symbol('R') do
|
13
|
+
l_value ['L']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
|
-
require 'compiled_arithmetic_parser'
|
3
2
|
require 'arithmetic_evaluator'
|
4
3
|
require 'arithmetic_test_methods'
|
5
|
-
|
4
|
+
eval(Dhaka::Parser.new(ArithmeticGrammar).compile_to_ruby_source_as(:CompiledArithmeticParser))
|
6
5
|
class TestArithmeticEvaluator < Test::Unit::TestCase
|
7
6
|
include ArithmeticTestMethods
|
8
7
|
|
@@ -15,7 +14,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
15
14
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_1
|
16
15
|
|
17
16
|
token_stream = [token('n', 2), token('-', nil), token('n', 4)]
|
18
|
-
syntax_tree =
|
17
|
+
syntax_tree = parse(token_stream)
|
19
18
|
assert_equal -2, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
20
19
|
|
21
20
|
end
|
@@ -23,7 +22,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
23
22
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_2
|
24
23
|
|
25
24
|
token_stream = [token('n', 2), token('-', nil), token('(', nil), token('n', 3), token('/', nil), token('n', 4), token(')', nil)]
|
26
|
-
syntax_tree =
|
25
|
+
syntax_tree = parse(token_stream)
|
27
26
|
assert_equal 1.25, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
28
27
|
|
29
28
|
end
|
@@ -31,7 +30,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
31
30
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_3
|
32
31
|
|
33
32
|
token_stream = [token('n', 2), token('+', nil), token('(', nil), token('n', 3), token('/', nil), token('(', nil), token('n', 7), token('-', nil), token('n', 5), token(')', nil) , token(')', nil)]
|
34
|
-
syntax_tree =
|
33
|
+
syntax_tree = parse(token_stream)
|
35
34
|
assert_equal 3.5, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
36
35
|
|
37
36
|
end
|
@@ -39,7 +38,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
39
38
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_4
|
40
39
|
|
41
40
|
token_stream = [token('n', 2), token('+', nil), token('h', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)]
|
42
|
-
syntax_tree =
|
41
|
+
syntax_tree = parse(token_stream)
|
43
42
|
assert_equal 6, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
44
43
|
|
45
44
|
end
|
@@ -47,7 +46,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
47
46
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_5
|
48
47
|
|
49
48
|
token_stream = [token('n', 2), token('+', nil), token('l', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)]
|
50
|
-
syntax_tree =
|
49
|
+
syntax_tree = parse(token_stream)
|
51
50
|
assert_equal 5, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
52
51
|
|
53
52
|
end
|
@@ -4,6 +4,7 @@ class ArithmeticPrecedenceGrammar < Dhaka::Grammar
|
|
4
4
|
precedences do
|
5
5
|
left ['+', '-']
|
6
6
|
left ['*', '/']
|
7
|
+
nonassoc ['^']
|
7
8
|
end
|
8
9
|
|
9
10
|
for_symbol(Dhaka::START_SYMBOL_NAME) do
|
@@ -15,6 +16,7 @@ class ArithmeticPrecedenceGrammar < Dhaka::Grammar
|
|
15
16
|
subtraction ['E', '-', 'E']
|
16
17
|
multiplication ['E', '*', 'E']
|
17
18
|
division ['E', '/', 'E']
|
19
|
+
power ['E', '^', 'E']
|
18
20
|
literal ['n']
|
19
21
|
parenthetized_expression ['(', 'E', ')']
|
20
22
|
negated_expression ['-', 'E'], :prec => '*'
|
@@ -8,6 +8,7 @@ class TestArithmeticPrecedenceGrammar < Test::Unit::TestCase
|
|
8
8
|
@subop = ArithmeticPrecedenceGrammar.symbol_for_name('-')
|
9
9
|
@mulop = ArithmeticPrecedenceGrammar.symbol_for_name('*')
|
10
10
|
@divop = ArithmeticPrecedenceGrammar.symbol_for_name('/')
|
11
|
+
@powop = ArithmeticPrecedenceGrammar.symbol_for_name('^')
|
11
12
|
end
|
12
13
|
|
13
14
|
def test_precedence_levels_and_associativity_of_terminals
|
@@ -15,10 +16,12 @@ class TestArithmeticPrecedenceGrammar < Test::Unit::TestCase
|
|
15
16
|
assert_equal(0, @subop.precedence.precedence_level)
|
16
17
|
assert_equal(1, @mulop.precedence.precedence_level)
|
17
18
|
assert_equal(1, @divop.precedence.precedence_level)
|
19
|
+
assert_equal(2, @powop.precedence.precedence_level)
|
18
20
|
assert_equal(:left, @addop.precedence.associativity)
|
19
21
|
assert_equal(:left, @subop.precedence.associativity)
|
20
22
|
assert_equal(:left, @mulop.precedence.associativity)
|
21
23
|
assert_equal(:left, @divop.precedence.associativity)
|
24
|
+
assert_equal(:nonassoc, @powop.precedence.associativity)
|
22
25
|
end
|
23
26
|
def test_precedence_of_production
|
24
27
|
assert_equal(@addop.precedence, ArithmeticPrecedenceGrammar.production_named("addition").precedence)
|
@@ -1,30 +1,33 @@
|
|
1
1
|
require "test/unit"
|
2
2
|
require "arithmetic_precedence_grammar"
|
3
|
-
require "
|
3
|
+
require "arithmetic_precedence_tokenizer"
|
4
4
|
require "arithmetic_precedence_evaluator"
|
5
|
+
require "fake_logger"
|
5
6
|
|
6
7
|
class TestArithmeticPrecedenceParser < Test::Unit::TestCase
|
7
8
|
|
8
9
|
def test_parses_arithmetic_expressions
|
9
10
|
fake_logger = FakeLogger.new
|
10
11
|
parser = Dhaka::Parser.new(ArithmeticPrecedenceGrammar, fake_logger)
|
11
|
-
|
12
|
+
eval(parser.compile_to_ruby_source_as(:ArithmeticPrecedenceParser))
|
13
|
+
assert_equal(30, fake_logger.warnings.size)
|
14
|
+
assert_equal(0, fake_logger.errors.size)
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
assert_equal(
|
16
|
+
assert_equal(-8, evaluate(parse("5 * -14/(2*7 - 7) + 2").syntax_tree))
|
17
|
+
assert_equal(-4, evaluate(parse("-2^2").syntax_tree))
|
18
|
+
assert_equal(10, evaluate(parse("2+2^3").syntax_tree))
|
19
|
+
assert_equal(64, evaluate(parse("(2+2)^3").syntax_tree))
|
20
|
+
assert_equal(128, evaluate(parse("(2+2)^3*2").syntax_tree))
|
21
|
+
assert(parse("(2+2)^3^2").has_error?)
|
17
22
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
attr_reader :messages
|
22
|
-
def initialize
|
23
|
-
@messages = []
|
23
|
+
|
24
|
+
def parse(input)
|
25
|
+
ArithmeticPrecedenceParser.parse(ArithmeticPrecedenceTokenizer.tokenize(input))
|
24
26
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@messages << message
|
27
|
+
|
28
|
+
def evaluate(syntax_tree)
|
29
|
+
ArithmeticPrecedenceEvaluator.new(syntax_tree).result
|
29
30
|
end
|
30
|
-
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../lib/dhaka'
|
2
|
+
require 'arithmetic_precedence_grammar'
|
3
|
+
|
4
|
+
|
5
|
+
class ArithmeticPrecedenceTokenizer < Dhaka::Tokenizer
|
6
|
+
|
7
|
+
digits = ('0'..'9').to_a
|
8
|
+
parenths = ['(', ')']
|
9
|
+
operators = ['-', '+', '/', '*', '^']
|
10
|
+
functions = ['h', 'l']
|
11
|
+
arg_separator = [',']
|
12
|
+
whitespace = [' ']
|
13
|
+
|
14
|
+
all_characters = digits + parenths + operators + functions + arg_separator + whitespace
|
15
|
+
|
16
|
+
for_state :idle_state do
|
17
|
+
for_characters(all_characters - (digits + whitespace)) do
|
18
|
+
tokens << Dhaka::Token.new(ArithmeticPrecedenceGrammar.symbol_for_name(curr_char), nil)
|
19
|
+
advance
|
20
|
+
end
|
21
|
+
for_characters digits do
|
22
|
+
self.accumulator = ''
|
23
|
+
switch_to :get_integer_literal
|
24
|
+
end
|
25
|
+
for_character whitespace do
|
26
|
+
advance
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
for_state :get_integer_literal do
|
31
|
+
for_characters all_characters - digits do
|
32
|
+
tokens << Dhaka::Token.new(ArithmeticPrecedenceGrammar.symbol_for_name('n'), accumulator.to_i)
|
33
|
+
switch_to :idle_state
|
34
|
+
end
|
35
|
+
for_characters digits do
|
36
|
+
self.accumulator += curr_char
|
37
|
+
advance
|
38
|
+
tokens << Dhaka::Token.new(ArithmeticPrecedenceGrammar.symbol_for_name('n'), accumulator.to_i) unless curr_char
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -1,15 +1,15 @@
|
|
1
1
|
require "test/unit"
|
2
2
|
require "simple_grammar"
|
3
|
-
require 'compiled_arithmetic_parser'
|
4
3
|
require 'arithmetic_test_methods'
|
4
|
+
require 'arithmetic_grammar'
|
5
|
+
|
6
|
+
eval(Dhaka::Parser.new(SimpleGrammar).compile_to_ruby_source_as('Foo'))
|
7
|
+
eval(Dhaka::Parser.new(ArithmeticGrammar).compile_to_ruby_source_as('CompiledArithmeticParser'))
|
5
8
|
|
6
9
|
class TestCompiledParser < Test::Unit::TestCase
|
7
10
|
include ArithmeticTestMethods
|
8
|
-
|
11
|
+
|
9
12
|
def test_compiled_parser_generates_syntax_tree_for_simple_grammar
|
10
|
-
grammar = SimpleGrammar
|
11
|
-
parser = Dhaka::Parser.new(grammar)
|
12
|
-
eval(parser.compile_to_ruby_source_as('Foo'))
|
13
13
|
syntax_tree = Foo.parse(build_tokens(['(','n','-','(','n','-','n',')',')','-','n','#'], Foo.grammar)).syntax_tree
|
14
14
|
assert_equal \
|
15
15
|
["literal",
|
@@ -50,7 +50,7 @@ class TestCompiledParser < Test::Unit::TestCase
|
|
50
50
|
"unpacking_parenthetized_expression",
|
51
51
|
"factor",
|
52
52
|
"term",
|
53
|
-
"expression"],
|
53
|
+
"expression"], parse(build_tokens(parser_input, CompiledArithmeticParser.grammar)).linearize
|
54
54
|
end
|
55
55
|
|
56
56
|
def test_parse_result_has_error_if_empty_token_array
|
data/test/fake_logger.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class FakeLogger
|
2
|
+
attr_reader :warnings, :debugs, :errors
|
3
|
+
def initialize
|
4
|
+
@warnings = []
|
5
|
+
@debugs = []
|
6
|
+
@errors = []
|
7
|
+
end
|
8
|
+
def debug message
|
9
|
+
@debugs << message
|
10
|
+
end
|
11
|
+
def error message
|
12
|
+
@errors << message
|
13
|
+
end
|
14
|
+
def warn message
|
15
|
+
@warnings << message
|
16
|
+
end
|
17
|
+
end
|
data/test/parser_test.rb
CHANGED
@@ -4,8 +4,10 @@ require 'simple_grammar'
|
|
4
4
|
require 'arithmetic_grammar'
|
5
5
|
require 'nullable_grammar'
|
6
6
|
require 'lalr_but_not_slr_grammar'
|
7
|
+
require 'another_lalr_but_not_slr_grammar'
|
7
8
|
require 'rr_conflict_grammar'
|
8
9
|
require 'sr_conflict_grammar'
|
10
|
+
require 'fake_logger'
|
9
11
|
|
10
12
|
class ParserTest < Test::Unit::TestCase
|
11
13
|
|
@@ -142,9 +144,18 @@ class ParserTest < Test::Unit::TestCase
|
|
142
144
|
assert_equal(["A_d", "E_bAc", "start"], get_linearized_parse_result(parser_input, parser))
|
143
145
|
end
|
144
146
|
|
147
|
+
def test_with_another_grammar_that_is_not_SLR
|
148
|
+
grammar = AnotherLALRButNotSLRGrammar
|
149
|
+
parser = Dhaka::Parser.new(grammar)
|
150
|
+
parser_input = ['*', 'id', '=', 'id']
|
151
|
+
assert_equal(["identifier", "l_value", "contents", "identifier", "l_value", "assignment"], get_linearized_parse_result(parser_input, parser))
|
152
|
+
end
|
153
|
+
|
145
154
|
def test_with_a_grammar_that_should_generate_an_RR_conflict
|
146
155
|
grammar = RRConflictGrammar
|
147
|
-
|
156
|
+
fake_logger = FakeLogger.new
|
157
|
+
Dhaka::Parser.new(grammar, fake_logger)
|
158
|
+
assert_equal(1, fake_logger.errors.size)
|
148
159
|
end
|
149
160
|
|
150
161
|
def set_finder(set1, set2)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/../lib/dhaka'
|
2
|
+
|
3
|
+
class PrecedenceGrammar < Dhaka::Grammar
|
4
|
+
precedences do
|
5
|
+
left ['*']
|
6
|
+
end
|
7
|
+
|
8
|
+
for_symbol(Dhaka::START_SYMBOL_NAME) do
|
9
|
+
expression ['E', '*', 'F']
|
10
|
+
whatever ['E', 'F'], :prec => '*'
|
11
|
+
end
|
12
|
+
|
13
|
+
for_symbol('F') do
|
14
|
+
something ['foo']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
require "precedence_grammar"
|
4
|
+
|
5
|
+
class TestPrecedenceGrammar < Test::Unit::TestCase
|
6
|
+
def test_precedences_are_computed_correctly
|
7
|
+
assert_equal(:left, PrecedenceGrammar.production_named('expression').precedence.associativity)
|
8
|
+
assert_equal(:left, PrecedenceGrammar.production_named('whatever').precedence.associativity)
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: dhaka
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2006-12-
|
6
|
+
version: 0.0.5
|
7
|
+
date: 2006-12-15 00:00:00 -05:00
|
8
8
|
summary: An LALR1 parser generator written in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- lib/parser/token.rb
|
50
50
|
- lib/tokenizer/tokenizer.rb
|
51
51
|
- test/all_tests.rb
|
52
|
+
- test/another_lalr_but_not_slr_grammar.rb
|
52
53
|
- test/arithmetic_evaluator.rb
|
53
54
|
- test/arithmetic_evaluator_test.rb
|
54
55
|
- test/arithmetic_grammar.rb
|
@@ -57,15 +58,16 @@ files:
|
|
57
58
|
- test/arithmetic_precedence_grammar.rb
|
58
59
|
- test/arithmetic_precedence_grammar_test.rb
|
59
60
|
- test/arithmetic_precedence_parser_test.rb
|
61
|
+
- test/arithmetic_precedence_tokenizer.rb
|
60
62
|
- test/arithmetic_test_methods.rb
|
61
63
|
- test/arithmetic_tokenizer.rb
|
62
64
|
- test/arithmetic_tokenizer_test.rb
|
63
65
|
- test/bracket_grammar.rb
|
64
66
|
- test/bracket_tokenizer.rb
|
65
67
|
- test/brackets_test.rb
|
66
|
-
- test/compiled_arithmetic_parser.rb
|
67
68
|
- test/compiled_parser_test.rb
|
68
69
|
- test/evaluator_test.rb
|
70
|
+
- test/fake_logger.rb
|
69
71
|
- test/grammar_test.rb
|
70
72
|
- test/incomplete_arithmetic_evaluator.rb
|
71
73
|
- test/lalr_but_not_slr_grammar.rb
|
@@ -73,6 +75,8 @@ files:
|
|
73
75
|
- test/malformed_grammar_test.rb
|
74
76
|
- test/nullable_grammar.rb
|
75
77
|
- test/parser_test.rb
|
78
|
+
- test/precedence_grammar.rb
|
79
|
+
- test/precedence_grammar_test.rb
|
76
80
|
- test/rr_conflict_grammar.rb
|
77
81
|
- test/simple_grammar.rb
|
78
82
|
- test/sr_conflict_grammar.rb
|
@@ -1,243 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__)+'/../lib/dhaka'
|
2
|
-
require 'arithmetic_grammar'
|
3
|
-
|
4
|
-
class CompiledArithmeticParser < Dhaka::CompiledParser
|
5
|
-
|
6
|
-
self.grammar = ArithmeticGrammar
|
7
|
-
|
8
|
-
start_with 11
|
9
|
-
|
10
|
-
at_state(21) {
|
11
|
-
for_symbol('l') { shift_to 16 }
|
12
|
-
for_symbol('FunctionName') { shift_to 23 }
|
13
|
-
for_symbol('n') { shift_to 12 }
|
14
|
-
for_symbol('Function') { shift_to 31 }
|
15
|
-
for_symbol('F') { shift_to 22 }
|
16
|
-
for_symbol('(') { shift_to 17 }
|
17
|
-
for_symbol('h') { shift_to 13 }
|
18
|
-
}
|
19
|
-
|
20
|
-
at_state(28) {
|
21
|
-
for_symbol('l') { shift_to 16 }
|
22
|
-
for_symbol('FunctionName') { shift_to 23 }
|
23
|
-
for_symbol('n') { shift_to 12 }
|
24
|
-
for_symbol('E') { shift_to 27 }
|
25
|
-
for_symbol('Function') { shift_to 31 }
|
26
|
-
for_symbol('F') { shift_to 30 }
|
27
|
-
for_symbol('Args') { shift_to 29 }
|
28
|
-
for_symbol('(') { shift_to 17 }
|
29
|
-
for_symbol('h') { shift_to 13 }
|
30
|
-
for_symbol(')') { reduce_with 'empty_args' }
|
31
|
-
for_symbol('T') { shift_to 14 }
|
32
|
-
}
|
33
|
-
|
34
|
-
at_state(17) {
|
35
|
-
for_symbol('l') { shift_to 16 }
|
36
|
-
for_symbol('FunctionName') { shift_to 23 }
|
37
|
-
for_symbol('n') { shift_to 12 }
|
38
|
-
for_symbol('E') { shift_to 18 }
|
39
|
-
for_symbol('Function') { shift_to 31 }
|
40
|
-
for_symbol('F') { shift_to 30 }
|
41
|
-
for_symbol('(') { shift_to 17 }
|
42
|
-
for_symbol('h') { shift_to 13 }
|
43
|
-
for_symbol('T') { shift_to 14 }
|
44
|
-
}
|
45
|
-
|
46
|
-
at_state(23) {
|
47
|
-
for_symbol('(') { shift_to 24 }
|
48
|
-
}
|
49
|
-
|
50
|
-
at_state(16) {
|
51
|
-
for_symbol('(') { reduce_with 'min_function' }
|
52
|
-
}
|
53
|
-
|
54
|
-
at_state(13) {
|
55
|
-
for_symbol('(') { reduce_with 'max_function' }
|
56
|
-
}
|
57
|
-
|
58
|
-
at_state(20) {
|
59
|
-
for_symbol('+') { reduce_with 'addition' }
|
60
|
-
for_symbol(',') { reduce_with 'addition' }
|
61
|
-
for_symbol('-') { reduce_with 'addition' }
|
62
|
-
for_symbol('/') { shift_to 15 }
|
63
|
-
for_symbol('_End_') { reduce_with 'addition' }
|
64
|
-
for_symbol(')') { reduce_with 'addition' }
|
65
|
-
for_symbol('*') { shift_to 21 }
|
66
|
-
}
|
67
|
-
|
68
|
-
at_state(34) {
|
69
|
-
for_symbol('+') { reduce_with 'unpacking_parenthetized_expression' }
|
70
|
-
for_symbol(',') { reduce_with 'unpacking_parenthetized_expression' }
|
71
|
-
for_symbol('-') { reduce_with 'unpacking_parenthetized_expression' }
|
72
|
-
for_symbol('/') { reduce_with 'unpacking_parenthetized_expression' }
|
73
|
-
for_symbol('_End_') { reduce_with 'unpacking_parenthetized_expression' }
|
74
|
-
for_symbol(')') { reduce_with 'unpacking_parenthetized_expression' }
|
75
|
-
for_symbol('*') { reduce_with 'unpacking_parenthetized_expression' }
|
76
|
-
}
|
77
|
-
|
78
|
-
at_state(32) {
|
79
|
-
for_symbol('l') { shift_to 16 }
|
80
|
-
for_symbol('FunctionName') { shift_to 23 }
|
81
|
-
for_symbol('n') { shift_to 12 }
|
82
|
-
for_symbol('Function') { shift_to 31 }
|
83
|
-
for_symbol('F') { shift_to 30 }
|
84
|
-
for_symbol('(') { shift_to 17 }
|
85
|
-
for_symbol('h') { shift_to 13 }
|
86
|
-
for_symbol('T') { shift_to 33 }
|
87
|
-
}
|
88
|
-
|
89
|
-
at_state(15) {
|
90
|
-
for_symbol('l') { shift_to 16 }
|
91
|
-
for_symbol('FunctionName') { shift_to 23 }
|
92
|
-
for_symbol('n') { shift_to 12 }
|
93
|
-
for_symbol('Function') { shift_to 31 }
|
94
|
-
for_symbol('F') { shift_to 35 }
|
95
|
-
for_symbol('(') { shift_to 17 }
|
96
|
-
for_symbol('h') { shift_to 13 }
|
97
|
-
}
|
98
|
-
|
99
|
-
at_state(33) {
|
100
|
-
for_symbol('+') { reduce_with 'subtraction' }
|
101
|
-
for_symbol(',') { reduce_with 'subtraction' }
|
102
|
-
for_symbol('-') { reduce_with 'subtraction' }
|
103
|
-
for_symbol('/') { shift_to 15 }
|
104
|
-
for_symbol('_End_') { reduce_with 'subtraction' }
|
105
|
-
for_symbol(')') { reduce_with 'subtraction' }
|
106
|
-
for_symbol('*') { shift_to 21 }
|
107
|
-
}
|
108
|
-
|
109
|
-
at_state(24) {
|
110
|
-
for_symbol('l') { shift_to 16 }
|
111
|
-
for_symbol('FunctionName') { shift_to 23 }
|
112
|
-
for_symbol('n') { shift_to 12 }
|
113
|
-
for_symbol('E') { shift_to 27 }
|
114
|
-
for_symbol('Function') { shift_to 31 }
|
115
|
-
for_symbol('F') { shift_to 30 }
|
116
|
-
for_symbol('Args') { shift_to 25 }
|
117
|
-
for_symbol('(') { shift_to 17 }
|
118
|
-
for_symbol('h') { shift_to 13 }
|
119
|
-
for_symbol(')') { reduce_with 'empty_args' }
|
120
|
-
for_symbol('T') { shift_to 14 }
|
121
|
-
}
|
122
|
-
|
123
|
-
at_state(11) {
|
124
|
-
for_symbol('l') { shift_to 16 }
|
125
|
-
for_symbol('FunctionName') { shift_to 23 }
|
126
|
-
for_symbol('n') { shift_to 12 }
|
127
|
-
for_symbol('E') { shift_to 36 }
|
128
|
-
for_symbol('Function') { shift_to 31 }
|
129
|
-
for_symbol('F') { shift_to 30 }
|
130
|
-
for_symbol('(') { shift_to 17 }
|
131
|
-
for_symbol('h') { shift_to 13 }
|
132
|
-
for_symbol('T') { shift_to 14 }
|
133
|
-
}
|
134
|
-
|
135
|
-
at_state(35) {
|
136
|
-
for_symbol('+') { reduce_with 'division' }
|
137
|
-
for_symbol(',') { reduce_with 'division' }
|
138
|
-
for_symbol('-') { reduce_with 'division' }
|
139
|
-
for_symbol('/') { reduce_with 'division' }
|
140
|
-
for_symbol('_End_') { reduce_with 'division' }
|
141
|
-
for_symbol(')') { reduce_with 'division' }
|
142
|
-
for_symbol('*') { reduce_with 'division' }
|
143
|
-
}
|
144
|
-
|
145
|
-
at_state(31) {
|
146
|
-
for_symbol('+') { reduce_with 'function' }
|
147
|
-
for_symbol(',') { reduce_with 'function' }
|
148
|
-
for_symbol('-') { reduce_with 'function' }
|
149
|
-
for_symbol('/') { reduce_with 'function' }
|
150
|
-
for_symbol('_End_') { reduce_with 'function' }
|
151
|
-
for_symbol(')') { reduce_with 'function' }
|
152
|
-
for_symbol('*') { reduce_with 'function' }
|
153
|
-
}
|
154
|
-
|
155
|
-
at_state(26) {
|
156
|
-
for_symbol('+') { reduce_with 'evaluating_function' }
|
157
|
-
for_symbol(',') { reduce_with 'evaluating_function' }
|
158
|
-
for_symbol('-') { reduce_with 'evaluating_function' }
|
159
|
-
for_symbol('/') { reduce_with 'evaluating_function' }
|
160
|
-
for_symbol('_End_') { reduce_with 'evaluating_function' }
|
161
|
-
for_symbol(')') { reduce_with 'evaluating_function' }
|
162
|
-
for_symbol('*') { reduce_with 'evaluating_function' }
|
163
|
-
}
|
164
|
-
|
165
|
-
at_state(18) {
|
166
|
-
for_symbol('+') { shift_to 19 }
|
167
|
-
for_symbol('-') { shift_to 32 }
|
168
|
-
for_symbol(')') { shift_to 34 }
|
169
|
-
}
|
170
|
-
|
171
|
-
at_state(14) {
|
172
|
-
for_symbol('+') { reduce_with 'term' }
|
173
|
-
for_symbol(',') { reduce_with 'term' }
|
174
|
-
for_symbol('-') { reduce_with 'term' }
|
175
|
-
for_symbol('/') { shift_to 15 }
|
176
|
-
for_symbol('_End_') { reduce_with 'term' }
|
177
|
-
for_symbol(')') { reduce_with 'term' }
|
178
|
-
for_symbol('*') { shift_to 21 }
|
179
|
-
}
|
180
|
-
|
181
|
-
at_state(25) {
|
182
|
-
for_symbol(')') { shift_to 26 }
|
183
|
-
}
|
184
|
-
|
185
|
-
at_state(22) {
|
186
|
-
for_symbol('+') { reduce_with 'multiplication' }
|
187
|
-
for_symbol(',') { reduce_with 'multiplication' }
|
188
|
-
for_symbol('-') { reduce_with 'multiplication' }
|
189
|
-
for_symbol('/') { reduce_with 'multiplication' }
|
190
|
-
for_symbol('_End_') { reduce_with 'multiplication' }
|
191
|
-
for_symbol(')') { reduce_with 'multiplication' }
|
192
|
-
for_symbol('*') { reduce_with 'multiplication' }
|
193
|
-
}
|
194
|
-
|
195
|
-
at_state(12) {
|
196
|
-
for_symbol('+') { reduce_with 'getting_literals' }
|
197
|
-
for_symbol(',') { reduce_with 'getting_literals' }
|
198
|
-
for_symbol('-') { reduce_with 'getting_literals' }
|
199
|
-
for_symbol('/') { reduce_with 'getting_literals' }
|
200
|
-
for_symbol('_End_') { reduce_with 'getting_literals' }
|
201
|
-
for_symbol(')') { reduce_with 'getting_literals' }
|
202
|
-
for_symbol('*') { reduce_with 'getting_literals' }
|
203
|
-
}
|
204
|
-
|
205
|
-
at_state(36) {
|
206
|
-
for_symbol('+') { shift_to 19 }
|
207
|
-
for_symbol('-') { shift_to 32 }
|
208
|
-
for_symbol('_End_') { reduce_with 'expression' }
|
209
|
-
}
|
210
|
-
|
211
|
-
at_state(30) {
|
212
|
-
for_symbol('+') { reduce_with 'factor' }
|
213
|
-
for_symbol(',') { reduce_with 'factor' }
|
214
|
-
for_symbol('-') { reduce_with 'factor' }
|
215
|
-
for_symbol('/') { reduce_with 'factor' }
|
216
|
-
for_symbol('_End_') { reduce_with 'factor' }
|
217
|
-
for_symbol(')') { reduce_with 'factor' }
|
218
|
-
for_symbol('*') { reduce_with 'factor' }
|
219
|
-
}
|
220
|
-
|
221
|
-
at_state(29) {
|
222
|
-
for_symbol(')') { reduce_with 'concatenating_args' }
|
223
|
-
}
|
224
|
-
|
225
|
-
at_state(27) {
|
226
|
-
for_symbol('+') { shift_to 19 }
|
227
|
-
for_symbol(',') { shift_to 28 }
|
228
|
-
for_symbol('-') { shift_to 32 }
|
229
|
-
for_symbol(')') { reduce_with 'single_args' }
|
230
|
-
}
|
231
|
-
|
232
|
-
at_state(19) {
|
233
|
-
for_symbol('l') { shift_to 16 }
|
234
|
-
for_symbol('FunctionName') { shift_to 23 }
|
235
|
-
for_symbol('n') { shift_to 12 }
|
236
|
-
for_symbol('Function') { shift_to 31 }
|
237
|
-
for_symbol('F') { shift_to 30 }
|
238
|
-
for_symbol('(') { shift_to 17 }
|
239
|
-
for_symbol('h') { shift_to 13 }
|
240
|
-
for_symbol('T') { shift_to 20 }
|
241
|
-
}
|
242
|
-
|
243
|
-
end
|