aurum 0.1.0

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