simply_stored 0.1.4

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.
Files changed (121) hide show
  1. data/lib/simply_stored/class_methods_base.rb +31 -0
  2. data/lib/simply_stored/couch/belongs_to.rb +117 -0
  3. data/lib/simply_stored/couch/ext/couch_potato.rb +16 -0
  4. data/lib/simply_stored/couch/has_many.rb +148 -0
  5. data/lib/simply_stored/couch/has_one.rb +93 -0
  6. data/lib/simply_stored/couch/validations.rb +74 -0
  7. data/lib/simply_stored/couch/views/array_property_view_spec.rb +22 -0
  8. data/lib/simply_stored/couch/views.rb +1 -0
  9. data/lib/simply_stored/couch.rb +278 -0
  10. data/lib/simply_stored/instance_methods.rb +143 -0
  11. data/lib/simply_stored/simpledb/associations.rb +196 -0
  12. data/lib/simply_stored/simpledb/attributes.rb +173 -0
  13. data/lib/simply_stored/simpledb/storag.rb +85 -0
  14. data/lib/simply_stored/simpledb/validations.rb +88 -0
  15. data/lib/simply_stored/simpledb.rb +212 -0
  16. data/lib/simply_stored/storage.rb +93 -0
  17. data/lib/simply_stored.rb +9 -0
  18. data/test/custom_views_test.rb +33 -0
  19. data/test/fixtures/couch.rb +182 -0
  20. data/test/fixtures/simpledb/item.rb +11 -0
  21. data/test/fixtures/simpledb/item_daddy.rb +8 -0
  22. data/test/fixtures/simpledb/log_item.rb +3 -0
  23. data/test/fixtures/simpledb/namespace_bar.rb +5 -0
  24. data/test/fixtures/simpledb/namespace_foo.rb +7 -0
  25. data/test/fixtures/simpledb/protected_item.rb +3 -0
  26. data/test/simply_stored_couch_test.rb +1684 -0
  27. data/test/simply_stored_simpledb_test.rb +1341 -0
  28. data/test/test_helper.rb +22 -0
  29. data/test/vendor/dhaka-2.2.1/lib/dhaka/dot/dot.rb +29 -0
  30. data/test/vendor/dhaka-2.2.1/lib/dhaka/evaluator/evaluator.rb +133 -0
  31. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/closure_hash.rb +15 -0
  32. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar.rb +240 -0
  33. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar_symbol.rb +27 -0
  34. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/precedence.rb +19 -0
  35. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/production.rb +36 -0
  36. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/accept_actions.rb +36 -0
  37. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/alphabet.rb +21 -0
  38. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/compiled_lexer.rb +46 -0
  39. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/dfa.rb +121 -0
  40. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexeme.rb +32 -0
  41. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer.rb +70 -0
  42. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer_run.rb +78 -0
  43. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_grammar.rb +392 -0
  44. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_parser.rb +2010 -0
  45. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_tokenizer.rb +14 -0
  46. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/specification.rb +96 -0
  47. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state.rb +68 -0
  48. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state_machine.rb +37 -0
  49. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/action.rb +55 -0
  50. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/channel.rb +58 -0
  51. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/compiled_parser.rb +51 -0
  52. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/conflict.rb +54 -0
  53. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/item.rb +42 -0
  54. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_result.rb +50 -0
  55. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_tree.rb +66 -0
  56. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser.rb +165 -0
  57. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_methods.rb +11 -0
  58. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_run.rb +39 -0
  59. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_state.rb +74 -0
  60. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/token.rb +22 -0
  61. data/test/vendor/dhaka-2.2.1/lib/dhaka/runtime.rb +51 -0
  62. data/test/vendor/dhaka-2.2.1/lib/dhaka/tokenizer/tokenizer.rb +190 -0
  63. data/test/vendor/dhaka-2.2.1/lib/dhaka.rb +62 -0
  64. data/test/vendor/dhaka-2.2.1/test/all_tests.rb +5 -0
  65. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator.rb +64 -0
  66. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator_test.rb +43 -0
  67. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar.rb +41 -0
  68. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar_test.rb +9 -0
  69. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_test_methods.rb +9 -0
  70. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer.rb +39 -0
  71. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer_test.rb +38 -0
  72. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_evaluator.rb +43 -0
  73. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +24 -0
  74. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar_test.rb +30 -0
  75. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_lexer_specification.rb +23 -0
  76. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +33 -0
  77. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_grammar.rb +23 -0
  78. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_tokenizer.rb +22 -0
  79. data/test/vendor/dhaka-2.2.1/test/brackets/brackets_test.rb +28 -0
  80. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver.rb +46 -0
  81. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver_test.rb +276 -0
  82. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator.rb +284 -0
  83. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator_test.rb +38 -0
  84. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_grammar.rb +104 -0
  85. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer.rb +109 -0
  86. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_specification.rb +37 -0
  87. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_test.rb +58 -0
  88. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser.rb +879 -0
  89. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser_test.rb +55 -0
  90. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_test.rb +170 -0
  91. data/test/vendor/dhaka-2.2.1/test/core/another_lalr_but_not_slr_grammar.rb +20 -0
  92. data/test/vendor/dhaka-2.2.1/test/core/compiled_parser_test.rb +44 -0
  93. data/test/vendor/dhaka-2.2.1/test/core/dfa_test.rb +170 -0
  94. data/test/vendor/dhaka-2.2.1/test/core/evaluator_test.rb +22 -0
  95. data/test/vendor/dhaka-2.2.1/test/core/grammar_test.rb +83 -0
  96. data/test/vendor/dhaka-2.2.1/test/core/lalr_but_not_slr_grammar.rb +19 -0
  97. data/test/vendor/dhaka-2.2.1/test/core/lexer_test.rb +139 -0
  98. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar.rb +7 -0
  99. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar_test.rb +8 -0
  100. data/test/vendor/dhaka-2.2.1/test/core/nullable_grammar.rb +21 -0
  101. data/test/vendor/dhaka-2.2.1/test/core/parse_result_test.rb +44 -0
  102. data/test/vendor/dhaka-2.2.1/test/core/parser_state_test.rb +24 -0
  103. data/test/vendor/dhaka-2.2.1/test/core/parser_test.rb +131 -0
  104. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar.rb +17 -0
  105. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar_test.rb +9 -0
  106. data/test/vendor/dhaka-2.2.1/test/core/rr_conflict_grammar.rb +21 -0
  107. data/test/vendor/dhaka-2.2.1/test/core/simple_grammar.rb +22 -0
  108. data/test/vendor/dhaka-2.2.1/test/core/sr_conflict_grammar.rb +16 -0
  109. data/test/vendor/dhaka-2.2.1/test/dhaka_test_helper.rb +17 -0
  110. data/test/vendor/dhaka-2.2.1/test/fake_logger.rb +17 -0
  111. data/test/vendor/simplerdb-0.2/lib/simplerdb/client_exception.rb +10 -0
  112. data/test/vendor/simplerdb-0.2/lib/simplerdb/db.rb +146 -0
  113. data/test/vendor/simplerdb-0.2/lib/simplerdb/query_language.rb +266 -0
  114. data/test/vendor/simplerdb-0.2/lib/simplerdb/server.rb +33 -0
  115. data/test/vendor/simplerdb-0.2/lib/simplerdb/servlet.rb +191 -0
  116. data/test/vendor/simplerdb-0.2/lib/simplerdb.rb +3 -0
  117. data/test/vendor/simplerdb-0.2/test/functional_test.rb +81 -0
  118. data/test/vendor/simplerdb-0.2/test/query_evaluator_test.rb +73 -0
  119. data/test/vendor/simplerdb-0.2/test/query_parser_test.rb +64 -0
  120. data/test/vendor/simplerdb-0.2/test/simplerdb_test.rb +80 -0
  121. metadata +182 -0
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + '/arithmetic_evaluator'
3
+ require File.dirname(__FILE__) + '/arithmetic_test_methods'
4
+ eval(Dhaka::Parser.new(ArithmeticGrammar).compile_to_ruby_source_as(:CompiledArithmeticParser))
5
+
6
+ class TestArithmeticEvaluator < Test::Unit::TestCase
7
+ include ArithmeticTestMethods
8
+
9
+ def setup
10
+ @min_func = Proc.new {|args| args.inject {|min, elem| min = (elem < min ? elem : min)}}
11
+ @max_func = Proc.new {|args| args.inject {|max, elem| max = (elem > max ? elem : max)}}
12
+ end
13
+
14
+ def test_results_simple_arithmetic_given_tokens_and_parse_tree_1
15
+ token_stream = [token('n', 2), token('-', nil), token('n', 4), token(Dhaka::END_SYMBOL_NAME, nil)]
16
+ parse_tree = parse(token_stream)
17
+ assert_equal -2, ArithmeticEvaluator.new(@min_func, @max_func).evaluate(parse_tree)
18
+ end
19
+
20
+ def test_results_simple_arithmetic_given_tokens_and_parse_tree_2
21
+ token_stream = [token('n', 2), token('-', nil), token('(', nil), token('n', 3), token('/', nil), token('n', 4), token(')', nil), token(Dhaka::END_SYMBOL_NAME, nil)]
22
+ parse_tree = parse(token_stream)
23
+ assert_equal 1.25, ArithmeticEvaluator.new(@min_func, @max_func).evaluate(parse_tree)
24
+ end
25
+
26
+ def test_results_simple_arithmetic_given_tokens_and_parse_tree_3
27
+ 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), token(Dhaka::END_SYMBOL_NAME, nil)]
28
+ parse_tree = parse(token_stream)
29
+ assert_equal 3.5, ArithmeticEvaluator.new(@min_func, @max_func).evaluate(parse_tree)
30
+ end
31
+
32
+ def test_results_simple_arithmetic_given_tokens_and_parse_tree_4
33
+ token_stream = [token('n', 2), token('+', nil), token('h', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil), token(Dhaka::END_SYMBOL_NAME, nil)]
34
+ parse_tree = parse(token_stream)
35
+ assert_equal 6, ArithmeticEvaluator.new(@min_func, @max_func).evaluate(parse_tree)
36
+ end
37
+
38
+ def test_results_simple_arithmetic_given_tokens_and_parse_tree_5
39
+ token_stream = [token('n', 2), token('+', nil), token('l', nil), token('(', nil), token('n', 3), token(',', nil), token('n', 4), token(')', nil), token(Dhaka::END_SYMBOL_NAME, nil)]
40
+ parse_tree = parse(token_stream)
41
+ assert_equal 5, ArithmeticEvaluator.new(@min_func, @max_func).evaluate(parse_tree)
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ class ArithmeticGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ expression %w| E |
5
+ end
6
+
7
+ for_symbol('E') do
8
+ subtraction %w| E - T |
9
+ addition %w| E + T |
10
+ term %w| T |
11
+ end
12
+
13
+ for_symbol('T') do
14
+ factor %w| F |
15
+ division %w| T / F |
16
+ multiplication %w| T * F |
17
+ end
18
+
19
+ for_symbol('F') do
20
+ getting_literals %w| n |
21
+ unpacking_parenthetized_expression %w| ( E ) |
22
+ function %w| Function |
23
+ end
24
+
25
+ for_symbol('Function') do
26
+ evaluating_function %w| FunctionName ( Args ) |
27
+ end
28
+
29
+ for_symbol('FunctionName') do
30
+ max_function %w| h |
31
+ min_function %w| l |
32
+ end
33
+
34
+ for_symbol('Args') do
35
+ empty_args %w||
36
+ single_args %w| E |
37
+ concatenating_args %w| E , Args |
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + '/arithmetic_grammar'
3
+
4
+ class ArithmeticGrammarTest < Test::Unit::TestCase
5
+ def test_first_with_nullable_non_terminals
6
+ grammar = ArithmeticGrammar
7
+ assert_equal(Set.new(['(', 'n', 'h', 'l']), Set.new(grammar.first(grammar.symbol_for_name('Args')).collect { |symbol| symbol.name }))
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ArithmeticTestMethods
2
+ def parse(token_stream)
3
+ CompiledArithmeticParser.parse(token_stream)
4
+ end
5
+
6
+ def token(symbol_name, value)
7
+ Dhaka::Token.new(symbol_name, value, nil)
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/arithmetic_grammar'
2
+
3
+ class ArithmeticTokenizer < Dhaka::Tokenizer
4
+
5
+ digits = ('0'..'9').to_a
6
+ parenths = %w| ( ) |
7
+ operators = %w| - + / * |
8
+ functions = %w| h l |
9
+ arg_separator = %w| , |
10
+ whitespace = [' ']
11
+
12
+ all_characters = digits + parenths + operators + functions + arg_separator + whitespace
13
+
14
+ for_state Dhaka::TOKENIZER_IDLE_STATE do
15
+ for_characters(all_characters - (digits + whitespace)) do
16
+ create_token(curr_char, nil)
17
+ advance
18
+ end
19
+ for_characters digits do
20
+ create_token('n', '')
21
+ switch_to :get_integer_literal
22
+ end
23
+ for_character whitespace do
24
+ advance
25
+ end
26
+ end
27
+
28
+ for_state :get_integer_literal do
29
+ for_characters all_characters - digits do
30
+ switch_to Dhaka::TOKENIZER_IDLE_STATE
31
+ end
32
+ for_characters digits do
33
+ curr_token.value << curr_char
34
+ advance
35
+ end
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + "/arithmetic_tokenizer"
3
+
4
+ class TestArithmeticTokenizer < Test::Unit::TestCase
5
+ def test_returns_end_of_input_token_for_empty_input
6
+ assert_equal([token(Dhaka::END_SYMBOL_NAME, nil)], ArithmeticTokenizer.tokenize([]).to_a)
7
+ end
8
+
9
+ def test_tokenizes_given_a_string_input
10
+ assert_equal([token('n', 2), token('-', nil), token('n', 4), token(Dhaka::END_SYMBOL_NAME, nil)], ArithmeticTokenizer.tokenize('2 - 4').to_a)
11
+ end
12
+
13
+ def test_a_longer_input
14
+ actual = ArithmeticTokenizer.tokenize('2+(3 / (7 - 5))').to_a
15
+ 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), token(Dhaka::END_SYMBOL_NAME, nil)], actual)
16
+ end
17
+
18
+ def test_another_input_with_multi_digit_numbers
19
+ actual = ArithmeticTokenizer.tokenize('2034 +(3433 / (7 - 5))').to_a
20
+ 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), token(Dhaka::END_SYMBOL_NAME, nil)], actual)
21
+ end
22
+
23
+ def test_an_input_with_unrecognized_characters
24
+ result = ArithmeticTokenizer.tokenize('2+(3 / (7 -& 5))')
25
+ assert(result.has_error?)
26
+ assert_equal(11, result.unexpected_char_index)
27
+ end
28
+
29
+ def test_another_input_with_illegal_characters
30
+ result = ArithmeticTokenizer.tokenize('2034 +(34b3 / (7 - 5))')
31
+ assert(result.has_error?)
32
+ assert_equal(9, result.unexpected_char_index)
33
+ end
34
+
35
+ def token(symbol_name, value)
36
+ Dhaka::Token.new(symbol_name, value ? value.to_s : nil, nil)
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/arithmetic_precedence_grammar'
2
+
3
+ class ArithmeticPrecedenceEvaluator < Dhaka::Evaluator
4
+
5
+ self.grammar = ArithmeticPrecedenceGrammar
6
+
7
+ define_evaluation_rules do
8
+
9
+ for_subtraction do
10
+ evaluate(child_nodes[0]) - evaluate(child_nodes[2])
11
+ end
12
+
13
+ for_addition do
14
+ evaluate(child_nodes[0]) + evaluate(child_nodes[2])
15
+ end
16
+
17
+ for_division do
18
+ evaluate(child_nodes[0]).to_f/evaluate(child_nodes[2])
19
+ end
20
+
21
+ for_multiplication do
22
+ evaluate(child_nodes[0]) * evaluate(child_nodes[2])
23
+ end
24
+
25
+ for_literal do
26
+ child_nodes[0].token.value.to_i
27
+ end
28
+
29
+ for_parenthetized_expression do
30
+ evaluate(child_nodes[1])
31
+ end
32
+
33
+ for_negated_expression do
34
+ -evaluate(child_nodes[1])
35
+ end
36
+
37
+ for_power do
38
+ evaluate(child_nodes[0])**evaluate(child_nodes[2])
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,24 @@
1
+ class ArithmeticPrecedenceGrammar < Dhaka::Grammar
2
+
3
+ precedences do
4
+ left %w| + - |
5
+ left %w| * / |
6
+ nonassoc %w| ^ |
7
+ end
8
+
9
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
10
+ expression %w| E |
11
+ end
12
+
13
+ for_symbol('E') do
14
+ addition %w| E + E |
15
+ subtraction %w| E - E |
16
+ multiplication %w| E * E |
17
+ division %w| E / E |
18
+ power %w| E ^ E |
19
+ literal %w| n |
20
+ parenthetized_expression %w| ( E ) |
21
+ negated_expression %w| - E |, :prec => '*'
22
+ end
23
+
24
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + '/arithmetic_precedence_grammar'
3
+
4
+ class TestArithmeticPrecedenceGrammar < Test::Unit::TestCase
5
+ def setup
6
+ @addop = ArithmeticPrecedenceGrammar.symbol_for_name('+')
7
+ @subop = ArithmeticPrecedenceGrammar.symbol_for_name('-')
8
+ @mulop = ArithmeticPrecedenceGrammar.symbol_for_name('*')
9
+ @divop = ArithmeticPrecedenceGrammar.symbol_for_name('/')
10
+ @powop = ArithmeticPrecedenceGrammar.symbol_for_name('^')
11
+ end
12
+
13
+ def test_precedence_levels_and_associativity_of_terminals
14
+ assert_equal(0, @addop.precedence.precedence_level)
15
+ assert_equal(0, @subop.precedence.precedence_level)
16
+ assert_equal(1, @mulop.precedence.precedence_level)
17
+ assert_equal(1, @divop.precedence.precedence_level)
18
+ assert_equal(2, @powop.precedence.precedence_level)
19
+ assert_equal(:left, @addop.precedence.associativity)
20
+ assert_equal(:left, @subop.precedence.associativity)
21
+ assert_equal(:left, @mulop.precedence.associativity)
22
+ assert_equal(:left, @divop.precedence.associativity)
23
+ assert_equal(:nonassoc, @powop.precedence.associativity)
24
+ end
25
+ def test_precedence_of_production
26
+ assert_equal(@addop.precedence, ArithmeticPrecedenceGrammar.production_named("addition").precedence)
27
+ assert_equal(@mulop.precedence, ArithmeticPrecedenceGrammar.production_named("multiplication").precedence)
28
+ assert_equal(@mulop.precedence, ArithmeticPrecedenceGrammar.production_named("negated_expression").precedence)
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ class ArithmeticPrecedenceLexerSpecification < Dhaka::LexerSpecification
2
+
3
+ for_pattern '\s' do
4
+ # ignore whitespace
5
+ end
6
+
7
+ %w| - h l , |.each do |char|
8
+ for_pattern char do
9
+ create_token(char)
10
+ end
11
+ end
12
+
13
+ %w| ( ) + / * ^ |.each do |char|
14
+ for_pattern "\\#{char}" do
15
+ create_token(char)
16
+ end
17
+ end
18
+
19
+ for_pattern '\d+' do
20
+ create_token('n')
21
+ end
22
+
23
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + "/arithmetic_precedence_grammar"
3
+ require File.dirname(__FILE__) + "/arithmetic_precedence_lexer_specification"
4
+ require File.dirname(__FILE__) + "/arithmetic_precedence_evaluator"
5
+
6
+ class TestArithmeticPrecedenceParser < Test::Unit::TestCase
7
+ def test_parses_arithmetic_expressions
8
+ fake_logger = FakeLogger.new
9
+ parser = Dhaka::Parser.new(ArithmeticPrecedenceGrammar, fake_logger)
10
+ lexer = Dhaka::Lexer.new(ArithmeticPrecedenceLexerSpecification)
11
+ eval(parser.compile_to_ruby_source_as(:ArithmeticPrecedenceParser))
12
+ eval(lexer.compile_to_ruby_source_as(:ArithmeticPrecedenceLexer))
13
+
14
+ assert_equal(30, fake_logger.warnings.size)
15
+ assert_equal(0, fake_logger.errors.size)
16
+
17
+ assert_equal(-8, evaluate(parse("5 * -14/(2*7 - 7) + 2")))
18
+ assert_equal(-4, evaluate(parse("-2^2")))
19
+ assert_equal(10, evaluate(parse("2+2^3")))
20
+ assert_equal(64, evaluate(parse("(2+2)^3")))
21
+ assert_equal(128, evaluate(parse("(2+2)^3*2")))
22
+ assert(parse("(2+2)^3^2").has_error?)
23
+ end
24
+
25
+ def parse(input)
26
+ ArithmeticPrecedenceParser.parse(ArithmeticPrecedenceLexer.lex(input))
27
+ end
28
+
29
+ def evaluate(parse_tree)
30
+ ArithmeticPrecedenceEvaluator.new.evaluate(parse_tree)
31
+ end
32
+ end
33
+
@@ -0,0 +1,23 @@
1
+ class BracketGrammar < Dhaka::Grammar
2
+
3
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
4
+ start %w| Package |
5
+ end
6
+
7
+ for_symbol('Package') do
8
+ soft_wrapped_package %w| ( Contents ) |
9
+ cardboard_package %w| [ Contents ] |
10
+ wooden_package %w| { Contents } |
11
+ end
12
+
13
+ for_symbol('Contents') do
14
+ bracket %w| B |
15
+ set_of_packages %w| SetOfPackages |
16
+ end
17
+
18
+ for_symbol('SetOfPackages') do
19
+ one_package %w| Package |
20
+ multiple_packages %w| SetOfPackages Package |
21
+ end
22
+
23
+ end
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/bracket_grammar'
2
+
3
+ class BracketTokenizer < Dhaka::Tokenizer
4
+
5
+ all_characters = %w| ( [ { B } ] ) |
6
+
7
+ for_state Dhaka::TOKENIZER_IDLE_STATE do
8
+ for_characters(all_characters) do
9
+ create_token(curr_char, nil)
10
+ advance
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ class LazyBracketTokenizer < BracketTokenizer
17
+ for_state Dhaka::TOKENIZER_IDLE_STATE do
18
+ for_default do
19
+ advance
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/../dhaka_test_helper'
2
+ require File.dirname(__FILE__) + "/bracket_grammar"
3
+ require File.dirname(__FILE__) + '/bracket_tokenizer'
4
+
5
+ class TestBracketGrammar < Test::Unit::TestCase
6
+ def test_recognizes_faulty_bracket_configuration_correctly
7
+ eval Dhaka::Parser.new(BracketGrammar).compile_to_ruby_source_as(:BracketParser)
8
+ assert correct("[{(B)[B]}(B)]")
9
+ assert correct("[[B]{(B)}(B)]")
10
+ assert correct("{(B)[B]}")
11
+ assert !correct("{B[B]}")
12
+ assert !correct("B")
13
+ assert !correct("[[B]{(B)}}(B)]")
14
+ end
15
+
16
+ def test_ignores_invalid_characters_with_default_action
17
+ tokens = BracketTokenizer.tokenize("A{(B)[B]}")
18
+ assert tokens.has_error?
19
+
20
+ tokens = LazyBracketTokenizer.tokenize("A{(B)[B]}")
21
+ assert !tokens.has_error?
22
+ end
23
+
24
+ def correct input_string
25
+ result = BracketParser.parse(BracketTokenizer.tokenize(input_string))
26
+ !result.has_error?
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + "/chittagong_lexer_specification"
2
+ require File.dirname(__FILE__) + "/chittagong_evaluator"
3
+
4
+ class ChittagongDriver
5
+
6
+ ERROR_MARKER = ">>>"
7
+
8
+ def parse_error_message unexpected_token, program
9
+ if unexpected_token.symbol_name == Dhaka::END_SYMBOL_NAME
10
+ "Unexpected end of file."
11
+ else
12
+ "Unexpected token #{unexpected_token.symbol_name}:\n#{program.dup.insert(unexpected_token.input_position, ERROR_MARKER)}"
13
+ end
14
+ end
15
+
16
+ def tokenize_error_message unexpected_char_index, program
17
+ "Unexpected character #{program[unexpected_char_index].chr}:\n#{program.dup.insert(unexpected_char_index, ERROR_MARKER)}"
18
+ end
19
+
20
+ def evaluation_error_message evaluation_result, program
21
+ "#{evaluation_result.exception}:\n#{program.dup.insert(evaluation_result.node.tokens[0].input_position, ERROR_MARKER)}"
22
+ end
23
+
24
+ # lipi:run_method
25
+ def run(program)
26
+ parse_result = ChittagongParser.parse(ChittagongLexer.lex(program))
27
+
28
+ case parse_result
29
+ when Dhaka::TokenizerErrorResult
30
+ return tokenize_error_message(parse_result.unexpected_char_index, program)
31
+ when Dhaka::ParseErrorResult
32
+ return parse_error_message(parse_result.unexpected_token, program)
33
+ end
34
+
35
+ evaluation_result = ChittagongEvaluator.new([{}], output_stream = []).
36
+ evaluate(parse_result)
37
+ if evaluation_result.exception
38
+ return (output_stream << evaluation_error_message(evaluation_result, program)).
39
+ join("\n")
40
+ end
41
+
42
+ return output_stream.join("\n")
43
+ end
44
+ # lipi:run_method
45
+
46
+ end