From: <bi...@us...> - 2010-05-25 19:27:05
|
Revision: 5977 http://oorexx.svn.sourceforge.net/oorexx/?rev=5977&view=rev Author: bigrixx Date: 2010-05-25 19:26:59 +0000 (Tue, 25 May 2010) Log Message: ----------- some work on complex back reference paths Modified Paths: -------------- incubator/regex/regex.cls incubator/regex/regex.testGroup Modified: incubator/regex/regex.cls =================================================================== --- incubator/regex/regex.cls 2010-05-25 16:55:41 UTC (rev 5976) +++ incubator/regex/regex.cls 2010-05-25 19:26:59 UTC (rev 5977) @@ -316,7 +316,7 @@ return pattern -- now in pattern form -- register additional named patterns with a compiler instance -::method registerNamedPatterns +::method registerNamedPattern expose namedPatterns use strict arg name, pattern name = name~upper -- make sure we always use an uppercase name @@ -1140,7 +1140,7 @@ end else do -- a more complex look up - condition = .ResultBackReferenceTestNode~new(path[1]) + condition = .ResultBackReferenceTestNode~new(path) end end else do @@ -2006,19 +2006,6 @@ when ch == 'k' then do -- a \k back reference can be complicated return self~parseNamedGroup - referenceName = self~extractDelimited('<', '>') - -- apply Rexx symbol rules to the name and make uppercase - referenceName = referenceName~upper - - if \self~haveGroup(referenceName) then do - raise syntax 93.900 array("Unrecognized group back reference:" referenceName) - end - if self~caselessMode then do - return .CaselessGroupBackReferenceNode~new(referenceName) - end - else do - return .GroupBackReferenceNode~new(referenceName) - end end -- reference to a registered pattern when ch == 'm' then do @@ -2085,10 +2072,9 @@ -- "group", while <group{result<subgroup>}> will return the value of -- group "subgroup" within named result "result" of group "group" ::method parseNamedGroup - use arg nested -- create an accumulator, and start parsing the potentially lengthy group name path = .array~new - self~parseGroupName + self~parseGroupName(path) -- the first level is all we can verify exists at this point if \self~haveGroup(path[1]) then do @@ -2107,10 +2093,10 @@ -- more complex path resolution required else do if self~caselessMode then do - return .CaselessGroupBackReferenceNode~new(path[1]) + return .CaselessResultBackReferenceNode~new(path) end else do - return .GroupBackReferenceNode~new(path[1]) + return .ResultBackReferenceNode~new(path) end end @@ -2190,7 +2176,7 @@ -- get the result portion self~parseResultName(path) -- perform the delimiter check - ch self~next + ch = self~next if ch \== '>' then do raise syntax 93.900 array("Missing closing '>' on group name") end @@ -2227,8 +2213,9 @@ self~previous -- get the result portion self~parseGroupName(path) - -- perform the delimiter check - ch self~next + -- perform the delimiter check. We should have + -- a } after the close of the group name. + ch = self~next if ch \== '}' then do raise syntax 93.900 array("Missing closing '}' on result name") end @@ -3694,6 +3681,7 @@ ::method matchText expose resultPath use arg context + -- the first two matches here are a little different, since -- there will a guarantee of 2 names and the first one comes -- from the current matching context. After that, the Modified: incubator/regex/regex.testGroup =================================================================== --- incubator/regex/regex.testGroup 2010-05-25 16:55:41 UTC (rev 5976) +++ incubator/regex/regex.testGroup 2010-05-25 19:26:59 UTC (rev 5977) @@ -2096,3 +2096,52 @@ -- some tests for the [] method on a match result self~assertEquals("pos...@oo...", r[]) self~assertEquals("postmaster", re["username"]) + +::method testBackReference + + + -- numbered group + p = .Pattern~compile("(abc)\1") + -- This should match twice + r = self~find(p, "abcabc") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "abcabc")) + self~assertTrue(self~verifyMatchResult(r~group("1"), 1, 4, "abc")) + + -- numbered group, fully qualified back reference sequence + p = .Pattern~compile("(abc)\k<1>") + -- This should match twice + r = self~find(p, "abcabc") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "abcabc")) + self~assertTrue(self~verifyMatchResult(r~group("1"), 1, 4, "abc")) + + -- named group + p = .Pattern~compile("(?<foo>abc)\k<foo>)") + -- This should match twice + r = self~find(p, "abcabc") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "abcabc")) + self~assertTrue(self~verifyMatchResult(r~group("Foo"), 1, 4, "abc")) + + -- case insensitive names + p = .Pattern~compile("(?<foo>abc)\k<FOO>)") + -- This should match twice + r = self~find(p, "abcabc") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "abcabc")) + self~assertTrue(self~verifyMatchResult(r~group("Foo"), 1, 4, "abc")) + + compiler = .RegexCompiler~new + compiler~registerNamedPattern("abc", "(?<foo>bar)") + p = .Pattern~compile("\m{abc}\k<0{abc}>", compiler) + -- should match everything + r = self~find(p, "barbar") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "barbar")) + -- same as above, but the group is defaulted + p = .Pattern~compile("\m{abc}\k<{abc}>", compiler) + -- should match everything + r = self~find(p, "barbar") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "barbar")) + + -- same, but the back reference path goes one level deeper + p = .Pattern~compile("\m{abc}\k<{abc<foo>}>", compiler) + -- should match everything + r = self~find(p, "barbar") + self~assertTrue(self~verifyMatchResult(r, 1, 7, "barbar")) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |