dhaka 0.0.2 → 0.0.3
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/parser/parse_tree.rb +24 -0
- data/lib/parser/parser_methods.rb +1 -2
- data/lib/parser/parser_run.rb +19 -10
- data/test/arithmetic_evaluator.rb +0 -4
- data/test/arithmetic_evaluator_test.rb +5 -5
- data/test/arithmetic_grammar.rb +0 -3
- data/test/arithmetic_tokenizer.rb +2 -2
- data/test/arithmetic_tokenizer_test.rb +7 -7
- data/test/compiled_arithmetic_parser.rb +167 -176
- data/test/compiled_parser_test.rb +5 -6
- data/test/nullable_grammar.rb +1 -1
- data/test/parser_test.rb +5 -8
- metadata +2 -2
data/lib/parser/parse_tree.rb
CHANGED
@@ -11,6 +11,23 @@ module Dhaka
|
|
11
11
|
def to_s
|
12
12
|
"CompositeNode: #{production.symbol} --> [#{child_nodes.join(", ")}]"
|
13
13
|
end
|
14
|
+
def dot_name
|
15
|
+
"Node#{object_id}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_dot
|
19
|
+
result = []
|
20
|
+
result << ["digraph x {", "node [fontsize=\"10\" shape=box size=\"5\"]"] if head_node?
|
21
|
+
label = self.production
|
22
|
+
result << "#{dot_name} [label=\"#{label}\"]"
|
23
|
+
child_nodes.each do |child|
|
24
|
+
result << "#{dot_name} -> #{child.dot_name}"
|
25
|
+
result << "#{child.to_dot}"
|
26
|
+
end
|
27
|
+
result << ['}'] if head_node?
|
28
|
+
result.join("\n")
|
29
|
+
end
|
30
|
+
|
14
31
|
def head_node?
|
15
32
|
production.symbol.name == START_SYMBOL_NAME
|
16
33
|
end
|
@@ -27,6 +44,13 @@ module Dhaka
|
|
27
44
|
def to_s
|
28
45
|
"LeafNode: #{token}"
|
29
46
|
end
|
47
|
+
def dot_name
|
48
|
+
"Node#{object_id}"
|
49
|
+
end
|
50
|
+
def to_dot
|
51
|
+
label = "#{token}#{' : '+token.value.to_s if token.value}"
|
52
|
+
"#{dot_name} [label=\"#{label}\"]"
|
53
|
+
end
|
30
54
|
def head_node?
|
31
55
|
false
|
32
56
|
end
|
@@ -2,8 +2,7 @@
|
|
2
2
|
module Dhaka
|
3
3
|
module ParserMethods
|
4
4
|
def parse token_stream
|
5
|
-
|
6
|
-
parser_run = ParserRun.new(grammar, start_state, token_stream+[Token.new(@grammar.end_symbol, nil)])
|
5
|
+
parser_run = ParserRun.new(grammar, start_state, token_stream)
|
7
6
|
parser_run.run
|
8
7
|
end
|
9
8
|
end
|
data/lib/parser/parser_run.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Dhaka
|
2
2
|
class ParserRun
|
3
|
-
|
3
|
+
|
4
4
|
def initialize(grammar, start_state, token_stream)
|
5
5
|
@grammar = grammar
|
6
6
|
@node_stack = []
|
@@ -8,21 +8,29 @@ module Dhaka
|
|
8
8
|
@token_stream = token_stream
|
9
9
|
@current_token_index = 0
|
10
10
|
end
|
11
|
-
|
12
|
-
@token_stream[@current_token_index]
|
13
|
-
end
|
14
|
-
def advance
|
15
|
-
node_stack << ParseTreeLeafNode.new(current_token)
|
16
|
-
@current_token_index += 1
|
17
|
-
end
|
11
|
+
|
18
12
|
def run
|
19
|
-
|
13
|
+
for_each_token_with_end do
|
20
14
|
error = execute_action current_token.grammar_symbol.name
|
21
15
|
return error if error
|
22
|
-
|
16
|
+
node_stack << ParseTreeLeafNode.new(current_token)
|
17
|
+
@current_token_index += 1
|
23
18
|
end
|
24
19
|
ParseSuccessResult.new(node_stack[0])
|
25
20
|
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :state_stack, :token_stream, :node_stack, :current_token
|
25
|
+
|
26
|
+
def for_each_token_with_end
|
27
|
+
token_stream.each do |@current_token|
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
@current_token = Token.new(@grammar.end_symbol, nil)
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
|
26
34
|
def execute_action symbol_name
|
27
35
|
action = state_stack[-1].actions[symbol_name]
|
28
36
|
return ParseErrorResult.new(@current_token_index) unless action
|
@@ -31,5 +39,6 @@ module Dhaka
|
|
31
39
|
end
|
32
40
|
nil
|
33
41
|
end
|
42
|
+
|
34
43
|
end
|
35
44
|
end
|
@@ -14,7 +14,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_1
|
16
16
|
|
17
|
-
token_stream = [token('n', 2), token('-', nil), token('n', 4)
|
17
|
+
token_stream = [token('n', 2), token('-', nil), token('n', 4)]
|
18
18
|
syntax_tree = get_syntax_tree_with_compiled_arithmetic_parser(token_stream)
|
19
19
|
assert_equal -2, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
20
20
|
|
@@ -22,7 +22,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
22
22
|
|
23
23
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_2
|
24
24
|
|
25
|
-
token_stream = [token('n', 2), token('-', nil), token('(', nil), token('n', 3), token('/', nil), token('n', 4), token(')', nil)
|
25
|
+
token_stream = [token('n', 2), token('-', nil), token('(', nil), token('n', 3), token('/', nil), token('n', 4), token(')', nil)]
|
26
26
|
syntax_tree = get_syntax_tree_with_compiled_arithmetic_parser(token_stream)
|
27
27
|
assert_equal 1.25, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
28
28
|
|
@@ -30,7 +30,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
30
30
|
|
31
31
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_3
|
32
32
|
|
33
|
-
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)
|
33
|
+
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
34
|
syntax_tree = get_syntax_tree_with_compiled_arithmetic_parser(token_stream)
|
35
35
|
assert_equal 3.5, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
36
36
|
|
@@ -38,7 +38,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
38
38
|
|
39
39
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_4
|
40
40
|
|
41
|
-
token_stream = [token('n', 2), token('+', nil), token('h', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)
|
41
|
+
token_stream = [token('n', 2), token('+', nil), token('h', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)]
|
42
42
|
syntax_tree = get_syntax_tree_with_compiled_arithmetic_parser(token_stream)
|
43
43
|
assert_equal 6, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
44
44
|
|
@@ -46,7 +46,7 @@ class TestArithmeticEvaluator < Test::Unit::TestCase
|
|
46
46
|
|
47
47
|
def test_results_simple_arithmetic_given_tokens_and_syntax_tree_5
|
48
48
|
|
49
|
-
token_stream = [token('n', 2), token('+', nil), token('l', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)
|
49
|
+
token_stream = [token('n', 2), token('+', nil), token('l', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil)]
|
50
50
|
syntax_tree = get_syntax_tree_with_compiled_arithmetic_parser(token_stream)
|
51
51
|
assert_equal 5, ArithmeticEvaluator.new(syntax_tree, @min_func, @max_func).result
|
52
52
|
|
data/test/arithmetic_grammar.rb
CHANGED
@@ -9,10 +9,9 @@ class ArithmeticTokenizer < Dhaka::Tokenizer
|
|
9
9
|
operators = ['-', '+', '/', '*']
|
10
10
|
functions = ['h', 'l']
|
11
11
|
arg_separator = [',']
|
12
|
-
sentinel = ['#']
|
13
12
|
whitespace = [' ']
|
14
13
|
|
15
|
-
all_characters = digits + parenths + operators + functions + arg_separator +
|
14
|
+
all_characters = digits + parenths + operators + functions + arg_separator + whitespace
|
16
15
|
|
17
16
|
for_state :idle_state do
|
18
17
|
for_characters(all_characters - (digits + whitespace)) do
|
@@ -36,6 +35,7 @@ class ArithmeticTokenizer < Dhaka::Tokenizer
|
|
36
35
|
for_characters digits do
|
37
36
|
self.accumulator += curr_char
|
38
37
|
advance
|
38
|
+
tokens << Dhaka::Token.new(ArithmeticGrammar.symbol_for_name('n'), accumulator.to_i) unless curr_char
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -6,24 +6,24 @@ class TestArithmeticTokenizer < Test::Unit::TestCase
|
|
6
6
|
assert_equal([], ArithmeticTokenizer.tokenize([]))
|
7
7
|
end
|
8
8
|
def test_tokenizes_given_a_string_input
|
9
|
-
assert_equal([token('n', 2), token('-', nil), token('n', 4)
|
9
|
+
assert_equal([token('n', 2), token('-', nil), token('n', 4)], ArithmeticTokenizer.tokenize('2 - 4'))
|
10
10
|
end
|
11
11
|
def test_a_longer_input
|
12
|
-
actual = ArithmeticTokenizer.tokenize('2+(3 / (7 - 5))
|
13
|
-
assert_equal([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)
|
12
|
+
actual = ArithmeticTokenizer.tokenize('2+(3 / (7 - 5))')
|
13
|
+
assert_equal([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)], actual)
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_another_input_with_multi_digit_numbers
|
17
|
-
actual = ArithmeticTokenizer.tokenize('2034 +(3433 / (7 - 5))
|
18
|
-
assert_equal([token('n', 2034), token('+', nil), token('(', nil), token('n', 3433), token('/', nil), token('(', nil), token('n', 7), token('-', nil), token('n', 5), token(')', nil) , token(')', nil)
|
17
|
+
actual = ArithmeticTokenizer.tokenize('2034 +(3433 / (7 - 5))')
|
18
|
+
assert_equal([token('n', 2034), token('+', nil), token('(', nil), token('n', 3433), token('/', nil), token('(', nil), token('n', 7), token('-', nil), token('n', 5), token(')', nil) , token(')', nil)], actual)
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_an_input_with_unrecognized_characters
|
22
|
-
assert_raise(Dhaka::UnrecognizedInputCharacterException) {ArithmeticTokenizer.tokenize('2+(3 / (7 -& 5))
|
22
|
+
assert_raise(Dhaka::UnrecognizedInputCharacterException) {ArithmeticTokenizer.tokenize('2+(3 / (7 -& 5))')}
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_another_input_with_illegal_characters
|
26
|
-
assert_raise(Dhaka::UnrecognizedInputCharacterException) {ArithmeticTokenizer.tokenize('2034 +(34b3 / (7 - 5))
|
26
|
+
assert_raise(Dhaka::UnrecognizedInputCharacterException) {ArithmeticTokenizer.tokenize('2034 +(34b3 / (7 - 5))')}
|
27
27
|
end
|
28
28
|
|
29
29
|
def token(symbol_name, value)
|
@@ -5,248 +5,239 @@ class CompiledArithmeticParser < Dhaka::CompiledParser
|
|
5
5
|
|
6
6
|
self.grammar = ArithmeticGrammar
|
7
7
|
|
8
|
-
start_with
|
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
|
+
}
|
9
33
|
|
10
|
-
at_state(
|
11
|
-
for_symbol('l') { shift_to
|
12
|
-
for_symbol('
|
13
|
-
for_symbol('
|
14
|
-
for_symbol('
|
15
|
-
for_symbol('
|
16
|
-
for_symbol('
|
17
|
-
for_symbol('(') { shift_to
|
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 }
|
18
44
|
}
|
19
45
|
|
20
|
-
at_state(
|
21
|
-
for_symbol('
|
22
|
-
for_symbol(',') { reduce_with 'subtraction' }
|
23
|
-
for_symbol('-') { reduce_with 'subtraction' }
|
24
|
-
for_symbol('#') { reduce_with 'subtraction' }
|
25
|
-
for_symbol('/') { shift_to 44 }
|
26
|
-
for_symbol(')') { reduce_with 'subtraction' }
|
27
|
-
for_symbol('*') { shift_to 48 }
|
46
|
+
at_state(23) {
|
47
|
+
for_symbol('(') { shift_to 24 }
|
28
48
|
}
|
29
49
|
|
30
|
-
at_state(
|
31
|
-
for_symbol('
|
32
|
-
|
33
|
-
|
34
|
-
|
50
|
+
at_state(16) {
|
51
|
+
for_symbol('(') { reduce_with 'min_function' }
|
52
|
+
}
|
53
|
+
|
54
|
+
at_state(13) {
|
55
|
+
for_symbol('(') { reduce_with 'max_function' }
|
35
56
|
}
|
36
57
|
|
37
|
-
at_state(
|
58
|
+
at_state(20) {
|
38
59
|
for_symbol('+') { reduce_with 'addition' }
|
39
60
|
for_symbol(',') { reduce_with 'addition' }
|
40
61
|
for_symbol('-') { reduce_with 'addition' }
|
41
|
-
for_symbol('
|
42
|
-
for_symbol('
|
62
|
+
for_symbol('/') { shift_to 15 }
|
63
|
+
for_symbol('_End_') { reduce_with 'addition' }
|
43
64
|
for_symbol(')') { reduce_with 'addition' }
|
44
|
-
for_symbol('*') { shift_to
|
65
|
+
for_symbol('*') { shift_to 21 }
|
45
66
|
}
|
46
67
|
|
47
|
-
at_state(
|
48
|
-
for_symbol('+') { reduce_with '
|
49
|
-
for_symbol(',') { reduce_with '
|
50
|
-
for_symbol('-') { reduce_with '
|
51
|
-
for_symbol('
|
52
|
-
for_symbol('
|
53
|
-
for_symbol(')') { reduce_with '
|
54
|
-
for_symbol('*') { reduce_with '
|
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' }
|
55
76
|
}
|
56
77
|
|
57
|
-
at_state(
|
58
|
-
for_symbol('
|
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 }
|
59
87
|
}
|
60
88
|
|
61
|
-
at_state(
|
62
|
-
for_symbol('l') { shift_to
|
63
|
-
for_symbol('
|
64
|
-
for_symbol('
|
65
|
-
for_symbol('Function') { shift_to
|
66
|
-
for_symbol('F') { shift_to
|
67
|
-
for_symbol('
|
68
|
-
for_symbol('
|
69
|
-
for_symbol('T') { shift_to 53 }
|
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 }
|
70
97
|
}
|
71
98
|
|
72
99
|
at_state(33) {
|
73
|
-
for_symbol('
|
74
|
-
for_symbol('
|
75
|
-
for_symbol('
|
76
|
-
for_symbol('
|
77
|
-
for_symbol('
|
78
|
-
for_symbol('
|
79
|
-
for_symbol('
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
for_symbol('
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
for_symbol('
|
91
|
-
for_symbol('
|
92
|
-
for_symbol('
|
93
|
-
for_symbol('
|
94
|
-
for_symbol('Function') { shift_to 46 }
|
95
|
-
for_symbol('F') { shift_to 50 }
|
96
|
-
for_symbol('h') { shift_to 41 }
|
97
|
-
for_symbol('(') { shift_to 38 }
|
98
|
-
for_symbol('T') { shift_to 54 }
|
99
|
-
}
|
100
|
-
|
101
|
-
at_state(34) {
|
102
|
-
for_symbol('(') { shift_to 35 }
|
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 }
|
103
121
|
}
|
104
122
|
|
105
|
-
at_state(
|
106
|
-
for_symbol('
|
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 }
|
107
133
|
}
|
108
134
|
|
109
|
-
at_state(
|
110
|
-
for_symbol('
|
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' }
|
111
143
|
}
|
112
144
|
|
113
|
-
at_state(
|
145
|
+
at_state(31) {
|
114
146
|
for_symbol('+') { reduce_with 'function' }
|
115
147
|
for_symbol(',') { reduce_with 'function' }
|
116
148
|
for_symbol('-') { reduce_with 'function' }
|
117
|
-
for_symbol('#') { reduce_with 'function' }
|
118
149
|
for_symbol('/') { reduce_with 'function' }
|
150
|
+
for_symbol('_End_') { reduce_with 'function' }
|
119
151
|
for_symbol(')') { reduce_with 'function' }
|
120
152
|
for_symbol('*') { reduce_with 'function' }
|
121
153
|
}
|
122
154
|
|
123
|
-
at_state(
|
124
|
-
for_symbol('+') { reduce_with '
|
125
|
-
for_symbol(',') { reduce_with '
|
126
|
-
for_symbol('-') { reduce_with '
|
127
|
-
for_symbol('
|
128
|
-
for_symbol('
|
129
|
-
for_symbol(')') { reduce_with '
|
130
|
-
for_symbol('*') { reduce_with '
|
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' }
|
131
163
|
}
|
132
164
|
|
133
|
-
at_state(
|
134
|
-
for_symbol('
|
135
|
-
for_symbol('
|
136
|
-
for_symbol('
|
137
|
-
for_symbol('E') { shift_to 55 }
|
138
|
-
for_symbol('Function') { shift_to 46 }
|
139
|
-
for_symbol('F') { shift_to 50 }
|
140
|
-
for_symbol('Args') { shift_to 36 }
|
141
|
-
for_symbol('h') { shift_to 41 }
|
142
|
-
for_symbol('(') { shift_to 38 }
|
143
|
-
for_symbol(')') { reduce_with 'empty_args' }
|
144
|
-
for_symbol('T') { shift_to 54 }
|
165
|
+
at_state(18) {
|
166
|
+
for_symbol('+') { shift_to 19 }
|
167
|
+
for_symbol('-') { shift_to 32 }
|
168
|
+
for_symbol(')') { shift_to 34 }
|
145
169
|
}
|
146
170
|
|
147
|
-
at_state(
|
171
|
+
at_state(14) {
|
148
172
|
for_symbol('+') { reduce_with 'term' }
|
149
173
|
for_symbol(',') { reduce_with 'term' }
|
150
174
|
for_symbol('-') { reduce_with 'term' }
|
151
|
-
for_symbol('
|
152
|
-
for_symbol('
|
175
|
+
for_symbol('/') { shift_to 15 }
|
176
|
+
for_symbol('_End_') { reduce_with 'term' }
|
153
177
|
for_symbol(')') { reduce_with 'term' }
|
154
|
-
for_symbol('*') { shift_to
|
155
|
-
}
|
156
|
-
|
157
|
-
at_state(58) {
|
158
|
-
for_symbol('+') { shift_to 52 }
|
159
|
-
for_symbol('-') { shift_to 40 }
|
160
|
-
for_symbol('#') { reduce_with 'expression' }
|
178
|
+
for_symbol('*') { shift_to 21 }
|
161
179
|
}
|
162
180
|
|
163
|
-
at_state(
|
164
|
-
for_symbol('
|
165
|
-
for_symbol('n') { shift_to 42 }
|
166
|
-
for_symbol('FunctionName') { shift_to 34 }
|
167
|
-
for_symbol('E') { shift_to 55 }
|
168
|
-
for_symbol('Function') { shift_to 46 }
|
169
|
-
for_symbol('F') { shift_to 50 }
|
170
|
-
for_symbol('Args') { shift_to 57 }
|
171
|
-
for_symbol('h') { shift_to 41 }
|
172
|
-
for_symbol('(') { shift_to 38 }
|
173
|
-
for_symbol(')') { reduce_with 'empty_args' }
|
174
|
-
for_symbol('T') { shift_to 54 }
|
181
|
+
at_state(25) {
|
182
|
+
for_symbol(')') { shift_to 26 }
|
175
183
|
}
|
176
184
|
|
177
|
-
at_state(
|
178
|
-
for_symbol('+') { reduce_with '
|
179
|
-
for_symbol(',') { reduce_with '
|
180
|
-
for_symbol('-') { reduce_with '
|
181
|
-
for_symbol('
|
182
|
-
for_symbol('
|
183
|
-
for_symbol(')') { reduce_with '
|
184
|
-
for_symbol('*') { reduce_with '
|
185
|
-
}
|
186
|
-
|
187
|
-
at_state(44) {
|
188
|
-
for_symbol('l') { shift_to 47 }
|
189
|
-
for_symbol('n') { shift_to 42 }
|
190
|
-
for_symbol('FunctionName') { shift_to 34 }
|
191
|
-
for_symbol('F') { shift_to 45 }
|
192
|
-
for_symbol('Function') { shift_to 46 }
|
193
|
-
for_symbol('h') { shift_to 41 }
|
194
|
-
for_symbol('(') { shift_to 38 }
|
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' }
|
195
193
|
}
|
196
194
|
|
197
|
-
at_state(
|
195
|
+
at_state(12) {
|
198
196
|
for_symbol('+') { reduce_with 'getting_literals' }
|
199
197
|
for_symbol(',') { reduce_with 'getting_literals' }
|
200
198
|
for_symbol('-') { reduce_with 'getting_literals' }
|
201
|
-
for_symbol('#') { reduce_with 'getting_literals' }
|
202
199
|
for_symbol('/') { reduce_with 'getting_literals' }
|
200
|
+
for_symbol('_End_') { reduce_with 'getting_literals' }
|
203
201
|
for_symbol(')') { reduce_with 'getting_literals' }
|
204
202
|
for_symbol('*') { reduce_with 'getting_literals' }
|
205
203
|
}
|
206
204
|
|
207
205
|
at_state(36) {
|
208
|
-
for_symbol('
|
206
|
+
for_symbol('+') { shift_to 19 }
|
207
|
+
for_symbol('-') { shift_to 32 }
|
208
|
+
for_symbol('_End_') { reduce_with 'expression' }
|
209
209
|
}
|
210
210
|
|
211
|
-
at_state(
|
212
|
-
for_symbol('+') { reduce_with '
|
213
|
-
for_symbol(',') { reduce_with '
|
214
|
-
for_symbol('-') { reduce_with '
|
215
|
-
for_symbol('
|
216
|
-
for_symbol('
|
217
|
-
for_symbol(')') { reduce_with '
|
218
|
-
for_symbol('*') { reduce_with '
|
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
219
|
}
|
220
220
|
|
221
|
-
at_state(
|
221
|
+
at_state(29) {
|
222
222
|
for_symbol(')') { reduce_with 'concatenating_args' }
|
223
223
|
}
|
224
224
|
|
225
|
-
at_state(
|
226
|
-
for_symbol('
|
227
|
-
for_symbol('
|
228
|
-
for_symbol('
|
229
|
-
for_symbol('
|
230
|
-
for_symbol('F') { shift_to 50 }
|
231
|
-
for_symbol('h') { shift_to 41 }
|
232
|
-
for_symbol('(') { shift_to 38 }
|
233
|
-
for_symbol('T') { shift_to 43 }
|
234
|
-
}
|
235
|
-
|
236
|
-
at_state(39) {
|
237
|
-
for_symbol('+') { shift_to 52 }
|
238
|
-
for_symbol('-') { shift_to 40 }
|
239
|
-
for_symbol(')') { shift_to 51 }
|
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' }
|
240
230
|
}
|
241
231
|
|
242
|
-
at_state(
|
243
|
-
for_symbol('
|
244
|
-
for_symbol('
|
245
|
-
for_symbol('
|
246
|
-
for_symbol('
|
247
|
-
for_symbol('
|
248
|
-
for_symbol('
|
249
|
-
for_symbol('
|
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 }
|
250
241
|
}
|
251
242
|
|
252
243
|
end
|
@@ -29,7 +29,7 @@ class TestCompiledParser < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_compiled_parser_generates_syntax_tree_for_arithmetic_grammar
|
32
|
-
parser_input = ['(','n','-','(','n','/','n','-','n',')','/','n',')'
|
32
|
+
parser_input = ['(','n','-','(','n','/','n','-','n',')','/','n',')']
|
33
33
|
assert_equal \
|
34
34
|
["getting_literals",
|
35
35
|
"factor",
|
@@ -50,16 +50,15 @@ class TestCompiledParser < Test::Unit::TestCase
|
|
50
50
|
"unpacking_parenthetized_expression",
|
51
51
|
"factor",
|
52
52
|
"term",
|
53
|
-
"expression",
|
54
|
-
"start_production"], get_syntax_tree_with_compiled_arithmetic_parser(build_tokens(parser_input, CompiledArithmeticParser.grammar)).linearize
|
53
|
+
"expression"], get_syntax_tree_with_compiled_arithmetic_parser(build_tokens(parser_input, CompiledArithmeticParser.grammar)).linearize
|
55
54
|
end
|
56
55
|
|
57
|
-
def
|
58
|
-
|
56
|
+
def test_parse_result_has_error_if_empty_token_array
|
57
|
+
assert CompiledArithmeticParser.parse([]).has_error?
|
59
58
|
end
|
60
59
|
|
61
60
|
def test_parser_returns_error_result_with_index_of_bad_token_if_parse_error
|
62
|
-
parse_result = CompiledArithmeticParser.parse(build_tokens(['(', '-', ')'
|
61
|
+
parse_result = CompiledArithmeticParser.parse(build_tokens(['(', '-', ')'], CompiledArithmeticParser.grammar))
|
63
62
|
assert parse_result.has_error?
|
64
63
|
assert_equal 1, parse_result.bad_token_index
|
65
64
|
end
|
data/test/nullable_grammar.rb
CHANGED
data/test/parser_test.rb
CHANGED
@@ -76,8 +76,7 @@ class ParserTest < Test::Unit::TestCase
|
|
76
76
|
def test_with_a_different_grammar_with_division
|
77
77
|
grammar = ArithmeticGrammar
|
78
78
|
parser = Dhaka::Parser.new(grammar)
|
79
|
-
|
80
|
-
parser_input = ['(','n','-','(','n','/','n','-','n',')','/','n',')','#']
|
79
|
+
parser_input = ['(','n','-','(','n','/','n','-','n',')','/','n',')']
|
81
80
|
assert_equal \
|
82
81
|
["getting_literals",
|
83
82
|
"factor",
|
@@ -98,10 +97,9 @@ class ParserTest < Test::Unit::TestCase
|
|
98
97
|
"unpacking_parenthetized_expression",
|
99
98
|
"factor",
|
100
99
|
"term",
|
101
|
-
"expression",
|
102
|
-
"start_production"], get_linearized_parse_result(parser_input, parser)
|
100
|
+
"expression"], get_linearized_parse_result(parser_input, parser)
|
103
101
|
|
104
|
-
parser_input = ['h','(','(','n',')','-','n',',','n',')'
|
102
|
+
parser_input = ['h','(','(','n',')','-','n',',','n',')']
|
105
103
|
assert_equal \
|
106
104
|
["max_function",
|
107
105
|
"getting_literals",
|
@@ -122,14 +120,13 @@ class ParserTest < Test::Unit::TestCase
|
|
122
120
|
"function",
|
123
121
|
"factor",
|
124
122
|
"term",
|
125
|
-
"expression",
|
126
|
-
"start_production"], get_linearized_parse_result(parser_input, parser)
|
123
|
+
"expression"], get_linearized_parse_result(parser_input, parser)
|
127
124
|
end
|
128
125
|
|
129
126
|
def test_with_a_grammar_with_nullables_after_terminals
|
130
127
|
grammar = NullableGrammar
|
131
128
|
parser = Dhaka::Parser.new(grammar)
|
132
|
-
parser_input = ['(','a',')'
|
129
|
+
parser_input = ['(','a',')']
|
133
130
|
assert_equal \
|
134
131
|
["literal_a",
|
135
132
|
"empty_element_list",
|
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-
|
6
|
+
version: 0.0.3
|
7
|
+
date: 2006-12-04 00:00:00 -05:00
|
8
8
|
summary: An LALR1 parser generator written in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|