1// Copyright 2013 the V8 project authors. All rights reserved. 2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24description( 25'Test regular expression processing with alternatives that match consuming no characters' 26); 27 28var emptyStr = ""; 29var s1 = "xxxx"; 30var s2 = "aaaa"; 31var s3 = "aax"; 32var s4 = "abab"; 33var s5 = "ab"; 34var s6 = "xabx"; 35var s7 = "g0"; 36 37// Non-capturing empty first alternative greedy '*' 38var re1 = new RegExp(/(?:|a|z)*/); 39shouldBe('emptyStr.match(re1)', '[""]'); 40shouldBe('s1.match(re1)', '[""]'); 41shouldBe('s2.match(re1)', '["aaaa"]'); 42shouldBe('s3.match(re1)', '["aa"]'); 43 44// Non-capturing empty middle alternative greedy '*' 45var re2 = new RegExp(/(?:a||z)*/); 46shouldBe('emptyStr.match(re2)', '[""]'); 47shouldBe('s1.match(re2)', '[""]'); 48shouldBe('s2.match(re2)', '["aaaa"]'); 49shouldBe('s3.match(re2)', '["aa"]'); 50 51// Non-capturing empty last alternative greedy '*' 52var re3 = new RegExp(/(?:a|z|)*/); 53shouldBe('emptyStr.match(re3)', '[""]'); 54shouldBe('s1.match(re3)', '[""]'); 55shouldBe('s2.match(re3)', '["aaaa"]'); 56shouldBe('s3.match(re3)', '["aa"]'); 57 58// Capturing empty first alternative greedy '*' 59var re4 = new RegExp(/(|a|z)*/); 60shouldBe('emptyStr.match(re4)', '["", undefined]'); 61shouldBe('s1.match(re4)', '["", undefined]'); 62shouldBe('s2.match(re4)', '["aaaa", "a"]'); 63shouldBe('s3.match(re4)', '["aa", "a"]'); 64 65// Capturing empty middle alternative greedy '*' 66var re5 = new RegExp(/(a||z)*/); 67shouldBe('emptyStr.match(re5)', '["", undefined]'); 68shouldBe('s1.match(re5)', '["", undefined]'); 69shouldBe('s2.match(re5)', '["aaaa", "a"]'); 70shouldBe('s3.match(re5)', '["aa", "a"]'); 71 72// Capturing empty last alternative greedy '*' 73var re6 = new RegExp(/(a|z|)*/); 74shouldBe('emptyStr.match(re6)', '["", undefined]'); 75shouldBe('s1.match(re6)', '["", undefined]'); 76shouldBe('s2.match(re6)', '["aaaa", "a"]'); 77shouldBe('s3.match(re6)', '["aa", "a"]'); 78 79// Non-capturing empty first alternative fixed-count 80var re7 = new RegExp(/(?:|a|z){2,5}/); 81shouldBe('emptyStr.match(re7)', '[""]'); 82shouldBe('s1.match(re7)', '[""]'); 83shouldBe('s2.match(re7)', '["aaa"]'); 84shouldBe('s3.match(re7)', '["aa"]'); 85 86// Non-capturing empty middle alternative fixed-count 87var re8 = new RegExp(/(?:a||z){2,5}/); 88shouldBe('emptyStr.match(re8)', '[""]'); 89shouldBe('s1.match(re8)', '[""]'); 90shouldBe('s2.match(re8)', '["aaaa"]'); 91shouldBe('s3.match(re8)', '["aa"]'); 92 93// Non-capturing empty last alternative fixed-count 94var re9 = new RegExp(/(?:a|z|){2,5}/); 95shouldBe('emptyStr.match(re9)', '[""]'); 96shouldBe('s1.match(re9)', '[""]'); 97shouldBe('s2.match(re9)', '["aaaa"]'); 98shouldBe('s3.match(re9)', '["aa"]'); 99 100// Non-capturing empty first alternative non-greedy '*' 101var re10 = new RegExp(/(?:|a|z)*?/); 102shouldBe('emptyStr.match(re10)', '[""]'); 103shouldBe('s1.match(re10)', '[""]'); 104shouldBe('s2.match(re10)', '[""]'); 105shouldBe('s3.match(re10)', '[""]'); 106 107// Non-capturing empty middle alternative non-greedy '*' 108var re11 = new RegExp(/(?:a||z)*?/); 109shouldBe('emptyStr.match(re11)', '[""]'); 110shouldBe('s1.match(re11)', '[""]'); 111shouldBe('s2.match(re11)', '[""]'); 112shouldBe('s3.match(re11)', '[""]'); 113 114// Non-capturing empty last alternative non-greedy '*' 115var re12 = new RegExp(/(?:a|z|)*?/); 116shouldBe('emptyStr.match(re12)', '[""]'); 117shouldBe('s1.match(re12)', '[""]'); 118shouldBe('s2.match(re12)', '[""]'); 119shouldBe('s3.match(re12)', '[""]'); 120 121// Capturing empty first alternative non-greedy '*' 122var re13 = new RegExp(/(|a|z)*?/); 123shouldBe('emptyStr.match(re13)', '["", undefined]'); 124shouldBe('s1.match(re13)', '["", undefined]'); 125shouldBe('s2.match(re13)', '["", undefined]'); 126shouldBe('s3.match(re13)', '["", undefined]'); 127 128// Capturing empty middle alternative non-greedy '*' 129var re14 = new RegExp(/(a||z)*?/); 130shouldBe('emptyStr.match(re14)', '["", undefined]'); 131shouldBe('s1.match(re14)', '["", undefined]'); 132shouldBe('s2.match(re14)', '["", undefined]'); 133shouldBe('s3.match(re14)', '["", undefined]'); 134 135// Capturing empty last alternative non-greedy '*' 136var re15 = new RegExp(/(a|z|)*?/); 137shouldBe('emptyStr.match(re15)', '["", undefined]'); 138shouldBe('s1.match(re15)', '["", undefined]'); 139shouldBe('s2.match(re15)', '["", undefined]'); 140shouldBe('s3.match(re15)', '["", undefined]'); 141 142// Non-capturing empty first alternative greedy '?' 143var re16 = new RegExp(/(?:|a|z)?/); 144shouldBe('emptyStr.match(re16)', '[""]'); 145shouldBe('s1.match(re16)', '[""]'); 146shouldBe('s2.match(re16)', '["a"]'); 147shouldBe('s3.match(re16)', '["a"]'); 148 149// Non-capturing empty middle alternative greedy '?' 150var re17 = new RegExp(/(?:a||z)?/); 151shouldBe('emptyStr.match(re17)', '[""]'); 152shouldBe('s1.match(re17)', '[""]'); 153shouldBe('s2.match(re17)', '["a"]'); 154shouldBe('s3.match(re17)', '["a"]'); 155 156// Non-capturing empty last alternative greedy '?' 157var re18 = new RegExp(/(?:a|z|)?/); 158shouldBe('emptyStr.match(re18)', '[""]'); 159shouldBe('s1.match(re18)', '[""]'); 160shouldBe('s2.match(re18)', '["a"]'); 161shouldBe('s3.match(re18)', '["a"]'); 162 163// Capturing empty first alternative greedy '?' 164var re19 = new RegExp(/(|a|z)?/); 165shouldBe('emptyStr.match(re19)', '["", undefined]'); 166shouldBe('s1.match(re19)', '["", undefined]'); 167shouldBe('s2.match(re19)', '["a", "a"]'); 168shouldBe('s3.match(re19)', '["a", "a"]'); 169 170// Capturing empty middle alternative greedy '?' 171var re20 = new RegExp(/(a||z)?/); 172shouldBe('emptyStr.match(re20)', '["", undefined]'); 173shouldBe('s1.match(re20)', '["", undefined]'); 174shouldBe('s2.match(re20)', '["a", "a"]'); 175shouldBe('s3.match(re20)', '["a", "a"]'); 176 177// Capturing empty last alternative greedy '?' 178var re21 = new RegExp(/(a|z|)?/); 179shouldBe('emptyStr.match(re21)', '["", undefined]'); 180shouldBe('s1.match(re21)', '["", undefined]'); 181shouldBe('s2.match(re21)', '["a", "a"]'); 182shouldBe('s3.match(re21)', '["a", "a"]'); 183 184// Non-capturing empty first alternative non-greedy '?' 185var re22 = new RegExp(/(?:|a|z)??/); 186shouldBe('emptyStr.match(re22)', '[""]'); 187shouldBe('s1.match(re22)', '[""]'); 188shouldBe('s2.match(re22)', '[""]'); 189shouldBe('s3.match(re22)', '[""]'); 190 191// Non-capturing empty middle alternative non-greedy '?' 192var re23 = new RegExp(/(?:a||z)??/); 193shouldBe('emptyStr.match(re23)', '[""]'); 194shouldBe('s1.match(re23)', '[""]'); 195shouldBe('s2.match(re23)', '[""]'); 196shouldBe('s3.match(re23)', '[""]'); 197 198// Non-capturing empty last alternative non-greedy '?' 199var re24 = new RegExp(/(?:a|z|)??/); 200shouldBe('emptyStr.match(re24)', '[""]'); 201shouldBe('s1.match(re24)', '[""]'); 202shouldBe('s2.match(re24)', '[""]'); 203shouldBe('s3.match(re24)', '[""]'); 204 205// Capturing empty first alternative non-greedy '?' 206var re25 = new RegExp(/(|a|z)??/); 207shouldBe('emptyStr.match(re25)', '["", undefined]'); 208shouldBe('s1.match(re25)', '["", undefined]'); 209shouldBe('s2.match(re25)', '["", undefined]'); 210shouldBe('s3.match(re25)', '["", undefined]'); 211 212// Capturing empty middle alternative non-greedy '?' 213var re26 = new RegExp(/(a||z)??/); 214shouldBe('emptyStr.match(re26)', '["", undefined]'); 215shouldBe('s1.match(re26)', '["", undefined]'); 216shouldBe('s2.match(re26)', '["", undefined]'); 217shouldBe('s3.match(re26)', '["", undefined]'); 218 219// Capturing empty last alternative non-greedy '?' 220var re27 = new RegExp(/(a|z|)??/); 221shouldBe('emptyStr.match(re27)', '["", undefined]'); 222shouldBe('s1.match(re27)', '["", undefined]'); 223shouldBe('s2.match(re27)', '["", undefined]'); 224shouldBe('s3.match(re27)', '["", undefined]'); 225 226// Non-capturing empty first alternative greedy '*' non-terminal 227var re28 = new RegExp(/(?:|a|z)*x/); 228shouldBe('emptyStr.match(re28)', 'null'); 229shouldBe('s1.match(re28)', '["x"]'); 230shouldBe('s2.match(re28)', 'null'); 231shouldBe('s3.match(re28)', '["aax"]'); 232 233// Non-capturing empty middle alternative greedy '*' non-terminal 234var re29 = new RegExp(/(?:a||z)*x/); 235shouldBe('emptyStr.match(re29)', 'null'); 236shouldBe('s1.match(re29)', '["x"]'); 237shouldBe('s2.match(re29)', 'null'); 238shouldBe('s3.match(re29)', '["aax"]'); 239 240// Non-capturing empty last alternative greedy '*' non-terminal 241var re30 = new RegExp(/(?:a|z|)*x/); 242shouldBe('emptyStr.match(re30)', 'null'); 243shouldBe('s1.match(re30)', '["x"]'); 244shouldBe('s2.match(re30)', 'null'); 245shouldBe('s3.match(re30)', '["aax"]'); 246 247// Non-capturing two possibly empty alternatives greedy '*' 248var re31 = new RegExp(/(?:a*|b*)*/); 249shouldBe('emptyStr.match(re31)', '[""]'); 250shouldBe('s1.match(re31)', '[""]'); 251shouldBe('s3.match(re31)', '["aa"]'); 252shouldBe('s4.match(re31)', '["abab"]'); 253 254// Non-capturing two possibly empty non-greedy alternatives non-greedy '*' 255var re32 = new RegExp(/(?:a*?|b*?)*/); 256shouldBe('emptyStr.match(re32)', '[""]'); 257shouldBe('s1.match(re32)', '[""]'); 258shouldBe('s2.match(re32)', '["aaaa"]'); 259shouldBe('s4.match(re32)', '["abab"]'); 260shouldBe('s5.match(re32)', '["ab"]'); 261shouldBe('s6.match(re32)', '[""]'); 262 263// Three possibly empty alternatives with greedy + 264var re33 = new RegExp(/(?:(?:(?!))|g?|0*\*?)+/); 265shouldBe('emptyStr.match(re33)', '[""]'); 266shouldBe('s1.match(re33)', '[""]'); 267shouldBe('s7.match(re33)', '["g0"]'); 268 269// first alternative zero length fixed count 270var re34 = new RegExp(/(?:|a)/); 271shouldBe('emptyStr.match(re34)', '[""]'); 272shouldBe('s1.match(re34)', '[""]'); 273shouldBe('s2.match(re34)', '[""]'); 274shouldBe('s3.match(re34)', '[""]'); 275