aurum 0.1.0

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 (28) hide show
  1. data/example/expression/expression.rb +29 -0
  2. data/lib/aurum.rb +10 -0
  3. data/lib/aurum/engine.rb +173 -0
  4. data/lib/aurum/grammar.rb +234 -0
  5. data/lib/aurum/lexical_table_generator.rb +423 -0
  6. data/lib/aurum/parsing_table_generator.rb +445 -0
  7. data/test/engine/lexer_test.rb +52 -0
  8. data/test/engine/semantic_attributes_test.rb +15 -0
  9. data/test/grammar_definition/character_class_definition_test.rb +28 -0
  10. data/test/grammar_definition/grammar_definition_test.rb +54 -0
  11. data/test/grammar_definition/lexical_definition_test.rb +56 -0
  12. data/test/grammar_definition/operator_precedence_definition_test.rb +35 -0
  13. data/test/grammar_definition/production_definition_test.rb +60 -0
  14. data/test/lexical_table_generator/automata_test.rb +74 -0
  15. data/test/lexical_table_generator/character_set_test.rb +73 -0
  16. data/test/lexical_table_generator/interval_test.rb +36 -0
  17. data/test/lexical_table_generator/pattern_test.rb +109 -0
  18. data/test/lexical_table_generator/subset_determinizer_test.rb +19 -0
  19. data/test/lexical_table_generator/table_generator_test.rb +126 -0
  20. data/test/parsing_table_generator/augmented_grammar_test.rb +45 -0
  21. data/test/parsing_table_generator/lalr_n_computation_test.rb +89 -0
  22. data/test/parsing_table_generator/lr_0_automata_test.rb +91 -0
  23. data/test/parsing_table_generator/lr_item_test.rb +33 -0
  24. data/test/parsing_table_generator/parsing_table_state_test.rb +39 -0
  25. data/test/parsing_table_generator/precedence_table_test.rb +28 -0
  26. data/test/parsing_table_generator/production_test.rb +9 -0
  27. data/test/test_helper.rb +103 -0
  28. metadata +78 -0
