dhaka 2.0.0 → 2.0.1
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/dhaka.rb +24 -22
- data/lib/evaluator/evaluator.rb +42 -44
- data/lib/grammar/closure_hash.rb +4 -3
- data/lib/grammar/grammar.rb +113 -110
- data/lib/grammar/grammar_symbol.rb +6 -3
- data/lib/grammar/precedence.rb +3 -2
- data/lib/grammar/production.rb +5 -6
- data/lib/parser/action.rb +16 -11
- data/lib/parser/channel.rb +22 -16
- data/lib/parser/compiled_parser.rb +28 -22
- data/lib/parser/conflict.rb +54 -0
- data/lib/parser/item.rb +19 -19
- data/lib/parser/parse_result.rb +16 -1
- data/lib/parser/parse_tree.rb +15 -9
- data/lib/parser/parser.rb +51 -80
- data/lib/parser/parser_run.rb +6 -6
- data/lib/parser/parser_state.rb +16 -18
- data/lib/parser/token.rb +6 -4
- data/lib/tokenizer/tokenizer.rb +34 -31
- data/test/all_tests.rb +4 -18
- data/test/another_lalr_but_not_slr_grammar.rb +9 -5
- data/test/{arithmetic_evaluator.rb → arithmetic/arithmetic_evaluator.rb} +1 -2
- data/test/{arithmetic_evaluator_test.rb → arithmetic/arithmetic_evaluator_test.rb} +9 -20
- data/test/arithmetic/arithmetic_grammar.rb +41 -0
- data/test/{arithmetic_grammar_test.rb → arithmetic/arithmetic_grammar_test.rb} +2 -4
- data/test/{arithmetic_test_methods.rb → arithmetic/arithmetic_test_methods.rb} +1 -3
- data/test/{arithmetic_tokenizer.rb → arithmetic/arithmetic_tokenizer.rb} +8 -10
- data/test/{arithmetic_tokenizer_test.rb → arithmetic/arithmetic_tokenizer_test.rb} +4 -2
- data/test/{arithmetic_precedence_evaluator.rb → arithmetic_precedence/arithmetic_precedence_evaluator.rb} +1 -2
- data/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +24 -0
- data/test/{arithmetic_precedence_grammar_test.rb → arithmetic_precedence/arithmetic_precedence_grammar_test.rb} +2 -3
- data/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +31 -0
- data/test/{arithmetic_precedence_tokenizer.rb → arithmetic_precedence/arithmetic_precedence_tokenizer.rb} +8 -10
- data/test/brackets/bracket_grammar.rb +23 -0
- data/test/{bracket_tokenizer.rb → brackets/bracket_tokenizer.rb} +2 -4
- data/test/{brackets_test.rb → brackets/brackets_test.rb} +3 -4
- data/test/chittagong/chittagong_driver.rb +47 -0
- data/test/{chittagong_driver_test.rb → chittagong/chittagong_driver_test.rb} +66 -58
- data/test/{chittagong_evaluator.rb → chittagong/chittagong_evaluator.rb} +28 -13
- data/test/{chittagong_evaluator_test.rb → chittagong/chittagong_evaluator_test.rb} +6 -10
- data/test/chittagong/chittagong_grammar.rb +110 -0
- data/test/{chittagong_parser_test.rb → chittagong/chittagong_parser_test.rb} +5 -7
- data/test/{chittagong_test.rb → chittagong/chittagong_test.rb} +27 -36
- data/test/{chittagong_tokenizer.rb → chittagong/chittagong_tokenizer.rb} +17 -17
- data/test/{chittagong_tokenizer_test.rb → chittagong/chittagong_tokenizer_test.rb} +2 -3
- data/test/compiled_parser_test.rb +9 -42
- data/test/dhaka_test_helper.rb +17 -0
- data/test/evaluator_test.rb +18 -3
- data/test/grammar_test.rb +10 -15
- data/test/lalr_but_not_slr_grammar.rb +10 -8
- data/test/malformed_grammar.rb +2 -4
- data/test/malformed_grammar_test.rb +2 -3
- data/test/nullable_grammar.rb +11 -8
- data/test/parse_result_test.rb +44 -0
- data/test/parser_state_test.rb +36 -0
- data/test/parser_test.rb +53 -103
- data/test/precedence_grammar.rb +6 -6
- data/test/precedence_grammar_test.rb +2 -3
- data/test/rr_conflict_grammar.rb +5 -7
- data/test/simple_grammar.rb +6 -8
- data/test/sr_conflict_grammar.rb +6 -6
- metadata +30 -26
- data/test/arithmetic_grammar.rb +0 -35
- data/test/arithmetic_precedence_grammar.rb +0 -24
- data/test/arithmetic_precedence_parser_test.rb +0 -33
- data/test/bracket_grammar.rb +0 -25
- data/test/chittagong_grammar.rb +0 -104
- data/test/incomplete_arithmetic_evaluator.rb +0 -60
@@ -1,65 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require "
|
3
|
-
require "chittagong_grammar"
|
4
|
-
require "chittagong_tokenizer"
|
5
|
-
require "chittagong_evaluator"
|
6
|
-
require "fake_logger"
|
7
|
-
|
1
|
+
require File.dirname(__FILE__)+'/../dhaka_test_helper'
|
2
|
+
require File.dirname(__FILE__) + "/chittagong_grammar"
|
8
3
|
unless Object.const_defined? :ChittagongParser
|
9
4
|
eval(Dhaka::Parser.new(ChittagongGrammar, FakeLogger.new).compile_to_ruby_source_as(:ChittagongParser))
|
10
5
|
end
|
11
|
-
|
12
|
-
class ChittagongDriver
|
13
|
-
def marked_program(program, error_position)
|
14
|
-
if error_position > 0
|
15
|
-
program[0..(error_position-1)] + ">>>" + program[error_position..-1]
|
16
|
-
else
|
17
|
-
">>>"+program
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def parse_error_message unexpected_token, program
|
22
|
-
if unexpected_token.symbol_name == Dhaka::END_SYMBOL_NAME
|
23
|
-
"Unexpected end of file."
|
24
|
-
else
|
25
|
-
"Unexpected token #{unexpected_token.symbol_name}:\n#{marked_program(program, unexpected_token.input_position)}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def tokenize_error_message unexpected_char_index, program
|
30
|
-
"Unexpected character #{program[unexpected_char_index].chr}:\n#{marked_program(program, unexpected_char_index)}"
|
31
|
-
end
|
32
|
-
|
33
|
-
def evaluation_error_message evaluation_result, program
|
34
|
-
"#{evaluation_result.exception}:\n#{marked_program(program, evaluation_result.node.tokens[0].input_position)}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def run(program)
|
38
|
-
tokenize_result = ChittagongTokenizer.tokenize(program)
|
39
|
-
if tokenize_result.has_error?
|
40
|
-
return tokenize_error_message(tokenize_result.unexpected_char_index, program)
|
41
|
-
end
|
42
|
-
|
43
|
-
parse_result = ChittagongParser.parse(tokenize_result)
|
44
|
-
if parse_result.has_error?
|
45
|
-
return parse_error_message(parse_result.unexpected_token, program)
|
46
|
-
end
|
47
|
-
|
48
|
-
evaluation_result = ChittagongEvaluator.new([{}], output_stream = []).
|
49
|
-
evaluate(parse_result.parse_tree)
|
50
|
-
if evaluation_result.exception
|
51
|
-
return (output_stream << evaluation_error_message(evaluation_result, program)).
|
52
|
-
join("\n")
|
53
|
-
end
|
54
|
-
|
55
|
-
return output_stream.join("\n")
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
6
|
+
require File.dirname(__FILE__) + "/chittagong_driver"
|
60
7
|
|
61
8
|
class TestChittagongDriver < Test::Unit::TestCase
|
62
|
-
|
63
9
|
def setup
|
64
10
|
@driver = ChittagongDriver.new
|
65
11
|
end
|
@@ -178,7 +124,7 @@ Undefined variable c:
|
|
178
124
|
|
179
125
|
", @driver.run(program))
|
180
126
|
end
|
181
|
-
|
127
|
+
# lipi:variable_scoping
|
182
128
|
def test_variable_scope
|
183
129
|
program = "
|
184
130
|
x = 1
|
@@ -211,6 +157,7 @@ Undefined variable c:
|
|
211
157
|
|
212
158
|
", @driver.run(program))
|
213
159
|
end
|
160
|
+
# lipi:variable_scoping
|
214
161
|
|
215
162
|
def test_nested_function_calls
|
216
163
|
|
@@ -258,4 +205,65 @@ Undefined variable c:
|
|
258
205
|
", @driver.run(program))
|
259
206
|
|
260
207
|
end
|
208
|
+
|
209
|
+
def test_an_empty_program
|
210
|
+
program = ""
|
211
|
+
assert_equal("Unexpected end of file.", @driver.run(program))
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_associating_equality_tests_should_show_an_error
|
215
|
+
program = "
|
216
|
+
def foo()
|
217
|
+
print 999
|
218
|
+
end
|
219
|
+
|
220
|
+
foo()
|
221
|
+
print 1 == 1 == 1"
|
222
|
+
|
223
|
+
assert_equal("Unexpected token ==:
|
224
|
+
|
225
|
+
def foo()
|
226
|
+
print 999
|
227
|
+
end
|
228
|
+
|
229
|
+
foo()
|
230
|
+
print 1 == 1 >>>== 1", @driver.run(program))
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_catches_bad_decimal_points
|
234
|
+
program = "
|
235
|
+
a = .234
|
236
|
+
b = 20.234.2
|
237
|
+
"
|
238
|
+
|
239
|
+
assert_equal("Unexpected token .:
|
240
|
+
|
241
|
+
a = .234
|
242
|
+
b = 20.234>>>.2
|
243
|
+
", @driver.run(program))
|
244
|
+
end
|
245
|
+
# lipi:recursive_fib
|
246
|
+
def test_recursive_fibonacci
|
247
|
+
program = "
|
248
|
+
|
249
|
+
def fib(n)
|
250
|
+
if n == 0
|
251
|
+
return 1
|
252
|
+
end
|
253
|
+
if n == 1
|
254
|
+
return 1
|
255
|
+
end
|
256
|
+
return fib(n-1) + fib(n-2)
|
257
|
+
end
|
258
|
+
|
259
|
+
x = 0
|
260
|
+
while x < 9
|
261
|
+
print fib(x)
|
262
|
+
x = x + 1
|
263
|
+
end
|
264
|
+
|
265
|
+
"
|
266
|
+
assert_equal(["1", "1", "2", "3", "5", "8", "13", "21", "34"].join("\n"), @driver.run(program))
|
267
|
+
end
|
268
|
+
# lipi:recursive_fib
|
261
269
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require File.dirname(__FILE__)+'
|
2
|
-
require 'chittagong_grammar'
|
1
|
+
require File.dirname(__FILE__) + '/chittagong_grammar'
|
3
2
|
|
4
3
|
class ChittagongEvaluator < Dhaka::Evaluator
|
5
4
|
|
@@ -25,14 +24,15 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
25
24
|
return first if (first.exception || first.result)
|
26
25
|
evaluate(child_nodes[2])
|
27
26
|
end
|
28
|
-
|
27
|
+
# lipi:function_defs
|
29
28
|
for_function_definition do
|
30
|
-
function_name
|
29
|
+
function_name = evaluate(child_nodes[1])
|
31
30
|
arg_declarations = evaluate(child_nodes[3])
|
32
|
-
body
|
31
|
+
body = child_nodes[6]
|
33
32
|
@function_table[function_name] = Function.new(arg_declarations, body)
|
34
33
|
ChittagongSuccessResult.new(nil)
|
35
34
|
end
|
35
|
+
# lipi:function_defs
|
36
36
|
|
37
37
|
for_main_body_if_statement do
|
38
38
|
checked_if_statement
|
@@ -76,7 +76,7 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def checked_while_statement
|
79
|
-
|
79
|
+
loop do
|
80
80
|
condition_eval = evaluate(child_nodes[1])
|
81
81
|
return condition_eval if condition_eval.exception
|
82
82
|
break unless condition_eval.result
|
@@ -107,7 +107,7 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
107
107
|
for_function_call_expression do
|
108
108
|
checked_function_call
|
109
109
|
end
|
110
|
-
|
110
|
+
# lipi:checked_function_call
|
111
111
|
def checked_function_call
|
112
112
|
function_name = evaluate(child_nodes[0])
|
113
113
|
return ChittagongExceptionResult.new("Undefined function #{function_name}",
|
@@ -121,6 +121,7 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
121
121
|
"Wrong number of arguments", child_nodes[1]
|
122
122
|
) unless function.args.size == arg_values.result.size
|
123
123
|
new_frame = {}
|
124
|
+
|
124
125
|
function.args.zip(arg_values.result).each do |arg_name, arg_value|
|
125
126
|
new_frame[arg_name] = arg_value
|
126
127
|
end
|
@@ -131,6 +132,7 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
131
132
|
|
132
133
|
result
|
133
134
|
end
|
135
|
+
# lipi:checked_function_call
|
134
136
|
|
135
137
|
for_return_statement do
|
136
138
|
checked_unary_operation(child_nodes[1]){|x| x}
|
@@ -166,7 +168,16 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
166
168
|
ChittagongSuccessResult.new(@stack[-1][variable_name])
|
167
169
|
end
|
168
170
|
|
169
|
-
|
171
|
+
|
172
|
+
for_float_without_leading_digits do
|
173
|
+
ChittagongSuccessResult.new(('.' + child_nodes[1].token.value).to_f)
|
174
|
+
end
|
175
|
+
|
176
|
+
for_float_with_leading_digits do
|
177
|
+
ChittagongSuccessResult.new((child_nodes[0].token.value + '.' +child_nodes[2].token.value).to_f)
|
178
|
+
end
|
179
|
+
|
180
|
+
for_integer do
|
170
181
|
ChittagongSuccessResult.new(child_nodes[0].token.value.to_i)
|
171
182
|
end
|
172
183
|
|
@@ -229,23 +240,27 @@ class ChittagongEvaluator < Dhaka::Evaluator
|
|
229
240
|
end
|
230
241
|
|
231
242
|
for_function_name do
|
232
|
-
|
243
|
+
token_value
|
233
244
|
end
|
234
245
|
|
235
246
|
for_variable_name do
|
236
|
-
|
247
|
+
token_value
|
237
248
|
end
|
238
249
|
|
239
250
|
for_arg_declaration do
|
240
|
-
|
251
|
+
token_value
|
241
252
|
end
|
242
|
-
|
253
|
+
|
254
|
+
def token_value
|
255
|
+
child_nodes.first.token.value
|
256
|
+
end
|
257
|
+
# lipi:initialize
|
243
258
|
def initialize(stack, output_stream)
|
244
259
|
@stack = stack
|
245
260
|
@function_table = {}
|
246
261
|
@output_stream = output_stream
|
247
262
|
end
|
248
|
-
|
263
|
+
# lipi:initialize
|
249
264
|
end
|
250
265
|
|
251
266
|
end
|
@@ -1,16 +1,12 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
require "fake_logger"
|
5
|
-
|
6
|
-
unless Object.const_defined? :ChittagongParser
|
1
|
+
require File.dirname(__FILE__) + '/../dhaka_test_helper'
|
2
|
+
require File.dirname(__FILE__) + "/chittagong_evaluator"
|
3
|
+
unless defined? ChittagongParser
|
7
4
|
eval(Dhaka::Parser.new(ChittagongGrammar, FakeLogger.new).compile_to_ruby_source_as(:ChittagongParser))
|
8
5
|
end
|
9
6
|
|
10
7
|
class TestChittagongEvaluator < Test::Unit::TestCase
|
11
|
-
|
12
8
|
def test_evaluates_a_simple_program
|
13
|
-
token_stream
|
9
|
+
token_stream = build_tokens(
|
14
10
|
['newline'],
|
15
11
|
['word_literal', 'x'], ['='], ['int_literal', 23], ['newline'],
|
16
12
|
['print'], ['word_literal', 'x'], ['newline'],
|
@@ -25,9 +21,9 @@ class TestChittagongEvaluator < Test::Unit::TestCase
|
|
25
21
|
['newline'],
|
26
22
|
[Dhaka::END_SYMBOL_NAME]
|
27
23
|
)
|
28
|
-
stack
|
24
|
+
stack = [{}]
|
29
25
|
output_stream = []
|
30
|
-
ChittagongEvaluator.new(stack, output_stream).evaluate(ChittagongParser.parse(token_stream)
|
26
|
+
ChittagongEvaluator.new(stack, output_stream).evaluate(ChittagongParser.parse(token_stream))
|
31
27
|
assert_equal(23, stack[0]['x'])
|
32
28
|
assert_equal(46, stack[0]['y'])
|
33
29
|
assert_equal(['23', '1058', '46'], output_stream)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
class ChittagongGrammar < Dhaka::Grammar
|
2
|
+
|
3
|
+
precedences do
|
4
|
+
nonassoc %w| == |
|
5
|
+
nonassoc %w| < > |
|
6
|
+
left %w| + - |
|
7
|
+
left %w| * / |
|
8
|
+
nonassoc %w| ^ |
|
9
|
+
nonassoc %w| ! |
|
10
|
+
end
|
11
|
+
# lipi:grammar_overview
|
12
|
+
|
13
|
+
for_symbol(Dhaka::START_SYMBOL_NAME) do
|
14
|
+
program %w| opt_terms main_body opt_terms |
|
15
|
+
end
|
16
|
+
|
17
|
+
for_symbol('main_body') do
|
18
|
+
single_main_body_statement %w| main_body_statement |
|
19
|
+
multiple_main_body_statements %w| main_body terms main_body_statement |
|
20
|
+
end
|
21
|
+
|
22
|
+
for_symbol('main_body_statement') do
|
23
|
+
main_body_simple_statement %w| simple_statement |
|
24
|
+
function_definition %w| def function_name ( arg_declarations ) terms
|
25
|
+
function_body terms end |
|
26
|
+
main_body_if_statement %w| if expression terms main_body terms end |
|
27
|
+
main_body_if_else_statement %w| if expression terms main_body terms else terms main_body
|
28
|
+
terms end |
|
29
|
+
main_body_while_statement %w| while expression terms main_body terms end |
|
30
|
+
end
|
31
|
+
# lipi:grammar_overview
|
32
|
+
|
33
|
+
for_symbol('simple_statement') do
|
34
|
+
assignment_statement %w| var_name = expression |
|
35
|
+
print_statement %w| print expression |
|
36
|
+
function_call_statement %w| function_name ( arg_list ) |
|
37
|
+
end
|
38
|
+
|
39
|
+
for_symbol('function_body') do
|
40
|
+
single_function_body_statement %w| function_body_statement |
|
41
|
+
multiple_function_body_statements %w| function_body terms function_body_statement |
|
42
|
+
end
|
43
|
+
|
44
|
+
for_symbol('function_body_statement') do
|
45
|
+
function_body_simple_statement %w| simple_statement |
|
46
|
+
return_statement %w| return expression |
|
47
|
+
function_body_if_statement %w| if expression terms function_body terms end |
|
48
|
+
function_body_if_else_statement %w| if expression terms function_body terms else terms function_body terms end |
|
49
|
+
function_body_while_statement %w| while expression terms function_body terms end |
|
50
|
+
end
|
51
|
+
|
52
|
+
for_symbol('function_name') do
|
53
|
+
function_name %w| word_literal |
|
54
|
+
end
|
55
|
+
|
56
|
+
for_symbol('var_name') do
|
57
|
+
variable_name %w| word_literal |
|
58
|
+
end
|
59
|
+
|
60
|
+
for_symbol('arg_declarations') do
|
61
|
+
no_arg_decl %w| |
|
62
|
+
single_arg_declaration %w| arg_decl |
|
63
|
+
multiple_arg_declarations %w| arg_declarations , arg_decl |
|
64
|
+
end
|
65
|
+
|
66
|
+
for_symbol('arg_decl') do
|
67
|
+
arg_declaration %w| word_literal |
|
68
|
+
end
|
69
|
+
|
70
|
+
for_symbol('arg_list') do
|
71
|
+
no_args %w| |
|
72
|
+
single_arg %w| expression |
|
73
|
+
multiple_args %w| arg_list , expression |
|
74
|
+
end
|
75
|
+
# lipi:expressions
|
76
|
+
for_symbol('expression') do
|
77
|
+
negation %w| ! expression |
|
78
|
+
equality_comparison %w| expression == expression |
|
79
|
+
greater_than_comparison %w| expression > expression |
|
80
|
+
less_than_comparison %w| expression < expression |
|
81
|
+
addition %w| expression + expression |
|
82
|
+
subtraction %w| expression - expression |
|
83
|
+
multiplication %w| expression * expression |
|
84
|
+
division %w| expression / expression |
|
85
|
+
power %w| expression ^ expression |
|
86
|
+
literal %w| numeric_literal |
|
87
|
+
function_call_expression %w| function_name ( arg_list ) |
|
88
|
+
variable_reference %w| var_name |
|
89
|
+
parenthetized_expression %w| ( expression ) |
|
90
|
+
negated_expression %w| - expression |, :prec => '*'
|
91
|
+
end
|
92
|
+
# lipi:expressions
|
93
|
+
|
94
|
+
for_symbol('numeric_literal') do
|
95
|
+
integer %w| int_literal |
|
96
|
+
float_with_leading_digits %w| int_literal . int_literal |
|
97
|
+
float_without_leading_digits %w| . int_literal |
|
98
|
+
end
|
99
|
+
|
100
|
+
for_symbol('terms') do
|
101
|
+
single_term %w| newline |
|
102
|
+
multiple_terms %w| terms newline |
|
103
|
+
end
|
104
|
+
|
105
|
+
for_symbol('opt_terms') do
|
106
|
+
some_terms %w| terms |
|
107
|
+
no_terms %w| |
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -1,8 +1,5 @@
|
|
1
|
-
require File.dirname(__FILE__)+'/../
|
2
|
-
|
3
|
-
require 'chittagong_grammar'
|
4
|
-
require "test/unit"
|
5
|
-
require "fake_logger"
|
1
|
+
require File.dirname(__FILE__) + '/../dhaka_test_helper'
|
2
|
+
require File.dirname(__FILE__) + '/chittagong_grammar'
|
6
3
|
|
7
4
|
class TestChittagongParser < Test::Unit::TestCase
|
8
5
|
def setup
|
@@ -10,7 +7,7 @@ class TestChittagongParser < Test::Unit::TestCase
|
|
10
7
|
@parser = Dhaka::Parser.new(ChittagongGrammar, fake_logger)
|
11
8
|
assert_equal(80, fake_logger.warnings.size)
|
12
9
|
assert_equal(0, fake_logger.errors.size)
|
13
|
-
eval(@parser.compile_to_ruby_source_as(:ChittagongParser)) unless
|
10
|
+
eval(@parser.compile_to_ruby_source_as(:ChittagongParser)) unless defined? ChittagongParser
|
14
11
|
end
|
15
12
|
|
16
13
|
def test_parses_a_series_of_statements
|
@@ -28,6 +25,7 @@ class TestChittagongParser < Test::Unit::TestCase
|
|
28
25
|
assert_equal(["single_term",
|
29
26
|
"some_terms",
|
30
27
|
"variable_name",
|
28
|
+
"integer",
|
31
29
|
"literal",
|
32
30
|
"assignment_statement",
|
33
31
|
"main_body_simple_statement",
|
@@ -49,7 +47,7 @@ class TestChittagongParser < Test::Unit::TestCase
|
|
49
47
|
"single_term",
|
50
48
|
"multiple_terms",
|
51
49
|
"some_terms",
|
52
|
-
"program"], result.
|
50
|
+
"program"], result.linearize.collect {|node| node.production.name})
|
53
51
|
|
54
52
|
end
|
55
53
|
|
@@ -1,15 +1,11 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require "
|
4
|
-
require "
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
unless Object.const_defined? :ChittagongParser
|
9
|
-
eval(Dhaka::Parser.new(ChittagongGrammar, FakeLogger.new).compile_to_ruby_source_as(:ChittagongParser))
|
1
|
+
require File.dirname(__FILE__) + '/../dhaka_test_helper'
|
2
|
+
require File.dirname(__FILE__) + "/chittagong_grammar"
|
3
|
+
require File.dirname(__FILE__) + "/chittagong_tokenizer"
|
4
|
+
require File.dirname(__FILE__) + "/chittagong_evaluator"
|
5
|
+
unless defined? ChittagongParser
|
6
|
+
eval(Dhaka::Parser.new(ChittagongGrammar, FakeLogger.new).compile_to_ruby_source_as(:ChittagongParser))
|
10
7
|
end
|
11
8
|
|
12
|
-
|
13
9
|
class TestChittagong < Test::Unit::TestCase
|
14
10
|
|
15
11
|
def fact(n)
|
@@ -20,7 +16,7 @@ class TestChittagong < Test::Unit::TestCase
|
|
20
16
|
def program_output program
|
21
17
|
output_stream = []
|
22
18
|
parse_result = ChittagongParser.parse(ChittagongTokenizer.tokenize(program))
|
23
|
-
result = ChittagongEvaluator.new([{}], output_stream).evaluate(parse_result
|
19
|
+
result = ChittagongEvaluator.new([{}], output_stream).evaluate(parse_result)
|
24
20
|
return result, output_stream
|
25
21
|
end
|
26
22
|
|
@@ -71,30 +67,6 @@ class TestChittagong < Test::Unit::TestCase
|
|
71
67
|
assert_equal(["1", "1", "2", "3", "5", "8", "13", "21", "34"], output_stream)
|
72
68
|
end
|
73
69
|
|
74
|
-
def test_recursive_fibonacci
|
75
|
-
program = "
|
76
|
-
|
77
|
-
def fib(n)
|
78
|
-
if n == 0
|
79
|
-
return 1
|
80
|
-
end
|
81
|
-
if n == -1
|
82
|
-
return 0
|
83
|
-
end
|
84
|
-
return fib(n-1) + fib(n-2)
|
85
|
-
end
|
86
|
-
|
87
|
-
x = 0
|
88
|
-
while x < 9
|
89
|
-
print fib(x)
|
90
|
-
x = x + 1
|
91
|
-
end
|
92
|
-
|
93
|
-
"
|
94
|
-
result, output_stream = program_output(program)
|
95
|
-
assert_equal(["1", "1", "2", "3", "5", "8", "13", "21", "34"], output_stream)
|
96
|
-
end
|
97
|
-
|
98
70
|
def test_recursive_factorial
|
99
71
|
program = "
|
100
72
|
def fact(n)
|
@@ -172,4 +144,23 @@ class TestChittagong < Test::Unit::TestCase
|
|
172
144
|
assert_equal(["1", "2"], output_stream)
|
173
145
|
end
|
174
146
|
|
175
|
-
|
147
|
+
def test_decimal_numbers
|
148
|
+
program = "
|
149
|
+
print .2347 * 23.34
|
150
|
+
a = 1.012
|
151
|
+
b = 345.44
|
152
|
+
c = .234
|
153
|
+
print (a^b)/c
|
154
|
+
def foo(a)
|
155
|
+
print a
|
156
|
+
end
|
157
|
+
foo(3.4)
|
158
|
+
"
|
159
|
+
|
160
|
+
result, output_stream = program_output(program)
|
161
|
+
assert_equal(["5.477898", "263.233029427781", "3.4"], output_stream)
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
end
|