dhaka 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|