@@ -0,0 +1,33 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../')
2
+ require 'test_helper'
3
+
4
+ class LRItemTest < Test::Unit::TestCase
5
+ def test_should_return_dot_symbol
6
+ assert_equal T, LR_item(0, E, T, ID).dot_symbol
7
+ assert_equal ID, LR_item(1, E, T, ID).dot_symbol
8
+ end
9
+
10
+ def test_should_be_handle_if_at_right_most_position
11
+ assert LR_item(2, E, T, ID).handle?
12
+ assert !LR_item(1, E, T, ID).handle?
13
+ assert LR_item(0, E).handle?
14
+ end
15
+
16
+ def test_should_be_kernel_if_not_at_left_most_position
17
+ assert LR_item(2, E, T, ID).kernel?
18
+ assert LR_item(1, E, T, ID).kernel?
19
+ assert !LR_item(0, E, T, ID).kernel?
20
+ end
21
+
22
+ def test_should_return_zero_to_position_as_first_part
23
+ assert_equal [], LR_item(0, E, T, ID).first_part
24
+ assert_equal [T], LR_item(1, E, T, ID).first_part
25
+ assert_equal [T, ID], LR_item(2, E, T, ID).first_part
26
+ end
27
+
28
+ def test_should_return_position_to_end_as_second_part
29
+ assert_equal [T, ID], LR_item(0, E, T, ID).second_part
30
+ assert_equal [ID], LR_item(1, E, T, ID).second_part
31
+ assert_equal [], LR_item(2, E, T, ID).second_part
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../')
2
+ require 'test_helper'
3
+
4
+ class ParsingTableStateTest < Test::Unit::TestCase
5
+ def test_should_equal_to_state_with_same_items
6
+ state1 = parsing_table_state LR_item(1, E, T, T), LR_item(1, E, T)
7
+ state2 = parsing_table_state LR_item(1, E, T), LR_item(1, E, T, T)
8
+ assert_equal state1, state2
9
+ end
10
+
11
+ def test_should_be_read_reducable_if_contains_one_and_only_one_handle
12
+ assert parsing_table_state(LR_item(1, E, T)).read_reduce
13
+ assert !parsing_table_state(LR_item(1, E, T, T)).read_reduce
14
+ assert !parsing_table_state(LR_item(1, E, T, T), LR_item(1, E, T)).read_reduce
15
+ end
16
+
17
+ def test_should_not_add_duplicate_action
18
+ state = parsing_table_state(LR_item(1, E, T))
19
+ state[E] << Aurum::ReduceAction.new(production(E, T), true)
20
+ state[E] << Aurum::ReduceAction.new(production(E, T), true)
21
+ assert_equal 1, state[E].length
22
+ end
23
+
24
+ def test_should_be_consistent_if_contains_one_and_only_one_handle
25
+ assert parsing_table_state(LR_item(1, E, T)).consistent?
26
+ end
27
+
28
+ def test_should_be_consistent_if_contains_no_handle
29
+ assert parsing_table_state(LR_item(1, E, T, ID), LR_item(1, E, F, ID), LR_item(1, E, ID, F)).consistent?
30
+ end
31
+
32
+ def test_should_be_inconsistent_if_contains_handle_and_other_kernal_items
33
+ assert !parsing_table_state(LR_item(1, E, T), LR_item(1, E, T, ID)).consistent?
34
+ end
35
+
36
+ def test_should_return_all_direct_read_symbols
37
+ assert_equal [T], parsing_table_state(LR_item(1, E, T, T), LR_item(1, E, T)).direct_read
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../')
2
+ require 'test_helper'
3
+
4
+ class PrecedenceTableTest < Test::Unit::TestCase
5
+ OP_A, OP_B = terminal('+'), terminal('-')
6
+
7
+ def test_should_return_one_if_op_a_has_higher_precedence
8
+ precedences = precedence_table [[OP_A], [OP_B]]
9
+ assert_equal 1, precedences.compare(OP_A, OP_B)
10
+ end
11
+
12
+ def test_should_return_minus_one_if_op_a_has_lower_precedence
13
+ precedences = precedence_table [[OP_A], [OP_B]]
14
+ assert_equal -1, precedences.compare(OP_B, OP_A)
15
+ end
16
+
17
+ def test_should_return_one_if_ops_same_precedence_and_left_associativity
18
+ precedences = precedence_table [[OP_A, OP_B]]
19
+ assert_equal 1, precedences.compare(OP_A, OP_B)
20
+ assert_equal 1, precedences.compare(OP_B, OP_A)
21
+ end
22
+
23
+ def test_should_return_minus_one_if_ops_same_precedence_and_right_associativity
24
+ precedences = precedence_table [[OP_A, OP_B]], :right => [OP_A, OP_B]
25
+ assert_equal -1, precedences.compare(OP_A, OP_B)
26
+ assert_equal -1, precedences.compare(OP_B, OP_A)
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../')
2
+ require 'test_helper'
3
+
4
+ class ProductionTest < Test::Unit::TestCase
5
+ def test_should_return_last_terminal_as_opearator
6
+ production = production E, E, terminal('+'), E
7
+ assert_equal terminal('+'), production.operator
8
+ end
9
+ end
@@ -0,0 +1,103 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ require 'test/unit'
3
+ require 'aurum'
4
+
5
+ def terminal name
6
+ Aurum::Symbol.new name, true
7
+ end
8
+
9
+ def nonterminal name
10
+ Aurum::Symbol.new name, false
11
+ end
12
+
13
+ def production nt, *symbols
14
+ Aurum::Production.new nt, symbols
15
+ end
16
+
17
+ def LR_item position, nt, *symbols
18
+ Aurum::ParsingTableGenerator::LRItem.new production(nt, *symbols), position
19
+ end
20
+
21
+ def parsing_table_state *items
22
+ Aurum::ParsingTableGenerator::State.new items
23
+ end
24
+
25
+ def parser_generator(definition, precedences = [], associativities = {:left => [], :right => []})
26
+ Aurum::ParsingTableGenerator.new definition, precedences
27
+ end
28
+
29
+ def shift state
30
+ Aurum::ShiftAction.new state, false
31
+ end
32
+
33
+ def lookahead_shift state
34
+ Aurum::ShiftAction.new state, true
35
+ end
36
+
37
+ def read_reduce production_no
38
+ Aurum::ReduceAction.new production_no, true
39
+ end
40
+
41
+ def reduce production_no
42
+ Aurum::ReduceAction.new production_no, false
43
+ end
44
+
45
+ def precedence_table(precedences, associativities = {:left => [], :right => []})
46
+ Aurum::ParsingTableGenerator::PrecedenceTable.new precedences, associativities
47
+ end
48
+
49
+ String.class_eval do
50
+ def to_char_set
51
+ char_set = Aurum::CharacterSet.new
52
+ char_set << self
53
+ char_set
54
+ end
55
+
56
+ def to_pattern
57
+ Aurum::Pattern.from_string self
58
+ end
59
+ end
60
+
61
+ Aurum::CharacterSet.class_eval do
62
+ def intervals
63
+ @intervals
64
+ end
65
+ end
66
+
67
+ Test::Unit::TestCase.class_eval do
68
+ START, E, T, F, ID = nonterminal('$start'), nonterminal('E'), nonterminal('T'), nonterminal('F'), terminal('id')
69
+
70
+ SIMPLE_GRAMMAR_LR0 = {
71
+ E => [production(E, T, terminal('+'), T)],
72
+ T => [production(T, ID)]
73
+ }
74
+
75
+ EXPRESSION_GRAMMAR_LALR1 = {
76
+ E => [production(E, E, terminal('+'), T), production(E, T)],
77
+ T => [production(T, T, terminal('*'), F), production(T, F)],
78
+ F => [production(F, terminal('('), E, terminal(')')), production(F, ID)],
79
+ }
80
+
81
+ BNF, RLIST, RULE, SLIST = nonterminal('bnf'), nonterminal('rlist'), nonterminal('rule'), nonterminal('slist')
82
+ BNF_GRAMMAR_LALR2 = {
83
+ BNF => [production(BNF, RLIST)],
84
+ RLIST => [production(RLIST), production(RLIST, RLIST, RULE)],
85
+ RULE => [production(RULE, terminal('s'), terminal('->'), SLIST)],
86
+ SLIST => [production(SLIST), production(SLIST, SLIST, terminal('s'))]
87
+ }
88
+
89
+ STATEMENT = nonterminal 'statement'
90
+ IF_GRAMMAR_LALR2 = {
91
+ STATEMENT => [production(STATEMENT, terminal('if'), STATEMENT, terminal('then'), STATEMENT),
92
+ production(STATEMENT, terminal('if'), STATEMENT, terminal('then'), STATEMENT, terminal('else'), STATEMENT),
93
+ production(STATEMENT, terminal('stmt'))]
94
+ }
95
+
96
+ EXPRESSION_GRAMMAR = { E => [production(E, E, terminal('+'), E), production(E, E, terminal('*'), E), production(E, ID)]}
97
+ NOT_LALR_GRAMMAR = EXPRESSION_GRAMMAR
98
+
99
+ PATTERN_A, PATTERN_B, PATTERN_C = 'pattern_a'.to_pattern, 'pattern_b'.to_pattern, 'pattern_c'.to_pattern,
100
+ ABABB = Aurum::Pattern.concat(('a'.to_pattern | 'b'.to_pattern).kleene, 'abb'.to_pattern)
101
+ end
102
+
103
+
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: aurum
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-05-20 00:00:00 +10:00
8
+ summary: Aurum is a LALR(n) parser generator written in Ruby.
9
+ require_paths:
10
+ - lib
11
+ email: x at bjug dot org
12
+ homepage: http://rubyforge.org/projects/aurum
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: aurum
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Vincent Xu
31
+ files:
32
+ - example/expression
33
+ - example/expression/expression.rb
34
+ - lib/aurum
35
+ - lib/aurum/lexical_table_generator.rb
36
+ - lib/aurum/parsing_table_generator.rb
37
+ - lib/aurum/grammar.rb
38
+ - lib/aurum/engine.rb
39
+ - lib/aurum.rb
40
+ - test/parsing_table_generator
41
+ - test/parsing_table_generator/augmented_grammar_test.rb
42
+ - test/parsing_table_generator/lr_0_automata_test.rb
43
+ - test/parsing_table_generator/production_test.rb
44
+ - test/parsing_table_generator/parsing_table_state_test.rb
45
+ - test/parsing_table_generator/lr_item_test.rb
46
+ - test/parsing_table_generator/precedence_table_test.rb
47
+ - test/parsing_table_generator/lalr_n_computation_test.rb
48
+ - test/grammar_definition
49
+ - test/grammar_definition/grammar_definition_test.rb
50
+ - test/grammar_definition/character_class_definition_test.rb
51
+ - test/grammar_definition/lexical_definition_test.rb
52
+ - test/grammar_definition/operator_precedence_definition_test.rb
53
+ - test/grammar_definition/production_definition_test.rb
54
+ - test/lexical_table_generator
55
+ - test/lexical_table_generator/interval_test.rb
56
+ - test/lexical_table_generator/character_set_test.rb
57
+ - test/lexical_table_generator/automata_test.rb
58
+ - test/lexical_table_generator/pattern_test.rb
59
+ - test/lexical_table_generator/subset_determinizer_test.rb
60
+ - test/lexical_table_generator/table_generator_test.rb
61
+ - test/test_helper.rb
62
+ - test/engine
63
+ - test/engine/semantic_attributes_test.rb
64
+ - test/engine/lexer_test.rb
65
+ test_files: []
66
+
67
+ rdoc_options: []
68
+
69
+ extra_rdoc_files: []
70
+
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ requirements: []
76
+
77
+ dependencies: []
78
+