1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
require 'spec_helper'
module CompiledParserSpec
describe Runtime::CompiledParser, "for a grammar with two rules" do
attr_reader :parser
testing_grammar %{
grammar TwoRules
rule a
'a'
end
rule b
'bb'
end
end
}
before do
@parser = parser_class_under_test.new
end
it "allows its root to be specified" do
parser.parse('a').should_not be_nil
parser.parse('b').should be_nil
# Check that the temporary-override works:
parser.parse('bb', :root => :b).should_not be_nil
parser.parse('a', :root => :b).should be_nil
# Check that the temporary-override isn't sticky:
parser.parse('a').should_not be_nil
# Try a permanent override:
parser.root = :b
parser.parse('bb').should_not be_nil
parser.parse('a').should be_nil
end
it "allows the requirement that all input be consumed to be disabled" do
parser.parse('ab').should be_nil
# Try a temporary override, and check it's not sticky:
result = parser.parse('ab', :consume_all_input => false)
result.should_not be_nil
result.interval.should == (0...1)
parser.parse('ab').should be_nil
# Now a permanent override:
parser.consume_all_input = false
result = parser.parse('ab')
result.should_not be_nil
result.interval.should == (0...1)
end
it "allows input to be parsed at a given index" do
parser.parse('ba').should be_nil
parser.parse('ba', :index => 1).should_not be_nil
# Check that the index defaults again to zero:
parser.parse('a').should_not be_nil
result = parser.parse('ba', :consume_all_input => false, :index => 1)
result.should_not be_nil
result.interval.should == (1...2)
end
end
describe Runtime::CompiledParser, "for a grammar with a choice between terminals" do
attr_reader :parser
testing_grammar %{
grammar Choice
rule choice
'a' / 'b' / 'c'
end
end
}
before do
@parser = parser_class_under_test.new
end
it "provides #failure_reason, #failure_column, and #failure_line when there is a parse failure" do
parser.parse('z').should be_nil
parser.failure_reason.should == "Expected one of 'a', 'b', 'c' at line 1, column 1 (byte 1)"
parser.failure_line.should == 1
parser.failure_column.should == 1
end
end
describe Runtime::CompiledParser, "#terminal_failures" do
attr_reader:parser
testing_grammar %{
grammar SequenceOfTerminals
rule foo
'a' 'b' 'c'
end
end
}
before do
@parser = parser_class_under_test.new
end
it "is reset between parses" do
parser.parse('ac')
terminal_failures = parser.terminal_failures
terminal_failures.size.should == 1
failure = terminal_failures.first
failure.index.should == 1
failure.expected_string.should == "'b'"
parser.parse('b')
terminal_failures = parser.terminal_failures
terminal_failures.size.should == 1
failure = terminal_failures.first
failure.index.should == 0
failure.expected_string.should == "'a'"
end
end
describe "a SyntaxNode" do
attr_reader :parser
testing_grammar %{
grammar Alternates
rule main
aa &{|s| s[0].elements[0].parent.should == s[0] }
/ ab &{|s| s[0].elements[0].parent.should == s[0] }
end
rule aa
'a' 'a'
end
rule ab
'a' 'b'
end
end
}
before do
@parser = parser_class_under_test.new
end
it "should have its parent set and reset" do
parser.parse('ab')
end
end
end
|