rockit 0.7.1 → 0.7.2
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/README +24 -160
- data/TODO +17 -17
- data/VERSION +1 -1
- data/doc/rockit_paper.pdf +0 -0
- data/lib/packrat/grammar.rb +139 -84
- data/rakefile +27 -9
- data/tests/acceptance/packrat/java/atest_java.rb +37 -0
- data/tests/acceptance/packrat/java/java.rb +136 -0
- data/tests/acceptance/packrat/java/t.rb +10 -0
- data/tests/acceptance/packrat/java/todo +10 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/Java.rats +446 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaConstant.rats +111 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaCore.rats +508 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaIdentifier.rats +62 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaSymbol.rats +38 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaTree.rats +40 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/JavaType.rats +61 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/Spacing.rats +36 -0
- data/tests/acceptance/packrat/java/xtc.lang.java/Symbol.rats +77 -0
- data/tests/acceptance/packrat/minibasic/README +13 -0
- data/tests/acceptance/packrat/minibasic/atest_minibasic.rb +151 -13
- data/tests/acceptance/packrat/minibasic/minibasic.rb +94 -76
- data/tests/acceptance/packrat/minibasic/mult3.basic +6 -0
- data/tests/acceptance/packrat/minibasic/sumeven.basic +19 -0
- data/tests/unit/packrat/test_ast.rb +116 -0
- data/tests/unit/packrat/test_interpreting_parser.rb +15 -55
- metadata +22 -59
- data/lib/rockit/prettyprint/box.rb +0 -60
- data/lib/rockit/prettyprint/renderer.rb +0 -41
- data/lib/rockit/prettyprint/text_renderer.rb +0 -47
- data/lib/rockit/tree/base.rb +0 -223
- data/lib/rockit/tree/enter_leave_visitor.rb +0 -12
- data/lib/rockit/tree/graphviz.rb +0 -69
- data/lib/rockit/tree/visitor.rb +0 -12
- data/lib/util/array_alternatives.rb +0 -20
- data/lib/util/enter_leave_visitor.rb +0 -69
- data/lib/util/graphviz_dot.rb +0 -182
- data/lib/util/string_location.rb +0 -42
- data/lib/util/visitor.rb +0 -49
- data/lib/util/visitor_combinators.rb +0 -14
- data/tests/acceptance/rockit/dparser/atest_any_operator.rb +0 -33
- data/tests/acceptance/rockit/dparser/atest_arithmetic_grammar.rb +0 -30
- data/tests/acceptance/rockit/dparser/atest_list_operator.rb +0 -57
- data/tests/acceptance/rockit/dparser/atest_mult_operator.rb +0 -60
- data/tests/acceptance/rockit/dparser/atest_operator_grammar.rb +0 -61
- data/tests/acceptance/rockit/dparser/atest_plus_operator.rb +0 -55
- data/tests/acceptance/rockit/dparser/atest_samples_calculator.rb +0 -14
- data/tests/acceptance/rockit/dparser/atest_samples_minibasic.rb +0 -20
- data/tests/acceptance/rockit/dparser/atest_samples_multifunccalculator.rb +0 -36
- data/tests/acceptance/rockit/dparser/atest_simple_grammar.rb +0 -34
- data/tests/acceptance/rockit/dparser/atest_speculative_code_action.rb +0 -128
- data/tests/acceptance/rockit/dparser/calc_tests_common.rb +0 -103
- data/tests/unit/parse/utest_ebnf_grammar.rb +0 -50
- data/tests/unit/parse/utest_expand_grammar.rb +0 -23
- data/tests/unit/parse/utest_grammar.rb +0 -160
- data/tests/unit/rockit/assembler/llvm/utest_instructions.rb +0 -41
- data/tests/unit/rockit/assembler/llvm/utest_module.rb +0 -19
- data/tests/unit/rockit/prettyprint/utest_box.rb +0 -44
- data/tests/unit/rockit/tree/utest_tree_base.rb +0 -301
- data/tests/unit/rockit/tree/utest_tree_enter_leave_visitor.rb +0 -69
- data/tests/unit/rockit/tree/utest_tree_visitor.rb +0 -63
- data/tests/unit/rockit/utest_grammar.rb +0 -145
- data/tests/unit/rockit/utest_grammar_symbol.rb +0 -11
- data/tests/unit/rockit/utest_maybe_operator.rb +0 -12
- data/tests/unit/rockit/utest_regexp_terminal.rb +0 -45
- data/tests/unit/rockit/utest_repetition_operators.rb +0 -35
- data/tests/unit/rockit/utest_rule.rb +0 -23
- data/tests/unit/rockit/utest_string_terminal.rb +0 -40
- data/tests/unit/util/utest_array_alternatives.rb +0 -23
- data/tests/unit/util/utest_enter_leave_visitor.rb +0 -89
- data/tests/unit/util/utest_string_location.rb +0 -42
- data/tests/unit/util/utest_visitor.rb +0 -92
- data/tests/unit/util/utest_visitor_combinators.rb +0 -64
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
class ATestListOperator < Test::Unit::TestCase
|
5
|
-
ListTestGrammar = Rockit::DParser::Grammar.new do
|
6
|
-
start :S, [list(:Number, ",")], value(0)
|
7
|
-
term :Number, [/[0-9]+/]
|
8
|
-
end
|
9
|
-
|
10
|
-
Parser = ListTestGrammar.new_parser
|
11
|
-
|
12
|
-
def test_01_two_value_list
|
13
|
-
ary = Parser.parse("1, 2")
|
14
|
-
assert_equal(["1", "2"], ary)
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_02_multi_value_list
|
18
|
-
ary = Parser.parse("1, 2, 34, 567,890")
|
19
|
-
assert_equal(["1", "2", "34", "567", "890"], ary)
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_03_single_value_list
|
23
|
-
ary = Parser.parse("9731")
|
24
|
-
assert_equal(["9731"], ary)
|
25
|
-
end
|
26
|
-
|
27
|
-
ListAndAstTestGrammar = Rockit::DParser::Grammar.new do
|
28
|
-
start :S, [list(:Digit)], ast(:S, 0)
|
29
|
-
term :Digit, [/[0-9]+/]
|
30
|
-
end
|
31
|
-
|
32
|
-
AstParser = ListAndAstTestGrammar.new_parser
|
33
|
-
|
34
|
-
def test_04_multiple_occurences_and_ast
|
35
|
-
ast = AstParser.parse("7,5,6,9")
|
36
|
-
assert_equal("S", ast.name)
|
37
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
38
|
-
assert_equal(1, ast.num_children)
|
39
|
-
assert_equal(["7", "5", "6", "9"], ast[0])
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_05_single_occurence_and_ast
|
43
|
-
ast = AstParser.parse("745")
|
44
|
-
assert_equal("S", ast.name)
|
45
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
46
|
-
assert_equal(1, ast.num_children)
|
47
|
-
assert_equal(["745"], ast[0])
|
48
|
-
end
|
49
|
-
|
50
|
-
def atest_06_no_occurence_and_ast
|
51
|
-
ast = AstParser.parse("")
|
52
|
-
assert_equal("S", ast.name)
|
53
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
54
|
-
assert_equal(1, ast.num_children)
|
55
|
-
assert_equal([], ast[0])
|
56
|
-
end
|
57
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
class ATestMultOperator < Test::Unit::TestCase
|
5
|
-
MultTestGrammar = Rockit::DParser::Grammar.new do
|
6
|
-
start :S, [mult(:Digit)], value(0)
|
7
|
-
term :Digit, [/[0-9]/]
|
8
|
-
end
|
9
|
-
|
10
|
-
Parser = MultTestGrammar.new_parser
|
11
|
-
|
12
|
-
def test_01_multiple_occurences
|
13
|
-
(2..20).each do |i|
|
14
|
-
digit = rand(10).to_s
|
15
|
-
ary = Parser.parse(digit * i)
|
16
|
-
assert_equal((1..i).map {digit}, ary)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_02_single_occurence
|
21
|
-
ary = Parser.parse("7")
|
22
|
-
assert_equal(["7"], ary)
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_03_no_occurence
|
26
|
-
ary = Parser.parse("")
|
27
|
-
assert_equal([], ary)
|
28
|
-
end
|
29
|
-
|
30
|
-
MultAndAstTestGrammar = Rockit::DParser::Grammar.new do
|
31
|
-
start :S, [mult(:Digit)], ast(:S, 0)
|
32
|
-
term :Digit, [/[0-9]/]
|
33
|
-
end
|
34
|
-
|
35
|
-
AstParser = MultAndAstTestGrammar.new_parser
|
36
|
-
|
37
|
-
def test_04_multiple_occurences_and_ast
|
38
|
-
ast = AstParser.parse("7 5 6 9")
|
39
|
-
assert_equal("S", ast.name)
|
40
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
41
|
-
assert_equal(1, ast.num_children)
|
42
|
-
assert_equal(["7", "5", "6", "9"], ast[0])
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_05_single_occurence_and_ast
|
46
|
-
ast = AstParser.parse("7")
|
47
|
-
assert_equal("S", ast.name)
|
48
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
49
|
-
assert_equal(1, ast.num_children)
|
50
|
-
assert_equal(["7"], ast[0])
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_06_no_occurence_and_ast
|
54
|
-
ast = AstParser.parse("")
|
55
|
-
assert_equal("S", ast.name)
|
56
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
57
|
-
assert_equal(1, ast.num_children)
|
58
|
-
assert_equal([], ast[0])
|
59
|
-
end
|
60
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
class ATestOperatorGrammar < Test::Unit::TestCase
|
5
|
-
MaybeTestGrammar = Rockit::DParser::Grammar.new do
|
6
|
-
start :M, [[:A, maybe(:Digit)]], ast(:M, 0, 1)
|
7
|
-
term :A, ["a"]
|
8
|
-
term :Digit, [/[0-9]+/]
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_01_use_maybe_parser
|
12
|
-
parser = MaybeTestGrammar.new_parser
|
13
|
-
|
14
|
-
ast = parser.parse "a1"
|
15
|
-
assert_equal("M", ast.name)
|
16
|
-
assert_kind_of(parser.astclass_of_name(:M), ast)
|
17
|
-
assert_equal(2, ast.num_children)
|
18
|
-
assert_equal("a", ast[0])
|
19
|
-
assert_equal("1", ast[1])
|
20
|
-
|
21
|
-
ast = parser.parse "a"
|
22
|
-
assert_equal("M", ast.name)
|
23
|
-
assert_kind_of(parser.astclass_of_name(:M), ast)
|
24
|
-
assert_equal(2, ast.num_children)
|
25
|
-
assert_equal("a", ast[0])
|
26
|
-
assert_equal(nil, ast[1])
|
27
|
-
end
|
28
|
-
|
29
|
-
OperatorTestGrammar = Rockit::DParser::Grammar.new do
|
30
|
-
start :Str, [[:A, plus(:B), plus(:A), mult(:C), maybe(:D)]],
|
31
|
-
ast(:Str, 0, 1, 3, 4)
|
32
|
-
term :A, ["a"]
|
33
|
-
term :B, ["b"]
|
34
|
-
term :C, ["c"]
|
35
|
-
term :D, ["d"]
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_02_use_parser
|
39
|
-
parser = OperatorTestGrammar.new_parser
|
40
|
-
ast = parser.parse "abbbac"
|
41
|
-
assert_equal("Str", ast.name)
|
42
|
-
assert_kind_of(parser.astclass_of_name(:Str), ast)
|
43
|
-
assert_equal(4, ast.num_children)
|
44
|
-
assert_equal("a", ast[0])
|
45
|
-
assert_equal(["b", "b", "b"], ast[1])
|
46
|
-
assert_equal(["c"], ast[2])
|
47
|
-
assert_equal(nil, ast[3])
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_03_use_parser
|
51
|
-
parser = OperatorTestGrammar.new_parser
|
52
|
-
ast = parser.parse "a b a c c d"
|
53
|
-
assert_equal("Str", ast.name)
|
54
|
-
assert_kind_of(parser.astclass_of_name(:Str), ast)
|
55
|
-
assert_equal(4, ast.num_children)
|
56
|
-
assert_equal("a", ast[0])
|
57
|
-
assert_equal(["b"], ast[1])
|
58
|
-
assert_equal(["c", "c"], ast[2])
|
59
|
-
assert_equal("d", ast[3])
|
60
|
-
end
|
61
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
class ATestPlusOperator < Test::Unit::TestCase
|
5
|
-
PlusTestGrammar = Rockit::DParser::Grammar.new do
|
6
|
-
start :S, [plus(:A)], value(0)
|
7
|
-
term :A, ["a"]
|
8
|
-
end
|
9
|
-
|
10
|
-
Parser = PlusTestGrammar.new_parser
|
11
|
-
|
12
|
-
|
13
|
-
def test_01_multiple_occurences
|
14
|
-
(2..20).each do |i|
|
15
|
-
ary = Parser.parse("a" * i)
|
16
|
-
assert_equal((1..i).map {"a"}, ary)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_02_single_occurence
|
21
|
-
ary = Parser.parse("a")
|
22
|
-
assert_equal(["a"], ary)
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_03_no_occurence
|
26
|
-
assert_raises(RuntimeError) {Parser.parse("b")}
|
27
|
-
end
|
28
|
-
|
29
|
-
PlusAndAstTestGrammar = Rockit::DParser::Grammar.new do
|
30
|
-
start :S, [plus(:Digit)], ast(:S, 0)
|
31
|
-
term :Digit, [/[0-9]/]
|
32
|
-
end
|
33
|
-
|
34
|
-
AstParser = PlusAndAstTestGrammar.new_parser
|
35
|
-
|
36
|
-
def test_04_multiple_occurences_and_ast
|
37
|
-
ast = AstParser.parse("7 5 6 9")
|
38
|
-
assert_equal("S", ast.name)
|
39
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
40
|
-
assert_equal(1, ast.num_children)
|
41
|
-
assert_equal(["7", "5", "6", "9"], ast[0])
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_05_single_occurence_and_ast
|
45
|
-
ast = AstParser.parse("7")
|
46
|
-
assert_equal("S", ast.name)
|
47
|
-
assert_kind_of(AstParser.astclass_of_name(:S), ast)
|
48
|
-
assert_equal(1, ast.num_children)
|
49
|
-
assert_equal(["7"], ast[0])
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_06_no_occurence_and_ast
|
53
|
-
assert_raises(RuntimeError) {AstParser.parse("b")}
|
54
|
-
end
|
55
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
require 'calculator/calculator'
|
4
|
-
|
5
|
-
require File.join(File.dirname(__FILE__), "calc_tests_common")
|
6
|
-
|
7
|
-
class ATestSamplesCalculator < Test::Unit::TestCase
|
8
|
-
include CalcTestsCommon
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@grammar = Samples::CalculatorGrammar
|
12
|
-
@calculator = Samples::Calculator.new
|
13
|
-
end
|
14
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
require 'minibasic/minibasic_grammar'
|
5
|
-
|
6
|
-
class ATestSamplesMinibasic < Test::Unit::TestCase
|
7
|
-
# Test the String regexp by itself since it is special
|
8
|
-
StringTermGrammar = Rockit::DParser::Grammar.new do
|
9
|
-
start :S, [["PRINT", :String, value(1)]]
|
10
|
-
term :String, /"[^"]*"/
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_01_string_term
|
14
|
-
parser = StringTermGrammar.new_parser
|
15
|
-
value = parser.parse 'PRINT "a"'
|
16
|
-
assert_equal('"a"', value)
|
17
|
-
end
|
18
|
-
|
19
|
-
MiniBasicParser = Samples::MiniBasicGrammar.new_parser
|
20
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
require 'calculator/multifunc_calculator'
|
4
|
-
|
5
|
-
require File.join(File.dirname(__FILE__), "calc_tests_common")
|
6
|
-
|
7
|
-
class ATestSamplesMultiFuncCalc < Test::Unit::TestCase
|
8
|
-
include CalcTestsCommon
|
9
|
-
|
10
|
-
def setup
|
11
|
-
@grammar = Samples::MultiFuncCalcGrammar
|
12
|
-
@calculator = Samples::MultiFuncCalculator.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_10_eval
|
16
|
-
assert_calc(8, "2^3")
|
17
|
-
|
18
|
-
# The calculator is the same between successive calls to assert_calc so
|
19
|
-
# the variables should retain their values
|
20
|
-
assert_calc(1, "a = 1")
|
21
|
-
assert_calc(-2, "b=-2")
|
22
|
-
assert_calc(-1, "a+b")
|
23
|
-
assert_calc(-97, "c = (3 - 100)")
|
24
|
-
assert_calc(-2*-97+(4*1), "(b*c)+(4*a)")
|
25
|
-
|
26
|
-
assert_calc(Math.log(2), "ln(2)")
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_11_exponentiation_is_right_associative
|
30
|
-
assert_calc(2**(3**3), "2^3^3")
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_12_precedence_and_associativity
|
34
|
-
assert_calc(15, "1+2*3^2-4")
|
35
|
-
end
|
36
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
|
4
|
-
class ATestSimpleGrammar < Test::Unit::TestCase
|
5
|
-
SimpleTestGrammar = Rockit::DParser::Grammar.new do
|
6
|
-
start :Str, [[:A, :B, :A, :C, ast(:Str, 0, 1, 3)]]
|
7
|
-
term :A, ["a"]
|
8
|
-
term :B, ["b"]
|
9
|
-
term :C, ["c"]
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_01_creation_of_grammar
|
13
|
-
assert_kind_of(Rockit::DParser::Grammar, SimpleTestGrammar)
|
14
|
-
assert_equal(1, SimpleTestGrammar.rules.length)
|
15
|
-
assert_equal(3, SimpleTestGrammar.terms.values.length)
|
16
|
-
assert_equal(:Str, SimpleTestGrammar.start_symbol)
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_02_creation_of_parser
|
20
|
-
parser = SimpleTestGrammar.new_parser
|
21
|
-
assert_kind_of(Rockit::DParser::Parser, parser)
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_03_use_parser
|
25
|
-
parser = SimpleTestGrammar.new_parser
|
26
|
-
ast = parser.parse "ab a\tc"
|
27
|
-
assert_equal("Str", ast.name)
|
28
|
-
assert_kind_of(parser.astclass_of_name(:Str), ast)
|
29
|
-
assert_equal(3, ast.num_children)
|
30
|
-
assert_equal("a", ast[0])
|
31
|
-
assert_equal("b", ast[1])
|
32
|
-
assert_equal("c", ast[2])
|
33
|
-
end
|
34
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rockit/dparser'
|
3
|
-
require 'rockit/symbol_table'
|
4
|
-
|
5
|
-
class ATestSpeculativeCodeAction < Test::Unit::TestCase
|
6
|
-
TestGrammar = Rockit::DParser::Grammar.new do
|
7
|
-
start :S, [[:Id, ast(:S, 0)]]
|
8
|
-
rule :Id, [[:AIdent]]
|
9
|
-
|
10
|
-
rule :AIdent, [
|
11
|
-
[:Ident,
|
12
|
-
# Speculative code that rejects match unless the ident starts with "A"
|
13
|
-
speculative do |parser|
|
14
|
-
parser.reject if parser.get_value_of_child(0)[0,1] != "A"
|
15
|
-
end,
|
16
|
-
# Final code
|
17
|
-
ast(:A, 0),
|
18
|
-
]
|
19
|
-
]
|
20
|
-
|
21
|
-
term :Ident, /[A-Za-z]+/
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_01_no_reject
|
25
|
-
parser = TestGrammar.new_parser
|
26
|
-
ast = parser.parse "ABBA"
|
27
|
-
assert_equal("S", ast.name)
|
28
|
-
assert_kind_of(parser.astclass_of_name(:S), ast)
|
29
|
-
assert_equal(1, ast.num_children)
|
30
|
-
assert_kind_of(parser.astclass_of_name(:A), ast[0])
|
31
|
-
assert_equal(1, ast[0].num_children)
|
32
|
-
assert_equal("ABBA", ast[0][0])
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_02_reject
|
36
|
-
parser = TestGrammar.new_parser
|
37
|
-
# Make sure "CDE" is not a valid parse even though it matches Ident
|
38
|
-
# since it should be rejected by the speculative action code
|
39
|
-
assert_raises(RuntimeError) {ast = parser.parse "CDE"}
|
40
|
-
assert_raises(RuntimeError) {ast = parser.parse "B"}
|
41
|
-
assert_raises(RuntimeError) {ast = parser.parse "D"}
|
42
|
-
assert_raises(RuntimeError) {ast = parser.parse "G"}
|
43
|
-
end
|
44
|
-
|
45
|
-
# This example is a more realistic one with a SymbolTable that saves
|
46
|
-
# symbols and indicates that they are type names.
|
47
|
-
SymbolTableTestGrammar = Rockit::DParser::Grammar.new do
|
48
|
-
parser_include Rockit::ParserSymbolTable
|
49
|
-
|
50
|
-
start :TranslationUnit, [
|
51
|
-
[mult(:Declaration), plus(:Assignment)],
|
52
|
-
], ast(:TU, 0, 1)
|
53
|
-
|
54
|
-
rule :Assignment, [
|
55
|
-
[:Identifier, "=", :Identifier, ast(:Assign, 0, 2)],
|
56
|
-
]
|
57
|
-
|
58
|
-
rule :Declaration, [
|
59
|
-
[plus(:StorageClassSpecifier), :Identifier, ";",
|
60
|
-
|
61
|
-
# Speculative code that inserts identifier into symbol table
|
62
|
-
# if it is a typedef.
|
63
|
-
speculative do |parser|
|
64
|
-
e0, e1 = parser.get_value_of_child(0), parser.get_value_of_child(1)
|
65
|
-
if e0.include?("typedef") && e1.name == "Identifier"
|
66
|
-
parser.symbol_table.add_typename(e1[0])
|
67
|
-
end
|
68
|
-
end,
|
69
|
-
|
70
|
-
ast(:Declaration, 0, 1),
|
71
|
-
],
|
72
|
-
]
|
73
|
-
|
74
|
-
rule :StorageClassSpecifier, [
|
75
|
-
['auto'], ['register'], ['static'], ['extern'], ['typedef'],
|
76
|
-
]
|
77
|
-
|
78
|
-
rule :Identifier, [
|
79
|
-
[:Ident,
|
80
|
-
|
81
|
-
# Speculative code here that rejects the ident if it is in the
|
82
|
-
# symbol table and is a type name
|
83
|
-
speculative do |parser|
|
84
|
-
e0 = parser.get_value_of_child(0)
|
85
|
-
parser.reject if parser.symbol_table.typename?(e0)
|
86
|
-
end,
|
87
|
-
|
88
|
-
ast(:Identifier, 0)
|
89
|
-
]
|
90
|
-
]
|
91
|
-
|
92
|
-
term :Ident, /[A-Za-z]+/
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_03_valid_with_symbol_table_but_without_typedef
|
96
|
-
parser = SymbolTableTestGrammar.new_parser
|
97
|
-
ast = parser.parse "A = B"
|
98
|
-
assert_equal("TU", ast.name)
|
99
|
-
assert_kind_of(parser.astclass_of_name(:TU), ast)
|
100
|
-
assert_equal(2, ast.num_children)
|
101
|
-
assert_equal(0, ast[0].length)
|
102
|
-
assert_equal(1, ast[1].length)
|
103
|
-
assert_equal("Assign", ast[1][0].name)
|
104
|
-
assert_equal("A", ast[1][0][0][0])
|
105
|
-
assert_equal("B", ast[1][0][1][0])
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_03_valid_with_symbol_table_and_typedef
|
109
|
-
parser = SymbolTableTestGrammar.new_parser
|
110
|
-
ast = parser.parse "typedef C; A = B"
|
111
|
-
assert_equal("TU", ast.name)
|
112
|
-
assert_kind_of(parser.astclass_of_name(:TU), ast)
|
113
|
-
assert_equal(2, ast.num_children)
|
114
|
-
assert_equal(1, ast[0].length)
|
115
|
-
assert_equal("Declaration", ast[0][0].name)
|
116
|
-
assert_equal("C", ast[0][0][1][0])
|
117
|
-
assert_equal(1, ast[1].length)
|
118
|
-
assert_equal("Assign", ast[1][0].name)
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_04_invalid_with_typedef_and_symbol_table
|
122
|
-
parser = SymbolTableTestGrammar.new_parser
|
123
|
-
# Should not parse ok since the typedef means the A cannot later be an
|
124
|
-
# identifier.
|
125
|
-
assert_raises(RuntimeError) {ast = parser.parse "typedef A; A = B"}
|
126
|
-
assert_raises(RuntimeError) {ast = parser.parse "typedef B; A = B"}
|
127
|
-
end
|
128
|
-
end
|