-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduced more lightweight parsing model
This commit introduces LOTS of changes, most notably the following: - A parse now instantiates only one Match object. This object recieves an array of events in its initializer which contains information about how to generate the parse tree beneath it as needed. This change provides a significant speed boost and uses a lot less memory. - Added a case-insensitive primitive type that can be used as a quick substitute for regular expressions with the i option. This type uses backticks instead of quotes and follows the same conventions as double-quoted strings. - Rule#match was changed to Rule#parse to match GrammarMethods#parse. It also provides a much simpler interface when dealing with Rule objects because a plain string may be given instead of an Input. - Rule#test (and similarly Input#test) allow checking for a match without actually instantiating and returning one. This is faster than using Rule#parse when all that is needed is a quick check. - Rule[] can now be used to retrieve any Rule by its id. This is needed by Match objects to retrieve rule objects as needed to lazily instantiate submatches.
- Loading branch information
Showing
25 changed files
with
1,210 additions
and
944 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,48 @@ | ||
require File.expand_path('../helper', __FILE__) | ||
|
||
Citrus.load(File.expand_path('../_files/alias', __FILE__)) | ||
|
||
class AliasTest < Test::Unit::TestCase | ||
|
||
def test_terminal? | ||
rule = Alias.new | ||
assert_equal(false, rule.terminal?) | ||
end | ||
|
||
def test_match | ||
def test_exec | ||
grammar = Grammar.new { | ||
rule :a, :b | ||
rule :b, 'b' | ||
rule :b, 'abc' | ||
} | ||
|
||
match = grammar.parse('b') | ||
assert(match) | ||
assert_equal('b', match) | ||
assert_equal(1, match.length) | ||
rule = grammar.rule(:a) | ||
rule_b = grammar.rule(:b) | ||
events = rule.exec(Input.new('abc')) | ||
assert_equal([rule_b.id, CLOSE, 3], events) | ||
end | ||
|
||
def test_match_renamed | ||
def test_exec_miss | ||
grammar = Grammar.new { | ||
rule :a, ext(:b) { | ||
'a' + to_s | ||
} | ||
rule :b, 'b' | ||
rule :a, :b | ||
rule :b, 'abc' | ||
} | ||
|
||
match = grammar.parse('b') | ||
assert(match) | ||
assert('ab', match.value) | ||
|
||
assert_raise NoMatchError do | ||
match.b | ||
end | ||
rule = grammar.rule(:a) | ||
events = rule.exec(Input.new('def')) | ||
assert_equal([], events) | ||
end | ||
|
||
def test_peg | ||
match = AliasOne.parse('a') | ||
assert(match) | ||
end | ||
|
||
def test_included | ||
def test_exec_included | ||
grammar1 = Grammar.new { | ||
rule :a, 'a' | ||
rule :a, 'abc' | ||
} | ||
|
||
grammar2 = Grammar.new { | ||
include grammar1 | ||
rule :b, :a | ||
} | ||
|
||
match = grammar2.parse('a') | ||
assert(match) | ||
rule = grammar2.rule(:b) | ||
rule_a = grammar1.rule(:a) | ||
events = rule.exec(Input.new('abc')) | ||
assert_equal([rule_a.id, CLOSE, 3], events) | ||
end | ||
|
||
def test_to_s | ||
rule = Alias.new(:alpha) | ||
assert_equal('alpha', rule.to_s) | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,32 @@ | ||
require File.expand_path('../helper', __FILE__) | ||
|
||
class AndPredicateTest < Test::Unit::TestCase | ||
|
||
def test_terminal? | ||
rule = AndPredicate.new | ||
assert_equal(false, rule.terminal?) | ||
end | ||
|
||
def test_match | ||
rule = AndPredicate.new('a') | ||
def test_exec | ||
rule = AndPredicate.new('abc') | ||
events = rule.exec(Input.new('abc')) | ||
assert_equal([rule.id, CLOSE, 0], events) | ||
end | ||
|
||
match = rule.match(input('b')) | ||
assert_equal(nil, match) | ||
def test_exec_miss | ||
rule = AndPredicate.new('def') | ||
events = rule.exec(Input.new('abc')) | ||
assert_equal([], events) | ||
end | ||
|
||
match = rule.match(input('a')) | ||
assert(match) | ||
assert_equal('', match) | ||
assert_equal(0, match.length) | ||
def test_consumption | ||
rule = AndPredicate.new('abc') | ||
input = Input.new('abc') | ||
events = rule.exec(input) | ||
assert_equal(0, input.pos) | ||
end | ||
|
||
def test_to_s | ||
rule = AndPredicate.new('a') | ||
assert_equal('&"a"', rule.to_s) | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,41 @@ | ||
require File.expand_path('../helper', __FILE__) | ||
|
||
class ButPredicateTest < Test::Unit::TestCase | ||
|
||
def test_terminal? | ||
rule = ButPredicate.new | ||
assert_equal(false, rule.terminal?) | ||
end | ||
|
||
def test_match | ||
rule = ButPredicate.new('a') | ||
def test_exec | ||
rule = ButPredicate.new('abc') | ||
|
||
match = rule.match(input('b')) | ||
assert(match) | ||
assert_equal('b', match) | ||
assert_equal(1, match.length) | ||
events = rule.exec(Input.new('def')) | ||
assert_equal([rule.id, CLOSE, 3], events) | ||
|
||
match = rule.match(input('bbba')) | ||
assert(match) | ||
assert_equal('bbb', match) | ||
assert_equal(3, match.length) | ||
events = rule.exec(Input.new('defabc')) | ||
assert_equal([rule.id, CLOSE, 3], events) | ||
end | ||
|
||
match = rule.match(input('a')) | ||
assert_equal(nil, match) | ||
def test_exec_miss | ||
rule = ButPredicate.new('abc') | ||
events = rule.exec(Input.new('abc')) | ||
assert_equal([], events) | ||
end | ||
|
||
# ButPredicate must match at least one character. | ||
match = rule.match(input('')) | ||
assert_equal(nil, match) | ||
def test_consumption | ||
rule = ButPredicate.new('abc') | ||
|
||
input = Input.new('def') | ||
events = rule.exec(input) | ||
assert_equal(3, input.pos) | ||
|
||
input = Input.new('defabc') | ||
events = rule.exec(input) | ||
assert_equal(3, input.pos) | ||
end | ||
|
||
def test_to_s | ||
rule = ButPredicate.new('a') | ||
assert_equal('~"a"', rule.to_s) | ||
end | ||
|
||
end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.