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.
- data/example/expression/expression.rb +29 -0
- data/lib/aurum.rb +10 -0
- data/lib/aurum/engine.rb +173 -0
- data/lib/aurum/grammar.rb +234 -0
- data/lib/aurum/lexical_table_generator.rb +423 -0
- data/lib/aurum/parsing_table_generator.rb +445 -0
- data/test/engine/lexer_test.rb +52 -0
- data/test/engine/semantic_attributes_test.rb +15 -0
- data/test/grammar_definition/character_class_definition_test.rb +28 -0
- data/test/grammar_definition/grammar_definition_test.rb +54 -0
- data/test/grammar_definition/lexical_definition_test.rb +56 -0
- data/test/grammar_definition/operator_precedence_definition_test.rb +35 -0
- data/test/grammar_definition/production_definition_test.rb +60 -0
- data/test/lexical_table_generator/automata_test.rb +74 -0
- data/test/lexical_table_generator/character_set_test.rb +73 -0
- data/test/lexical_table_generator/interval_test.rb +36 -0
- data/test/lexical_table_generator/pattern_test.rb +109 -0
- data/test/lexical_table_generator/subset_determinizer_test.rb +19 -0
- data/test/lexical_table_generator/table_generator_test.rb +126 -0
- data/test/parsing_table_generator/augmented_grammar_test.rb +45 -0
- data/test/parsing_table_generator/lalr_n_computation_test.rb +89 -0
- data/test/parsing_table_generator/lr_0_automata_test.rb +91 -0
- data/test/parsing_table_generator/lr_item_test.rb +33 -0
- data/test/parsing_table_generator/parsing_table_state_test.rb +39 -0
- data/test/parsing_table_generator/precedence_table_test.rb +28 -0
- data/test/parsing_table_generator/production_test.rb +9 -0
- data/test/test_helper.rb +103 -0
- 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
|
data/test/test_helper.rb
ADDED
@@ -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
|
+
|