thorrparse.cpp 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef U_OVERRIDE_CXX_ALLOCATION
  14. #define U_OVERRIDE_CXX_ALLOCATION 0 // Enabling this forces all allocation of ICU objects to ICU's heap, but is incompatible with jmemleak
  15. #endif
  16. #include "jliball.hpp"
  17. #include "junicode.hpp"
  18. #include "thorrparse.ipp"
  19. #include "thorregex.hpp"
  20. #include "eclrtl.hpp"
  21. #include "thorcommon.ipp"
  22. #include "unicode/utf.h"
  23. #include "unicode/uchar.h"
  24. #include "unicode/schriter.h"
  25. #include "unicode/coll.h"
  26. #include "unicode/ustring.h"
  27. #ifdef TRACE_REGEX
  28. #define MATCH traceMatch
  29. #else
  30. #define MATCH match
  31. #endif
  32. #define TRANSFORM_BEFORE_CREATE_LIMIT 4096 // Over this size, transform into a temp
  33. #define REGEX_VERSION 4
  34. #define REGEXERR_IncompatibleVersion 1000
  35. #define REGEXERR_MatchFailure 1001
  36. #define REGEXERR_IncompatibleVersion_Text "Serialized regex library is not compatible, please rebuild workunit"
  37. #define REGEXERR_MatchFailure_Text "Failed to match pattern: pattern too complicated (offset %d)"
  38. static const char * getPatternText(ThorRegexKind kind)
  39. {
  40. switch (kind)
  41. {
  42. case ThorRegexNull: return "Null";
  43. case ThorRegexAnyChar: return "AnyChar";
  44. case ThorRegexAsciiDFA: return "AsciiDFA";
  45. case ThorRegexUnicodeDFA: return "UnicodeDFA";
  46. case ThorRegexAscii: return "Ascii";
  47. case ThorRegexAsciiI: return "AsciiI";
  48. case ThorRegexAsciiSet: return "AsciiSet";
  49. case ThorRegexAsciiISet: return "AsciiISet";
  50. case ThorRegexUnicode: return "Unicode";
  51. case ThorRegexUnicodeI: return "UnicodeI";
  52. case ThorRegexUnicodeSet: return "UnicodeSet";
  53. case ThorRegexUnicodeISet: return "UnicodeISet";
  54. case ThorRegexUtf8: return "Utf8";
  55. case ThorRegexUtf8I: return "Utf8I";
  56. case ThorRegexStart: return "Start";
  57. case ThorRegexFinish: return "Finish";
  58. case ThorRegexBeginToken: return "BeginToken";
  59. case ThorRegexEndToken: return "EndToken";
  60. case ThorRegexBeginSeparator: return "BeginSeparator";
  61. case ThorRegexEndSeparator: return "EndSeparator";
  62. case ThorRegexRepeat: return "Repeat";
  63. case ThorRegexBeginCheck: return "BeginCheck";
  64. case ThorRegexCheck: return "Check";
  65. case ThorRegexCheckLength: return "CheckLength";
  66. case ThorRegexAssertNext: return "AssertNext";
  67. case ThorRegexAssertPrev: return "AssertPrev";
  68. case ThorRegexNamed: return "Named";
  69. case ThorRegexEndNamed: return "EndNamed";
  70. case ThorRegexEndNested: return "EndNested";
  71. case ThorRegexDone: return "Done";
  72. case ThorRegexRepeatInstance: return "RepeatInstance";
  73. case ThorRegexValidateAscAsAsc: return "ValidateAscAsAsc";
  74. case ThorRegexValidateUniAsAsc: return "ValidateUniAsAsc" ;
  75. case ThorRegexValidateUtf8AsAsc: return "ValidateUtf8AsAsc" ;
  76. case ThorRegexValidateAscAsUni: return "ValidateAscAsUni" ;
  77. case ThorRegexValidateUniAsUni: return "ValidateUniAsUni";
  78. case ThorRegexValidateUtf8AsUni: return "ValidateUtf8AsUni" ;
  79. case ThorRegexRecursive: return "Recursive";
  80. case ThorRegexEndRecursive: return "EndRecursive";
  81. case ThorRegexPenalty: return "Penalty";
  82. case ThorRegexRepeatAny: return "RepeatAny";
  83. }
  84. UNIMPLEMENTED;
  85. }
  86. static const char * resultText[] = { "Done", "Backtrack", "TokenBack", "Continue" };
  87. #ifdef TRACE_REGEX
  88. static unsigned patternDepth;
  89. #endif
  90. bool isAsciiMatch(unsigned code, unsigned next)
  91. {
  92. switch (code)
  93. {
  94. case RCCalnum: return isalnum(next) != 0;
  95. case RCCcntrl: return iscntrl(next) != 0;
  96. case RCClower: return islower(next) != 0;
  97. case RCCupper: return isupper(next) != 0;
  98. case RCCspace: return isspace(next) != 0;
  99. case RCCalpha: return isalpha(next) != 0;
  100. case RCCdigit: return isdigit(next) != 0;
  101. case RCCprint: return isprint(next) != 0;
  102. case RCCblank: return (next == ' ' || next == '\t'); // return isblank(next);
  103. case RCCgraph: return isgraph(next) != 0;
  104. case RCCpunct: return ispunct(next) != 0;
  105. case RCCxdigit: return isxdigit(next) != 0;
  106. case RCCany: return true;
  107. default:
  108. UNIMPLEMENTED;
  109. }
  110. }
  111. bool isUnicodeMatch(unsigned code, unsigned next)
  112. {
  113. switch (code)
  114. {
  115. case RCCalnum: return u_isalnum(next) != 0;
  116. case RCCcntrl: return u_iscntrl(next) != 0;
  117. case RCClower: return u_islower(next) != 0;
  118. case RCCupper: return u_isupper(next) != 0;
  119. case RCCspace: return u_isWhitespace(next) != 0;
  120. case RCCalpha: return u_isalpha(next) != 0;
  121. case RCCdigit: return u_isdigit(next) != 0;
  122. case RCCprint: return u_isprint(next) != 0;
  123. case RCCblank: return u_isspace(next) != 0 || (next == '\t');
  124. case RCCgraph: return u_isprint(next) && !u_isspace(next);
  125. case RCCpunct: return u_isprint(next) && !(u_isspace(next) || u_isalnum(next));
  126. case RCCxdigit: return (next < 128) && isxdigit(next); // should be good enough.
  127. case RCCany: return true;
  128. default:
  129. UNIMPLEMENTED;
  130. }
  131. }
  132. //Anyone got some better code - this works, but isn't wonderfully efficient.
  133. //works by accessing esp[-4096] and seeing if it dies.
  134. inline void checkStackOverflow(unsigned offset)
  135. {
  136. try
  137. {
  138. doStackProbe();
  139. }
  140. catch (...)
  141. {
  142. throwError1(REGEXERR_MatchFailure, offset);
  143. }
  144. }
  145. //---------------------------------------------------------------------------
  146. void serializeLink(MemoryBuffer & out, RegexPattern * pattern, RegexSerializeState & state)
  147. {
  148. unsigned match = state.patterns.find(*pattern);
  149. assertex(match != NotFound);
  150. out.append(match);
  151. }
  152. RegexPattern * deserializeLink(MemoryBuffer & in, RegexSerializeState & state)
  153. {
  154. unsigned match;
  155. in.read(match);
  156. return LINK(&state.patterns.item(match));
  157. }
  158. void serializeName(MemoryBuffer & out, RegexNamed * pattern, RegexSerializeState & state)
  159. {
  160. unsigned match = state.named.find(*pattern);
  161. assertex(match != NotFound);
  162. out.append(match);
  163. }
  164. RegexNamed * deserializeName(MemoryBuffer & in, RegexSerializeState & state)
  165. {
  166. unsigned match;
  167. in.read(match);
  168. return LINK(&state.named.item(match));
  169. }
  170. MemoryBuffer & serializeKind(MemoryBuffer & out, ThorRegexKind kind)
  171. {
  172. return out.append((byte)kind);
  173. }
  174. void deserialize(MemoryBuffer & in, IAtom * & name)
  175. {
  176. StringAttr x;
  177. in.read(x);
  178. name = createAtom(x);
  179. }
  180. //---------------------------------------------------------------------------
  181. static MatchState * findTrailingSeparator(MatchState & matched)
  182. {
  183. MatchState * child = matched.firstChild;
  184. while (child)
  185. {
  186. //find the last child.
  187. MatchState * next = child->next;
  188. while (next)
  189. {
  190. child = next;
  191. next = child->next;
  192. }
  193. //If the last child is a separator that matches the last offset of the matched token, adjust the end
  194. if (child->queryName() == separatorTagAtom)
  195. return child;
  196. child = child->firstChild;
  197. }
  198. return NULL;
  199. }
  200. static void removeTrailingSeparator(MatchState & matched)
  201. {
  202. MatchState * child = findTrailingSeparator(matched);
  203. if (child && child->end == matched.end)
  204. matched.end = child->start;
  205. }
  206. MatchState * RegexMatchSearchInstance::find(MatchState * top, const NlpMatchPath & path, unsigned depth)
  207. {
  208. regexid_t id = path.getId(depth);
  209. do
  210. {
  211. if (top->queryID() == id)
  212. {
  213. bool matchAny = path.matchAny(depth);
  214. if (matchAny || (nextIndex == 1))
  215. {
  216. if (depth+1 == path.numItems())
  217. {
  218. lastExactMatchDepth = depth+1;
  219. return top;
  220. }
  221. if (!matchAny)
  222. {
  223. lastExactMatchDepth = depth+1;
  224. nextIndex = path.nextExactMatchIndex(depth+1);
  225. }
  226. MatchState * ret = NULL;
  227. unsigned prevExactMatchDepth = lastExactMatchDepth;
  228. if (top->firstChild)
  229. ret = find(top->firstChild, path, depth+1);
  230. //If must match a child, or one of children had a required match then we have a result
  231. if (!matchAny || (prevExactMatchDepth != lastExactMatchDepth))
  232. return ret;
  233. }
  234. else
  235. nextIndex--;
  236. }
  237. else
  238. {
  239. if (top->firstChild)
  240. {
  241. unsigned prevExactMatchDepth = lastExactMatchDepth;
  242. MatchState * ret = find(top->firstChild, path, depth);
  243. //return if matched another level - may have failed to match, or matched completely
  244. if (prevExactMatchDepth != lastExactMatchDepth)
  245. return ret;
  246. }
  247. }
  248. top = top->next;
  249. } while (top);
  250. return NULL;
  251. }
  252. IMatchedElement * RegexMatchPath::getMatch(MatchState * top, bool removeTrailingSep) const
  253. {
  254. RegexMatchSearchInstance search;
  255. search.lastExactMatchDepth = 0;
  256. search.nextIndex = nextExactMatchIndex(0);
  257. MatchState * state = search.find(top, *this, 0);
  258. if (!state)
  259. return NULL;
  260. if (removeTrailingSep)
  261. removeTrailingSeparator(*state);
  262. return new CMatchedElement(state);
  263. }
  264. //---------------------------------------------------------------------------
  265. void CRegexMatchedResults::extractResults(MatchState & top, const byte * _in, bool removeTrailingSeparator)
  266. {
  267. in = _in;
  268. notMatched.ptr = in;
  269. ForEachItemIn(idx, def->matchResults)
  270. {
  271. ::Release(matched[idx]);
  272. matched[idx] = ((RegexMatchPath&)def->matchResults.item(idx)).getMatch(&top, removeTrailingSeparator);
  273. if (!matched[idx]) matched[idx] = LINK(&notMatched);
  274. }
  275. }
  276. //---------------------------------------------------------------------------
  277. static const char * stateText[] = { "Init", "Follow", "Retry", "Finished", "Repeat", "FollowOnly", "RepeatOnly", "DoneRepeat" };
  278. #ifdef TRACE_REGEX
  279. ActiveStage & ActiveStage::setState(unsigned _state)
  280. {
  281. DBGLOG("%*s[%p]Change state to %s", patternDepth, "", pattern, stateText[_state]);
  282. state = _state;
  283. return *this;
  284. }
  285. #endif
  286. //---------------------------------------------------------------------------
  287. static void disposeLink(Owned<RegexPattern> & pattern)
  288. {
  289. if (pattern)
  290. {
  291. RegexPattern * cur = pattern.getClear();
  292. cur->dispose();
  293. cur->Release();
  294. }
  295. }
  296. static void disposeName(Owned<RegexNamed> & named)
  297. {
  298. if (named)
  299. {
  300. RegexNamed * cur = named.getClear();
  301. cur->dispose();
  302. cur->Release();
  303. }
  304. }
  305. RegexPattern::RegexPattern()
  306. {
  307. gathered = false;
  308. }
  309. void RegexPattern::dispose()
  310. {
  311. while (next.ordinality())
  312. {
  313. RegexPattern & cur = next.popGet();
  314. cur.dispose();
  315. cur.Release();
  316. }
  317. }
  318. bool RegexPattern::gather(RegexSerializeState & state)
  319. {
  320. if (gathered)
  321. return false;
  322. gathered = true;
  323. state.patterns.append(OLINK(*this));
  324. gatherNext(state);
  325. return true;
  326. }
  327. void RegexPattern::gatherNext(RegexSerializeState & state)
  328. {
  329. ForEachItemIn(idx, next)
  330. next.item(idx).gather(state);
  331. }
  332. void RegexPattern::serializePattern(MemoryBuffer & out)
  333. {
  334. serializeKind(out, getKind());
  335. }
  336. void RegexPattern::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  337. {
  338. out.append((unsigned)next.ordinality());
  339. ForEachItemIn(idx, next)
  340. serializeLink(out, &next.item(idx), state);
  341. }
  342. void RegexPattern::deserializePattern(MemoryBuffer & in)
  343. {
  344. }
  345. void RegexPattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  346. {
  347. unsigned nextCount;
  348. in.read(nextCount);
  349. for (unsigned idx=0; idx < nextCount; idx++)
  350. next.append(*deserializeLink(in, state));
  351. }
  352. RegexMatchAction RegexPattern::matchNext(RegexState & state)
  353. {
  354. unsigned num = next.ordinality();
  355. assertex(num);
  356. if (num == 1)
  357. return next.item(0).MATCH(state);
  358. const byte * saved = state.cur;
  359. for (unsigned idx = 0; idx < num; idx++)
  360. {
  361. RegexMatchAction ret = next.item(idx).MATCH(state);
  362. if (ret != RegexMatchBacktrack)
  363. return ret;
  364. state.cur = saved;
  365. }
  366. return RegexMatchBacktrack;
  367. }
  368. inline RegexMatchAction RegexPattern::pushMatched(RegexState & state)
  369. {
  370. pushStage(state).setMatched();
  371. return RegexMatchContinue;
  372. }
  373. inline RegexMatchAction RegexPattern::markFinishContinueMatch(RegexState & state)
  374. {
  375. MatchSaveState saved;
  376. state.markFinish(saved);
  377. RegexMatchAction ret = matchNext(state);
  378. state.unmarkFinish(saved);
  379. return ret;
  380. }
  381. ActiveStage & RegexPattern::pushStageBeginMatch(RegexState & state, RegexMatchStateSave * matched)
  382. {
  383. ActiveStage & stage = pushStage(state);
  384. stage.setMatched();
  385. stage.extra.matched = matched;
  386. state.pushMatch(*matched, matched->save);
  387. #ifdef TRACE_REGEX
  388. DBGLOG("%*s[%p]Push Begin Match", patternDepth, "", stage.pattern);
  389. #endif
  390. return stage;
  391. }
  392. void RegexPattern::cleanupBeginMatch(ActiveStage & stage, RegexState & state)
  393. {
  394. #ifdef TRACE_REGEX
  395. DBGLOG("%*s[%p]Pop Begin Match", patternDepth, "", stage.pattern);
  396. #endif
  397. state.popMatch(stage.extra.matched->save);
  398. state.cache.destroyStateSave(stage.extra.matched);
  399. stage.extra.matched = NULL;
  400. }
  401. RegexMatchAction RegexPattern::pushStageEndMatch(RegexState & state)
  402. {
  403. ActiveStage & stage = pushStage(state);
  404. stage.setMatched();
  405. state.markFinish(stage.extra.saved);
  406. #ifdef TRACE_REGEX
  407. DBGLOG("%*s[%p]Push End Match", patternDepth, "", stage.pattern);
  408. #endif
  409. return RegexMatchContinue;
  410. }
  411. void RegexPattern::cleanupEndMatch(ActiveStage & stage, RegexState & state)
  412. {
  413. #ifdef TRACE_REGEX
  414. DBGLOG("%*s[%p]Pop End Match", patternDepth, "", stage.pattern);
  415. #endif
  416. state.unmarkFinish(stage.extra.saved);
  417. }
  418. RegexMatchAction RegexPattern::traceMatch(RegexState & state)
  419. {
  420. static unsigned i;
  421. StringBuffer s,t;
  422. unsigned len = (size32_t)(state.end-state.cur);
  423. if (len > 10) len = 10;
  424. getTraceText(t);
  425. s.appendN(i++, ' ').appendf("Begin %s [%p] >%.*s<", t.str(), this, len, state.cur);
  426. DBGLOG("%s", s.str());
  427. RegexMatchAction ret = match(state);
  428. s.clear().appendN(--i, ' ').appendf("End %s [%p] = %s", t.str(), this, resultText[ret]);
  429. DBGLOG("%s", s.str());
  430. return ret;
  431. }
  432. void RegexPattern::getTraceText(StringBuffer & s)
  433. {
  434. s.append(getPatternText(getKind()));
  435. }
  436. void RegexPattern::toXML(StringBuffer & out, RegexXmlState & state)
  437. {
  438. out.appendf("\t<expr id=\"%d\"", state.patterns.find(*this));
  439. toXMLattr(out,state);
  440. if (next.ordinality())
  441. {
  442. out.append(">").newline();
  443. ForEachItemIn(idx, next)
  444. {
  445. out.appendf("\t\t<next id=\"%d\"/>", state.patterns.find(next.item(idx))).newline();
  446. }
  447. out.append("\t</expr>").newline();
  448. ForEachItemInRev(idx2, next)
  449. state.addLink(next.item(idx2));
  450. }
  451. else
  452. out.append("/>").newline();
  453. }
  454. void RegexPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  455. {
  456. out.appendf(" kind=\"%s\"", getPatternText(getKind()));
  457. }
  458. void RegexPattern::killStage(ActiveStage & stage, RegexState & state)
  459. {
  460. }
  461. RegexMatchAction RegexPattern::nextChild(ActiveStage & stage, RegexState & state)
  462. {
  463. if (next.isItem(stage.nextFollow))
  464. {
  465. RegexPattern & child = next.item(stage.nextFollow);
  466. stage.nextFollow++;
  467. state.cur = stage.followPosition;
  468. return child.beginMatch(state);
  469. }
  470. stage.setState(RSretry);
  471. return RegexMatchContinue;
  472. }
  473. RegexMatchAction RegexPattern::nextAction(ActiveStage & stage, RegexState & state)
  474. {
  475. switch (stage.getState())
  476. {
  477. case RSinit:
  478. throwUnexpected();
  479. case RSnextfollow:
  480. return nextChild(stage, state);
  481. case RSfollowonly:
  482. {
  483. RegexMatchAction action = nextChild(stage, state);
  484. if (stage.getState() == RSretry)
  485. stage.setState(RSfinished);
  486. return action;
  487. }
  488. case RSretry:
  489. case RSfinished:
  490. state.popStage();
  491. return RegexMatchBacktrack;
  492. }
  493. UNIMPLEMENTED;
  494. }
  495. ActiveStage & RegexPattern::pushStage(RegexState & state)
  496. {
  497. #ifdef TRACE_REGEX
  498. StringBuffer t;
  499. unsigned len = state.end-state.cur;
  500. if (len > 10) len = 10;
  501. getTraceText(t);
  502. DBGLOG("%*s[%p]Push %s >%.*s<", patternDepth++, "", this, t.str(), len, state.cur);
  503. #endif
  504. ActiveStage & cur = state.pushStage();
  505. cur.pattern = this;
  506. cur.followPosition = state.cur;
  507. cur.state = RSinit;
  508. cur.flags = 0;
  509. return cur;
  510. }
  511. //---------------------------------------------------------------------------
  512. RegexMatchAction RegexNullPattern::match(RegexState & state)
  513. {
  514. return matchNext(state);
  515. }
  516. RegexMatchAction RegexNullPattern::beginMatch(RegexState & state)
  517. {
  518. return pushMatched(state);
  519. }
  520. RegexMatchAction RegexBeginTokenPattern::match(RegexState & state)
  521. {
  522. RegexMatchAction ret = matchNext(state);
  523. if (ret == RegexMatchBacktrackToken)
  524. return RegexMatchBacktrack;
  525. return ret;
  526. }
  527. RegexMatchAction RegexBeginTokenPattern::beginMatch(RegexState & state)
  528. {
  529. ActiveStage & stage = pushStage(state).setMatched();
  530. stage.flags |= RFbeginToken;
  531. return RegexMatchContinue;
  532. }
  533. RegexMatchAction RegexEndTokenPattern::match(RegexState & state)
  534. {
  535. RegexMatchAction ret = matchNext(state);
  536. if (ret == RegexMatchBacktrack)
  537. return RegexMatchBacktrackToken;
  538. return ret;
  539. }
  540. RegexMatchAction RegexEndTokenPattern::beginMatch(RegexState & state)
  541. {
  542. return pushMatched(state);
  543. }
  544. RegexMatchAction RegexEndTokenPattern::nextAction(ActiveStage & stage, RegexState & state)
  545. {
  546. switch (stage.getState())
  547. {
  548. case RSretry:
  549. case RSfinished:
  550. state.popStage();
  551. return RegexMatchBacktrackToken;
  552. default:
  553. return RegexPattern::nextAction(stage, state);
  554. }
  555. }
  556. RegexMatchAction RegexStartPattern::match(RegexState & state)
  557. {
  558. if (state.cur == state.start)
  559. return matchNext(state);
  560. return RegexMatchBacktrack;
  561. }
  562. RegexMatchAction RegexStartPattern::beginMatch(RegexState & state)
  563. {
  564. if (state.cur == state.start)
  565. return pushMatched(state);
  566. return RegexMatchBacktrack;
  567. }
  568. RegexMatchAction RegexFinishPattern::match(RegexState & state)
  569. {
  570. if (state.cur == state.end)
  571. return matchNext(state);
  572. return RegexMatchBacktrack;
  573. }
  574. RegexMatchAction RegexFinishPattern::beginMatch(RegexState & state)
  575. {
  576. if (state.cur == state.end)
  577. return pushMatched(state);
  578. return RegexMatchBacktrack;
  579. }
  580. RegexMatchAction RegexAnyCharPattern::match(RegexState & state)
  581. {
  582. if (state.cur != state.end)
  583. {
  584. state.cur += state.charSize;
  585. return matchNext(state);
  586. }
  587. return RegexMatchBacktrack;
  588. }
  589. RegexMatchAction RegexAnyCharPattern::beginMatch(RegexState & state)
  590. {
  591. if (state.cur != state.end)
  592. {
  593. state.cur += state.charSize;
  594. return pushMatched(state);
  595. }
  596. return RegexMatchBacktrack;
  597. }
  598. //---------------------------------------------------------------------------
  599. RegexMatchAction RegexPenaltyPattern::match(RegexState & state)
  600. {
  601. state.score -= penalty;
  602. RegexMatchAction ret = matchNext(state);
  603. state.score += penalty;
  604. return ret;
  605. }
  606. RegexMatchAction RegexPenaltyPattern::beginMatch(RegexState & state)
  607. {
  608. state.score -= penalty;
  609. return pushMatched(state);
  610. }
  611. void RegexPenaltyPattern::killStage(ActiveStage & stage, RegexState & state)
  612. {
  613. state.score += penalty;
  614. }
  615. void RegexPenaltyPattern::serializePattern(MemoryBuffer & out)
  616. {
  617. RegexPattern::serializePattern(out);
  618. out.append(penalty);
  619. }
  620. void RegexPenaltyPattern::deserializePattern(MemoryBuffer & in)
  621. {
  622. RegexPattern::deserializePattern(in);
  623. in.read(penalty);
  624. }
  625. void RegexPenaltyPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  626. {
  627. RegexPattern::toXMLattr(out, state);
  628. out.append(" penalty=\"").append(penalty).append("\"");
  629. }
  630. //---------------------------------------------------------------------------
  631. void RegexAsciiBasePattern::serializePattern(MemoryBuffer & out)
  632. {
  633. RegexPattern::serializePattern(out);
  634. out.append(text);
  635. }
  636. void RegexAsciiBasePattern::deserializePattern(MemoryBuffer & in)
  637. {
  638. RegexPattern::deserializePattern(in);
  639. in.read(text);
  640. len = (size32_t)strlen(text);
  641. }
  642. void RegexAsciiBasePattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  643. {
  644. RegexPattern::toXMLattr(out, state);
  645. out.append(" text=\"");
  646. encodeXML(text, out, ENCODE_WHITESPACE);
  647. out.append("\"");
  648. }
  649. inline bool RegexAsciiPattern::doMatch(RegexState & state)
  650. {
  651. const byte * cur = state.cur;
  652. const byte * end = state.end;
  653. if (cur + len <= end)
  654. {
  655. if (memcmp(cur, text.get(), len) == 0)
  656. {
  657. state.cur = cur + len;
  658. return true;
  659. }
  660. }
  661. return false;
  662. }
  663. RegexMatchAction RegexAsciiPattern::match(RegexState & state)
  664. {
  665. if (doMatch(state))
  666. return matchNext(state);
  667. return RegexMatchBacktrack;
  668. }
  669. RegexMatchAction RegexAsciiPattern::beginMatch(RegexState & state)
  670. {
  671. if (doMatch(state))
  672. return pushMatched(state);
  673. return RegexMatchBacktrack;
  674. }
  675. inline bool RegexAsciiIPattern::doMatch(RegexState & state)
  676. {
  677. const byte * cur = state.cur;
  678. const byte * end = state.end;
  679. if (cur + len <= end)
  680. {
  681. if (memicmp(cur, text.get(), len) == 0)
  682. {
  683. state.cur = cur + len;
  684. return true;
  685. }
  686. }
  687. return false;
  688. }
  689. RegexMatchAction RegexAsciiIPattern::match(RegexState & state)
  690. {
  691. if (doMatch(state))
  692. return matchNext(state);
  693. return RegexMatchBacktrack;
  694. }
  695. RegexMatchAction RegexAsciiIPattern::beginMatch(RegexState & state)
  696. {
  697. if (doMatch(state))
  698. return pushMatched(state);
  699. return RegexMatchBacktrack;
  700. }
  701. //---------------------------------------------------------------------------
  702. RegexMatchAction RegexRecursivePattern::match(RegexState & state)
  703. {
  704. if ((positionStack.ordinality() == 0) || (positionStack.tos() != state.cur))
  705. {
  706. positionStack.append(state.cur);
  707. state.stack.append(*this);
  708. RegexMatchAction ret = matchNext(state);
  709. state.stack.pop();
  710. positionStack.pop();
  711. return ret;
  712. }
  713. else
  714. throw MakeStringException(0, "Grammar is left recursive - cannot yet process!");
  715. return RegexMatchBacktrack;
  716. }
  717. RegexMatchAction RegexRecursivePattern::beginMatch(RegexState & state)
  718. {
  719. //MORE!
  720. return pushMatched(state);
  721. }
  722. RegexMatchAction RegexEndRecursivePattern::match(RegexState & state)
  723. {
  724. RegexRecursivePattern & top = (RegexRecursivePattern &)state.stack.popGet();
  725. const void * saved = top.positionStack.popGet();
  726. RegexMatchAction ret = matchNext(state);
  727. top.positionStack.append(saved);
  728. state.stack.append(top);
  729. return ret;
  730. }
  731. RegexMatchAction RegexEndRecursivePattern::beginMatch(RegexState & state)
  732. {
  733. //MORE!
  734. return pushMatched(state);
  735. }
  736. void encodeUnicode(StringBuffer & out, size32_t len, const UChar * text)
  737. {
  738. UnicodeString unicode(text, len);
  739. unsigned len8 = unicode.extract(0, unicode.length(), 0, 0, "UTF-8");
  740. char * text8 = (char *)malloc(len8);
  741. unicode.extract(0, unicode.length(), text8, len8, "UTF-8");
  742. encodeXML(text8, out, ENCODE_WHITESPACE, len8, true);
  743. free(text8);
  744. }
  745. void RegexUnicodePattern::serializePattern(MemoryBuffer & out)
  746. {
  747. RegexPattern::serializePattern(out);
  748. ::serialize(out, text);
  749. }
  750. void RegexUnicodePattern::deserializePattern(MemoryBuffer & in)
  751. {
  752. RegexPattern::deserializePattern(in);
  753. ::deserialize(in, text);
  754. }
  755. void RegexUnicodePattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  756. {
  757. RegexPattern::toXMLattr(out, state);
  758. out.appendf(" text=\"");
  759. encodeUnicode(out, text.length()/2, (const UChar *)text.get());
  760. out.append("\"");
  761. }
  762. inline bool RegexUnicodePattern::doMatch(RegexState & state)
  763. {
  764. const byte * cur = state.cur;
  765. const byte * end = state.end;
  766. unsigned len = text.length();
  767. if (cur + len <= end)
  768. {
  769. if (memcmp(cur, text.get(), len) == 0)
  770. {
  771. state.cur = cur + len;
  772. return true;
  773. }
  774. }
  775. return false;
  776. }
  777. RegexMatchAction RegexUnicodePattern::match(RegexState & state)
  778. {
  779. if (doMatch(state))
  780. return matchNext(state);
  781. return RegexMatchBacktrack;
  782. }
  783. RegexMatchAction RegexUnicodePattern::beginMatch(RegexState & state)
  784. {
  785. if (doMatch(state))
  786. return pushMatched(state);
  787. return RegexMatchBacktrack;
  788. }
  789. //---------------------------------------------------------------------------
  790. RegexUnicodeIPattern::RegexUnicodeIPattern(unsigned _len, const UChar * _text)
  791. {
  792. UChar * curLower = (UChar *)lower.allocate(_len*2);
  793. UChar * curUpper = (UChar *)upper.allocate(_len*2);
  794. for (unsigned i = 0; i< _len; i++)
  795. {
  796. curLower[i] = (UChar)u_tolower(_text[i]);
  797. curUpper[i] = (UChar)u_toupper(_text[i]);
  798. }
  799. }
  800. void RegexUnicodeIPattern::serializePattern(MemoryBuffer & out)
  801. {
  802. RegexPattern::serializePattern(out);
  803. ::serialize(out, lower);
  804. ::serialize(out, upper);
  805. }
  806. void RegexUnicodeIPattern::deserializePattern(MemoryBuffer & in)
  807. {
  808. RegexPattern::deserializePattern(in);
  809. ::deserialize(in, lower);
  810. ::deserialize(in, upper);
  811. }
  812. void RegexUnicodeIPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  813. {
  814. RegexPattern::toXMLattr(out, state);
  815. out.appendf(" text=\"");
  816. encodeUnicode(out, lower.length()/2, (const UChar *)lower.get());
  817. out.append("\"");
  818. }
  819. inline bool RegexUnicodeIPattern::doMatch(RegexState & state)
  820. {
  821. const byte * start = state.cur;
  822. const byte * end = state.end;
  823. unsigned size = lower.length();
  824. if (start + size <= end)
  825. {
  826. unsigned i;
  827. unsigned len = size/sizeof(UChar);
  828. const UChar * cur = (const UChar *)state.cur;
  829. const UChar * curLower = (const UChar *)lower.get();
  830. const UChar * curUpper = (const UChar *)upper.get();
  831. for (i = 0; i < len; i++)
  832. {
  833. UChar next = cur[i];
  834. if ((next != curLower[i]) && (next != curUpper[i]))
  835. return false;
  836. }
  837. state.cur += size;
  838. return true;
  839. }
  840. return false;
  841. }
  842. RegexMatchAction RegexUnicodeIPattern::match(RegexState & state)
  843. {
  844. if (doMatch(state))
  845. return matchNext(state);
  846. return RegexMatchBacktrack;
  847. }
  848. RegexMatchAction RegexUnicodeIPattern::beginMatch(RegexState & state)
  849. {
  850. if (doMatch(state))
  851. return pushMatched(state);
  852. return RegexMatchBacktrack;
  853. }
  854. RegexUnicodeFIPattern::RegexUnicodeFIPattern(unsigned _len, const UChar * _text)
  855. {
  856. MemoryBuffer foldedBuffer;
  857. UChar temp[2];
  858. UErrorCode error = U_ZERO_ERROR;
  859. for (unsigned i = 0; i< _len; i++)
  860. {
  861. unsigned foldLen = u_strFoldCase(temp, _elements_in(temp), _text+i, 1, U_FOLD_CASE_DEFAULT, &error);
  862. foldedBuffer.append(foldLen, &temp);
  863. }
  864. folded.set(foldedBuffer.length(), foldedBuffer.toByteArray());
  865. }
  866. bool RegexUnicodeFIPattern::doMatch(RegexState & state)
  867. {
  868. const UChar * cur = (const UChar *)state.cur;
  869. const UChar * end = (const UChar *)state.end;
  870. UChar temp[2];
  871. UErrorCode error = U_ZERO_ERROR;
  872. const UChar * curMatchText = (const UChar *)folded.get();
  873. const UChar * endMatchText = (const UChar *)((const byte *)folded.get() + folded.length());
  874. while (cur != end)
  875. {
  876. unsigned foldLen = u_strFoldCase(temp, _elements_in(temp), cur, 1, U_FOLD_CASE_DEFAULT, &error);
  877. if (temp[0] != *curMatchText)
  878. return false;
  879. assertex(foldLen == 1 || foldLen == 2);
  880. if (foldLen == 2)
  881. {
  882. if (curMatchText + foldLen > endMatchText)
  883. return false;
  884. if (temp[1] != curMatchText[1])
  885. return false;
  886. }
  887. cur += 1;
  888. curMatchText += foldLen;
  889. if (curMatchText == endMatchText)
  890. {
  891. state.cur = (const byte *)cur;
  892. return true;
  893. }
  894. }
  895. return false;
  896. }
  897. RegexMatchAction RegexUnicodeFIPattern::match(RegexState & state)
  898. {
  899. if (doMatch(state))
  900. return matchNext(state);
  901. return RegexMatchBacktrack;
  902. }
  903. RegexMatchAction RegexUnicodeFIPattern::beginMatch(RegexState & state)
  904. {
  905. if (doMatch(state))
  906. return pushMatched(state);
  907. return RegexMatchBacktrack;
  908. }
  909. //---------------------------------------------------------------------------
  910. void RegexUtf8Pattern::serializePattern(MemoryBuffer & out)
  911. {
  912. RegexPattern::serializePattern(out);
  913. ::serialize(out, text);
  914. }
  915. void RegexUtf8Pattern::deserializePattern(MemoryBuffer & in)
  916. {
  917. RegexPattern::deserializePattern(in);
  918. ::deserialize(in, text);
  919. }
  920. void RegexUtf8Pattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  921. {
  922. RegexPattern::toXMLattr(out, state);
  923. out.appendf(" text=\"");
  924. encodeXML((const char *)text.get(), out, ENCODE_WHITESPACE, text.length(), true);
  925. out.append("\"");
  926. }
  927. inline bool RegexUtf8Pattern::doMatch(RegexState & state)
  928. {
  929. const byte * cur = state.cur;
  930. const byte * end = state.end;
  931. unsigned size = text.length();
  932. if (cur + size <= end)
  933. {
  934. if (memcmp(cur, text.get(), size) == 0)
  935. {
  936. state.cur = cur + size;
  937. return true;
  938. }
  939. }
  940. return false;
  941. }
  942. RegexMatchAction RegexUtf8Pattern::match(RegexState & state)
  943. {
  944. if (doMatch(state))
  945. return matchNext(state);
  946. return RegexMatchBacktrack;
  947. }
  948. RegexMatchAction RegexUtf8Pattern::beginMatch(RegexState & state)
  949. {
  950. if (doMatch(state))
  951. return pushMatched(state);
  952. return RegexMatchBacktrack;
  953. }
  954. //---------------------------------------------------------------------------
  955. RegexUtf8IPattern::RegexUtf8IPattern(unsigned _len, const char * _text)
  956. {
  957. //Store unicode lowercase and uppercase versions, and compare the incoming utf a character at a time.
  958. UChar * curLower = (UChar *)lower.allocate(_len*sizeof(UChar));
  959. UChar * curUpper = (UChar *)upper.allocate(_len*sizeof(UChar));
  960. const byte * cur = (const byte *)_text;
  961. const byte * end = cur + rtlUtf8Size(_len, cur);
  962. for (unsigned i = 0; i< _len; i++)
  963. {
  964. UChar next = readUtf8Character((size32_t)(end-cur), cur);
  965. curLower[i] = (UChar)u_tolower(next);
  966. curUpper[i] = (UChar)u_toupper(next);
  967. }
  968. }
  969. void RegexUtf8IPattern::serializePattern(MemoryBuffer & out)
  970. {
  971. RegexPattern::serializePattern(out);
  972. ::serialize(out, lower);
  973. ::serialize(out, upper);
  974. }
  975. void RegexUtf8IPattern::deserializePattern(MemoryBuffer & in)
  976. {
  977. RegexPattern::deserializePattern(in);
  978. ::deserialize(in, lower);
  979. ::deserialize(in, upper);
  980. }
  981. void RegexUtf8IPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  982. {
  983. RegexPattern::toXMLattr(out, state);
  984. out.appendf(" text=\"");
  985. encodeUnicode(out, lower.length()/2, (const UChar *)lower.get());
  986. out.append("\"");
  987. }
  988. inline bool RegexUtf8IPattern::doMatch(RegexState & state)
  989. {
  990. const byte * end = state.end;
  991. unsigned size = lower.length();
  992. unsigned len = size/sizeof(UChar);
  993. const byte * cur = state.cur;
  994. const UChar * curLower = (const UChar *)lower.get();
  995. const UChar * curUpper = (const UChar *)upper.get();
  996. for (unsigned i = 0; i < len; i++)
  997. {
  998. if (cur == end)
  999. return false;
  1000. UChar next = readUtf8Character((size32_t)(end-cur), cur);
  1001. if ((next != curLower[i]) && (next != curUpper[i]))
  1002. return false;
  1003. }
  1004. state.cur = cur;
  1005. return true;
  1006. }
  1007. RegexMatchAction RegexUtf8IPattern::match(RegexState & state)
  1008. {
  1009. if (doMatch(state))
  1010. return matchNext(state);
  1011. return RegexMatchBacktrack;
  1012. }
  1013. RegexMatchAction RegexUtf8IPattern::beginMatch(RegexState & state)
  1014. {
  1015. if (doMatch(state))
  1016. return pushMatched(state);
  1017. return RegexMatchBacktrack;
  1018. }
  1019. //---------------------------------------------------------------------------
  1020. RegexAsciiSetBasePattern::RegexAsciiSetBasePattern()
  1021. {
  1022. inverted = false;
  1023. for (unsigned i = 0; i < 256; i++)
  1024. include[i] = inverted;
  1025. }
  1026. void RegexAsciiSetBasePattern::setInvert(bool newValue)
  1027. {
  1028. //can call before or after processing the list.
  1029. if (inverted != newValue)
  1030. {
  1031. for (unsigned i = 0; i < 256; i++)
  1032. include[i] ^= true;
  1033. inverted = newValue;
  1034. }
  1035. }
  1036. void RegexAsciiSetBasePattern::serializePattern(MemoryBuffer & out)
  1037. {
  1038. RegexPattern::serializePattern(out);
  1039. serializeBoolArray(out, 256, include);
  1040. out.append(inverted);
  1041. }
  1042. void RegexAsciiSetBasePattern::deserializePattern(MemoryBuffer & in)
  1043. {
  1044. RegexPattern::deserializePattern(in);
  1045. deserializeBoolArray(256, include, in);
  1046. in.read(inverted);
  1047. }
  1048. inline bool RegexAsciiSetBasePattern::doMatch(RegexState & state)
  1049. {
  1050. const byte * cur = state.cur;
  1051. const byte * end = state.end;
  1052. if (cur < end)
  1053. {
  1054. if (include[*cur])
  1055. {
  1056. state.cur = cur + 1;
  1057. return true;
  1058. }
  1059. }
  1060. return false;
  1061. }
  1062. RegexMatchAction RegexAsciiSetBasePattern::match(RegexState & state)
  1063. {
  1064. if (doMatch(state))
  1065. return matchNext(state);
  1066. return RegexMatchBacktrack;
  1067. }
  1068. RegexMatchAction RegexAsciiSetBasePattern::beginMatch(RegexState & state)
  1069. {
  1070. if (doMatch(state))
  1071. return pushMatched(state);
  1072. return RegexMatchBacktrack;
  1073. }
  1074. void RegexAsciiSetBasePattern::addSpecialRange(unsigned value)
  1075. {
  1076. for (unsigned i = 0; i < 256; i++)
  1077. {
  1078. if (isAsciiMatch(value, i))
  1079. include[i] = !inverted;
  1080. }
  1081. }
  1082. void RegexAsciiSetBasePattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1083. {
  1084. RegexSetBasePattern::toXMLattr(out, state);
  1085. out.append(" set=\"");
  1086. if (inverted)
  1087. out.append("^");
  1088. for (unsigned i = 0; i < 256; i++)
  1089. {
  1090. if (include[i] != inverted)
  1091. {
  1092. char c = i;
  1093. encodeXML(&c, out, ENCODE_WHITESPACE, 1);
  1094. }
  1095. }
  1096. out.append("\"");
  1097. }
  1098. void RegexAsciiSetPattern::addRange(unsigned low, unsigned high)
  1099. {
  1100. if (low & RegexSpecialMask)
  1101. {
  1102. assertex(low == high);
  1103. addSpecialRange(low);
  1104. }
  1105. else
  1106. {
  1107. assertex(low < 256 && high < 256);
  1108. for (unsigned i = low; i <= high; i++)
  1109. include[i] = !inverted;
  1110. }
  1111. }
  1112. void RegexAsciiISetPattern::addRange(unsigned low, unsigned high)
  1113. {
  1114. if (low & RegexSpecialMask)
  1115. {
  1116. assertex(low == high);
  1117. addSpecialRange(low);
  1118. }
  1119. else
  1120. {
  1121. assertex(low < 256 && high < 256);
  1122. for (unsigned i = low; i <= high; i++)
  1123. {
  1124. include[tolower(i)] = !inverted;
  1125. include[toupper(i)] = !inverted;
  1126. }
  1127. }
  1128. }
  1129. //---------------------------------------------------------------------------
  1130. RegexUnicodeSetPattern::RegexUnicodeSetPattern(bool _caseSensitive)
  1131. {
  1132. inverted = false;
  1133. caseSensitive = _caseSensitive;
  1134. }
  1135. void RegexUnicodeSetPattern::addRange(unsigned low, unsigned high)
  1136. {
  1137. if (!caseSensitive)
  1138. {
  1139. //This isn't really good enough - probably need to use string for the high and low values to allow collation
  1140. //comparison, and to allow SS to match correctly.
  1141. if (low & RegexSpecialMask)
  1142. {
  1143. if ((low == RCClower) || (low == RCCupper))
  1144. low = RCCalpha;
  1145. }
  1146. else
  1147. {
  1148. low = u_foldCase(low, U_FOLD_CASE_DEFAULT);
  1149. high = u_foldCase(high, U_FOLD_CASE_DEFAULT);
  1150. }
  1151. }
  1152. from.append(low);
  1153. to.append(high);
  1154. }
  1155. void RegexUnicodeSetPattern::setInvert(bool value)
  1156. {
  1157. inverted = value;
  1158. }
  1159. bool RegexUnicodeSetPattern::doMatch(RegexState & state)
  1160. {
  1161. const byte * cur = (const byte *)state.cur;
  1162. const byte * end = (const byte *)state.end;
  1163. if (cur < end)
  1164. {
  1165. UChar next;
  1166. if (state.inputFormat == NlpUnicode)
  1167. {
  1168. next = *(const UChar *)cur;
  1169. cur += sizeof(UChar);
  1170. }
  1171. else
  1172. {
  1173. next = readUtf8Character((size32_t)(end-cur), cur);
  1174. }
  1175. if (!caseSensitive)
  1176. next = (UChar)u_foldCase(next, U_FOLD_CASE_DEFAULT); // MORE: Doesn't cope with full folding of SS
  1177. ForEachItemIn(idx, from)
  1178. {
  1179. unsigned low = from.item(idx);
  1180. if (low & RegexSpecialMask)
  1181. {
  1182. if (isUnicodeMatch(low, next))
  1183. {
  1184. if (inverted)
  1185. return false;
  1186. state.cur = cur;
  1187. return true;
  1188. }
  1189. }
  1190. else if ((next >= low) && (next <= to.item(idx)))
  1191. {
  1192. if (inverted)
  1193. return false;
  1194. state.cur = cur;
  1195. return true;
  1196. }
  1197. }
  1198. if (inverted)
  1199. {
  1200. state.cur = cur;
  1201. return true;
  1202. }
  1203. }
  1204. return false;
  1205. }
  1206. RegexMatchAction RegexUnicodeSetPattern::match(RegexState & state)
  1207. {
  1208. if (doMatch(state))
  1209. return matchNext(state);
  1210. return RegexMatchBacktrack;
  1211. }
  1212. RegexMatchAction RegexUnicodeSetPattern::beginMatch(RegexState & state)
  1213. {
  1214. if (doMatch(state))
  1215. return pushMatched(state);
  1216. return RegexMatchBacktrack;
  1217. }
  1218. void RegexUnicodeSetPattern::serializePattern(MemoryBuffer & out)
  1219. {
  1220. RegexPattern::serializePattern(out);
  1221. out.append(caseSensitive);
  1222. out.append(inverted);
  1223. out.append(from.ordinality());
  1224. ForEachItemIn(idx, from)
  1225. {
  1226. out.append(from.item(idx));
  1227. out.append(to.item(idx));
  1228. }
  1229. }
  1230. void RegexUnicodeSetPattern::deserializePattern(MemoryBuffer & in)
  1231. {
  1232. unsigned count;
  1233. RegexPattern::deserializePattern(in);
  1234. in.read(caseSensitive);
  1235. in.read(inverted);
  1236. in.read(count);
  1237. for (unsigned idx=0; idx < count; idx++)
  1238. {
  1239. unsigned value;
  1240. in.read(value);
  1241. from.append(value);
  1242. in.read(value);
  1243. to.append(value);
  1244. }
  1245. }
  1246. void RegexUnicodeSetPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1247. {
  1248. RegexSetBasePattern::toXMLattr(out, state);
  1249. if (state.detail >= 100)
  1250. {
  1251. if (inverted)
  1252. out.append(" inverted");
  1253. out.append(" set=\"");
  1254. ForEachItemIn(idx, from)
  1255. {
  1256. if (idx)
  1257. out.append(",");
  1258. out.append(from.item(idx));
  1259. if (from.item(idx) != to.item(idx))
  1260. out.append("..").append(to.item(idx));
  1261. }
  1262. out.append("\"");
  1263. }
  1264. }
  1265. //---------------------------------------------------------------------------
  1266. RegexMatchAction RegexDonePattern::match(RegexState & state)
  1267. {
  1268. state.top.end = state.cur;
  1269. if (state.matchAction->onMatch(state))
  1270. return RegexMatchDone;
  1271. return RegexMatchBacktrack;
  1272. }
  1273. RegexMatchAction RegexDonePattern::beginMatch(RegexState & state)
  1274. {
  1275. state.top.end = state.cur;
  1276. if (state.matchAction->onMatch(state))
  1277. return RegexMatchDone;
  1278. return RegexMatchBacktrack;
  1279. }
  1280. //---------------------------------------------------------------------------
  1281. RegexMatchAction RegexEndNestedPattern::match(RegexState & state)
  1282. {
  1283. RegexPattern & top = state.stack.popGet();
  1284. RegexMatchAction ret = top.MATCH(state);
  1285. state.stack.append(top);
  1286. return ret;
  1287. }
  1288. RegexMatchAction RegexEndNestedPattern::beginMatch(RegexState & state)
  1289. {
  1290. ActiveStage & stage = pushStage(state);
  1291. stage.setState(RSfinished);
  1292. stage.extra.nextPattern = &state.namedStack.popGet();
  1293. return stage.extra.nextPattern->beginMatch(state);
  1294. }
  1295. void RegexEndNestedPattern::killStage(ActiveStage & stage, RegexState & state)
  1296. {
  1297. state.namedStack.append(*stage.extra.nextPattern);
  1298. }
  1299. //---------------------------------------------------------------------------
  1300. void RegexAssertionPattern::dispose()
  1301. {
  1302. RegexPattern::dispose();
  1303. disposeLink(pattern);
  1304. }
  1305. bool RegexAssertionPattern::gather(RegexSerializeState & state)
  1306. {
  1307. bool ok = RegexPattern::gather(state);
  1308. if (ok)
  1309. pattern->gather(state);
  1310. return ok;
  1311. }
  1312. void RegexAssertionPattern::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  1313. {
  1314. RegexPattern::serializeLinks(out, state);
  1315. serializeLink(out, pattern, state);
  1316. }
  1317. void RegexAssertionPattern::serializePattern(MemoryBuffer & out)
  1318. {
  1319. RegexPattern::serializePattern(out);
  1320. out.append(invert);
  1321. }
  1322. void RegexAssertionPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1323. {
  1324. RegexPattern::toXMLattr(out, state);
  1325. out.appendf(" sub=\"%d\" invert=\"%d\"", state.patterns.find(*pattern), invert);
  1326. state.addLink(*pattern);
  1327. }
  1328. void RegexAssertionPattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  1329. {
  1330. RegexPattern::deserializeLinks(in, state);
  1331. pattern.setown(deserializeLink(in, state));
  1332. }
  1333. void RegexAssertionPattern::deserializePattern(MemoryBuffer & in)
  1334. {
  1335. RegexPattern::deserializePattern(in);
  1336. in.read(invert);
  1337. }
  1338. bool RegexAssertNextPattern::nextMatches(RegexState & state)
  1339. {
  1340. //Sub function to reduce stack usage
  1341. MatchedAssertionAction matchedFlag;
  1342. RegexState localState(state, &matchedFlag, (size32_t)(state.end - state.cur), state.cur);
  1343. localState.processPattern(pattern);
  1344. return matchedFlag.isMatched();
  1345. }
  1346. RegexMatchAction RegexAssertNextPattern::match(RegexState & state)
  1347. {
  1348. if (nextMatches(state) != invert)
  1349. return matchNext(state);
  1350. return RegexMatchBacktrack;
  1351. }
  1352. RegexMatchAction RegexAssertNextPattern::beginMatch(RegexState & state)
  1353. {
  1354. if (nextMatches(state) != invert)
  1355. return pushMatched(state);
  1356. return RegexMatchBacktrack;
  1357. }
  1358. bool RegexAssertPrevPattern::prevMatches(RegexState & state)
  1359. {
  1360. //Sub function to reduce stack usage
  1361. ExactMatchedAssertionAction matchedFlag;
  1362. //This will work efficiently on fixed size patterns, but its painful for variable length
  1363. //It would work much better if we reversed the pattern, reversed the string, and then matched.
  1364. //I'll implement it when someone complains!
  1365. unsigned sizeBefore = (size32_t)(state.cur - state.start);
  1366. if (sizeBefore >= minSize)
  1367. {
  1368. unsigned maxToCheck = sizeBefore < maxSize ? sizeBefore : maxSize;
  1369. for (unsigned sizeToCheck = minSize; sizeToCheck <= maxToCheck; sizeToCheck += state.charSize)
  1370. {
  1371. //MORE: A test of finish will incorrectly succeed
  1372. RegexState localState(state, &matchedFlag, sizeBefore, state.start);
  1373. localState.cur = state.cur - sizeToCheck;
  1374. localState.processPattern(pattern);
  1375. if (matchedFlag.isMatched())
  1376. return true;
  1377. }
  1378. }
  1379. return false;
  1380. }
  1381. RegexMatchAction RegexAssertPrevPattern::match(RegexState & state)
  1382. {
  1383. if (prevMatches(state) != invert)
  1384. return matchNext(state);
  1385. return RegexMatchBacktrack;
  1386. }
  1387. RegexMatchAction RegexAssertPrevPattern::beginMatch(RegexState & state)
  1388. {
  1389. if (prevMatches(state) != invert)
  1390. return pushMatched(state);
  1391. return RegexMatchBacktrack;
  1392. }
  1393. void RegexAssertPrevPattern::serializePattern(MemoryBuffer & out)
  1394. {
  1395. RegexAssertionPattern::serializePattern(out);
  1396. out.append(minSize);
  1397. out.append(maxSize);
  1398. }
  1399. void RegexAssertPrevPattern::deserializePattern(MemoryBuffer & in)
  1400. {
  1401. RegexAssertionPattern::deserializePattern(in);
  1402. in.read(minSize);
  1403. in.read(maxSize);
  1404. }
  1405. void RegexAssertPrevPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1406. {
  1407. RegexAssertionPattern::toXMLattr(out, state);
  1408. out.appendf(" min=\"%d\" max=\"%d\"", minSize, maxSize);
  1409. }
  1410. //---------------------------------------------------------------------------
  1411. RegexMatchAction RegexBeginCheckPattern::match(RegexState & state)
  1412. {
  1413. MatchState matched;
  1414. MatchSaveState saved;
  1415. state.pushMatch(matched, saved);
  1416. RegexMatchAction ret = matchNext(state);
  1417. state.popMatch(saved);
  1418. return ret;
  1419. }
  1420. RegexMatchAction RegexBeginCheckPattern::beginMatch(RegexState & state)
  1421. {
  1422. RegexMatchStateSave * matched = state.cache.createStateSave(NULL, 0);
  1423. pushStageBeginMatch(state, matched);
  1424. return RegexMatchContinue;
  1425. }
  1426. void RegexBeginCheckPattern::killStage(ActiveStage & stage, RegexState & state)
  1427. {
  1428. cleanupBeginMatch(stage, state);
  1429. }
  1430. void RegexCheckPattern::serializePattern(MemoryBuffer & out)
  1431. {
  1432. RegexPattern::serializePattern(out);
  1433. out.append(invert);
  1434. out.append(stripSeparator);
  1435. }
  1436. void RegexCheckPattern::deserializePattern(MemoryBuffer & in)
  1437. {
  1438. RegexPattern::deserializePattern(in);
  1439. in.read(invert);
  1440. in.read(stripSeparator);
  1441. }
  1442. inline const byte * RegexCheckPattern::getEndMatch(RegexState & state)
  1443. {
  1444. const byte * end = state.cur;
  1445. if (stripSeparator)
  1446. {
  1447. MatchState * child = findTrailingSeparator(*state.curMatch);
  1448. if (child && child->end == end)
  1449. end = child->start;
  1450. }
  1451. return end;
  1452. }
  1453. RegexMatchAction RegexCheckInPattern::match(RegexState & state)
  1454. {
  1455. const byte * start = state.curMatch->start;
  1456. const byte * end = getEndMatch(state);
  1457. MatchedCheckAction matchedFlag;
  1458. RegexState localState(state, &matchedFlag, (size32_t)(end - start), start);
  1459. pattern->MATCH(localState);
  1460. if (matchedFlag.isMatched() ^ invert)
  1461. return markFinishContinueMatch(state);
  1462. return RegexMatchBacktrack;
  1463. }
  1464. RegexMatchAction RegexCheckInPattern::beginMatch(RegexState & state)
  1465. {
  1466. const byte * start = state.curMatch->start;
  1467. const byte * end = getEndMatch(state);
  1468. MatchedCheckAction matchedFlag;
  1469. RegexState localState(state, &matchedFlag, (size32_t)(end - start), start);
  1470. localState.helper = state.helper;
  1471. localState.processPattern(pattern);
  1472. if (matchedFlag.isMatched() ^ invert)
  1473. return pushStageEndMatch(state);
  1474. return RegexMatchBacktrack;
  1475. }
  1476. void RegexCheckInPattern::killStage(ActiveStage & stage, RegexState & state)
  1477. {
  1478. cleanupEndMatch(stage, state);
  1479. }
  1480. void RegexCheckInPattern::dispose()
  1481. {
  1482. RegexCheckPattern::dispose();
  1483. disposeLink(pattern);
  1484. }
  1485. bool RegexCheckInPattern::gather(RegexSerializeState & state)
  1486. {
  1487. bool ok = RegexCheckPattern::gather(state);
  1488. if (ok)
  1489. pattern->gather(state);
  1490. return ok;
  1491. }
  1492. void RegexCheckInPattern::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  1493. {
  1494. RegexCheckPattern::serializeLinks(out, state);
  1495. serializeLink(out, pattern, state);
  1496. }
  1497. void RegexCheckInPattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  1498. {
  1499. RegexCheckPattern::deserializeLinks(in, state);
  1500. pattern.setown(deserializeLink(in, state));
  1501. }
  1502. void RegexCheckInPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1503. {
  1504. RegexCheckPattern::toXMLattr(out, state);
  1505. out.appendf(" sub=\"%d\"", state.patterns.find(*pattern));
  1506. state.addLink(*pattern);
  1507. }
  1508. inline bool RegexCheckLengthPattern::doMatch(RegexState & state)
  1509. {
  1510. const byte * start = state.curMatch->start;
  1511. const byte * end = getEndMatch(state);
  1512. unsigned matchSize = (size32_t)(end - start);
  1513. unsigned matchLength;
  1514. if (state.inputFormat == NlpUtf8)
  1515. matchLength = rtlUtf8Length(matchSize, start);
  1516. else
  1517. matchLength = matchSize;
  1518. bool inRange = ((matchLength >= minExpectedBytes) && (matchLength <= maxExpectedBytes));
  1519. return (inRange != invert);
  1520. }
  1521. RegexMatchAction RegexCheckLengthPattern::match(RegexState & state)
  1522. {
  1523. if (doMatch(state))
  1524. return markFinishContinueMatch(state);
  1525. return RegexMatchBacktrack;
  1526. }
  1527. RegexMatchAction RegexCheckLengthPattern::beginMatch(RegexState & state)
  1528. {
  1529. if (doMatch(state))
  1530. return pushStageEndMatch(state);
  1531. return RegexMatchBacktrack;
  1532. }
  1533. void RegexCheckLengthPattern::killStage(ActiveStage & stage, RegexState & state)
  1534. {
  1535. cleanupEndMatch(stage, state);
  1536. }
  1537. void RegexCheckLengthPattern::serializePattern(MemoryBuffer & out)
  1538. {
  1539. RegexCheckPattern::serializePattern(out);
  1540. out.append(minExpectedBytes);
  1541. out.append(maxExpectedBytes);
  1542. }
  1543. void RegexCheckLengthPattern::deserializePattern(MemoryBuffer & in)
  1544. {
  1545. RegexCheckPattern::deserializePattern(in);
  1546. in.read(minExpectedBytes);
  1547. in.read(maxExpectedBytes);
  1548. }
  1549. void RegexCheckLengthPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1550. {
  1551. RegexCheckPattern::toXMLattr(out, state);
  1552. out.appendf(" expected=\"%d..%d\"", minExpectedBytes, maxExpectedBytes);
  1553. }
  1554. //---------------------------------------------------------------------------
  1555. void RegexValidatePattern::serializePattern(MemoryBuffer & out)
  1556. {
  1557. RegexCheckPattern::serializePattern(out);
  1558. out.append(validatorIndex);
  1559. }
  1560. void RegexValidatePattern::deserializePattern(MemoryBuffer & in)
  1561. {
  1562. RegexCheckPattern::deserializePattern(in);
  1563. in.read(validatorIndex);
  1564. }
  1565. void RegexValidatePattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  1566. {
  1567. RegexCheckPattern::deserializeLinks(in, state);
  1568. }
  1569. void RegexValidatePattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1570. {
  1571. RegexCheckPattern::toXMLattr(out, state);
  1572. out.appendf(" validator=\"%d\"", validatorIndex);
  1573. }
  1574. RegexMatchAction RegexValidatePattern::match(RegexState & state)
  1575. {
  1576. if (doMatch(state))
  1577. return markFinishContinueMatch(state);
  1578. return RegexMatchBacktrack;
  1579. }
  1580. RegexMatchAction RegexValidatePattern::beginMatch(RegexState & state)
  1581. {
  1582. if (doMatch(state))
  1583. return pushStageEndMatch(state);
  1584. return RegexMatchBacktrack;
  1585. }
  1586. void RegexValidatePattern::killStage(ActiveStage & stage, RegexState & state)
  1587. {
  1588. cleanupEndMatch(stage, state);
  1589. }
  1590. bool RegexValidateAscAsAscPattern::doMatch(RegexState & state)
  1591. {
  1592. IStringValidator * validator = (IStringValidator *)state.helper->queryValidator(validatorIndex);
  1593. const byte * start = state.curMatch->start;
  1594. const byte * end = getEndMatch(state);
  1595. unsigned matchSize = (size32_t)(end - start);
  1596. return validator->isValid(matchSize, (const char *)start);
  1597. }
  1598. bool RegexValidateUniAsAscPattern::doMatch(RegexState & state)
  1599. {
  1600. IStringValidator * validator = (IStringValidator *)state.helper->queryValidator(validatorIndex);
  1601. const byte * start = state.curMatch->start;
  1602. const byte * end = getEndMatch(state);
  1603. size32_t matchSize = (size32_t)(end - start);
  1604. unsigned asciiLen;
  1605. char * asciiText;
  1606. rtlUnicodeToStrX(asciiLen, asciiText, matchSize/2, (const UChar *)start);
  1607. bool ok = validator->isValid(asciiLen, asciiText);
  1608. rtlFree(asciiText);
  1609. return ok;
  1610. }
  1611. bool RegexValidateUtf8AsAscPattern::doMatch(RegexState & state)
  1612. {
  1613. IStringValidator * validator = (IStringValidator *)state.helper->queryValidator(validatorIndex);
  1614. const byte * start = state.curMatch->start;
  1615. const byte * end = getEndMatch(state);
  1616. unsigned matchSize = (size32_t)(end - start);
  1617. unsigned asciiLen;
  1618. char * asciiText;
  1619. rtlUnicodeToStrX(asciiLen, asciiText, rtlUtf8Length(matchSize, start), (const UChar *)start);
  1620. bool ok = validator->isValid(asciiLen, asciiText);
  1621. rtlFree(asciiText);
  1622. return ok;
  1623. }
  1624. bool RegexValidateAscAsUniPattern::doMatch(RegexState & state)
  1625. {
  1626. IUnicodeValidator * validator = (IUnicodeValidator *)state.helper->queryValidator(validatorIndex);
  1627. const byte * start = state.curMatch->start;
  1628. const byte * end = getEndMatch(state);
  1629. unsigned matchSize = (size32_t)(end - start);
  1630. unsigned unicodeLen;
  1631. UChar * unicodeText;
  1632. rtlStrToUnicodeX(unicodeLen, unicodeText, matchSize, (const char *)start);
  1633. bool ok = validator->isValid(unicodeLen, unicodeText);
  1634. rtlFree(unicodeText);
  1635. return ok;
  1636. }
  1637. bool RegexValidateUniAsUniPattern::doMatch(RegexState & state)
  1638. {
  1639. IUnicodeValidator * validator = (IUnicodeValidator *)state.helper->queryValidator(validatorIndex);
  1640. const byte * start = state.curMatch->start;
  1641. const byte * end = getEndMatch(state);
  1642. unsigned matchSize = (size32_t)(end - start);
  1643. return (validator->isValid(matchSize/2, (const UChar *)start));
  1644. }
  1645. bool RegexValidateUtf8AsUniPattern::doMatch(RegexState & state)
  1646. {
  1647. IUnicodeValidator * validator = (IUnicodeValidator *)state.helper->queryValidator(validatorIndex);
  1648. const byte * start = state.curMatch->start;
  1649. const byte * end = getEndMatch(state);
  1650. unsigned matchSize = (size32_t)(end - start);
  1651. unsigned unicodeLen;
  1652. UChar * unicodeText;
  1653. rtlStrToUnicodeX(unicodeLen, unicodeText, rtlUtf8Length(matchSize, start), (const char *)start);
  1654. bool ok = validator->isValid(unicodeLen, unicodeText);
  1655. rtlFree(unicodeText);
  1656. return ok;
  1657. }
  1658. //---------------------------------------------------------------------------
  1659. void RegexNamedPattern::getTraceText(StringBuffer & s)
  1660. {
  1661. s.append(getPatternText(getKind()));
  1662. if (def->queryName())
  1663. s.append(" ").append(def->queryName());
  1664. }
  1665. RegexMatchAction RegexNamedPattern::match(RegexState & state)
  1666. {
  1667. #ifdef __64BIT__
  1668. // 64-bit systems have more space for stack
  1669. RegexMatchState matched(def);
  1670. return def->match(state, &end, matched);
  1671. #else
  1672. //Allocate on the heap to make a stack fault less likely
  1673. RegexMatchState * matched = state.cache.createState(def);
  1674. RegexMatchAction ret = def->match(state, &end, *matched);
  1675. state.cache.destroyState(matched);
  1676. return ret;
  1677. #endif
  1678. }
  1679. void RegexNamedPattern::dispose()
  1680. {
  1681. RegexPattern::dispose();
  1682. disposeName(def);
  1683. }
  1684. bool RegexNamedPattern::gather(RegexSerializeState & state)
  1685. {
  1686. bool ok = RegexPattern::gather(state);
  1687. if (ok)
  1688. def->gather(state);
  1689. return ok;
  1690. }
  1691. void RegexNamedPattern::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  1692. {
  1693. RegexPattern::serializeLinks(out, state);
  1694. serializeName(out, def, state);
  1695. }
  1696. void RegexNamedPattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  1697. {
  1698. RegexPattern::deserializeLinks(in, state);
  1699. def.setown(deserializeName(in, state));
  1700. }
  1701. void RegexNamedPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1702. {
  1703. RegexPattern::toXMLattr(out, state);
  1704. if (def->queryName())
  1705. out.appendf(" name=\"%s\"", def->queryName()->str());
  1706. out.appendf(" body=\"%d\"", state.named.find(*def));
  1707. }
  1708. RegexMatchAction RegexNamedPattern::RegexEndNamedPattern::match(RegexState & state)
  1709. {
  1710. MatchSaveState saved;
  1711. state.markFinish(saved);
  1712. RegexMatchAction ret = named->matchNext(state);
  1713. state.unmarkFinish(saved);
  1714. return ret;
  1715. }
  1716. RegexMatchAction RegexNamedPattern::RegexEndNamedPattern::beginMatch(RegexState & state)
  1717. {
  1718. return pushStageEndMatch(state);
  1719. }
  1720. RegexMatchAction RegexNamedPattern::RegexEndNamedPattern::nextAction(ActiveStage & stage, RegexState & state)
  1721. {
  1722. switch (stage.getState())
  1723. {
  1724. case RSnextfollow:
  1725. return named->nextChild(stage, state);
  1726. default:
  1727. return RegexPattern::nextAction(stage, state);
  1728. }
  1729. }
  1730. void RegexNamedPattern::RegexEndNamedPattern::killStage(ActiveStage & stage, RegexState & state)
  1731. {
  1732. cleanupEndMatch(stage, state);
  1733. }
  1734. RegexMatchAction RegexNamedPattern::beginMatch(RegexState & state)
  1735. {
  1736. RegexMatchStateSave * matched = state.cache.createStateSave(def);
  1737. ActiveStage & stage = pushStageBeginMatch(state, matched);
  1738. stage.setState(RSfinished); // so children don't get processed.
  1739. state.namedStack.append(end);
  1740. return def->beginMatch(state);
  1741. }
  1742. void RegexNamedPattern::killStage(ActiveStage & stage, RegexState & state)
  1743. {
  1744. cleanupBeginMatch(stage, state);
  1745. state.namedStack.pop();
  1746. }
  1747. //---------------------------------------------------------------------------
  1748. RegexMatchAction RegexBeginSeparatorPattern::match(RegexState & state)
  1749. {
  1750. MatchState matched(separatorTagAtom, 0);
  1751. MatchSaveState saved;
  1752. state.pushMatch(matched, saved);
  1753. RegexMatchAction ret = matchNext(state);
  1754. state.popMatch(saved);
  1755. return ret;
  1756. }
  1757. RegexMatchAction RegexBeginSeparatorPattern::beginMatch(RegexState & state)
  1758. {
  1759. RegexMatchStateSave * matched = state.cache.createStateSave(separatorTagAtom, 0);
  1760. pushStageBeginMatch(state, matched);
  1761. return RegexMatchContinue;
  1762. }
  1763. void RegexBeginSeparatorPattern::killStage(ActiveStage & stage, RegexState & state)
  1764. {
  1765. cleanupBeginMatch(stage, state);
  1766. }
  1767. RegexMatchAction RegexEndSeparatorPattern::match(RegexState & state)
  1768. {
  1769. return mapAction(markFinishContinueMatch(state));
  1770. }
  1771. RegexMatchAction RegexEndSeparatorPattern::beginMatch(RegexState & state)
  1772. {
  1773. return mapAction(pushStageEndMatch(state));
  1774. }
  1775. RegexMatchAction RegexEndSeparatorPattern::nextAction(ActiveStage & stage, RegexState & state)
  1776. {
  1777. return mapAction(RegexPattern::nextAction(stage, state));
  1778. }
  1779. void RegexEndSeparatorPattern::killStage(ActiveStage & stage, RegexState & state)
  1780. {
  1781. cleanupEndMatch(stage, state);
  1782. }
  1783. //---------------------------------------------------------------------------
  1784. RegexMatchAction RegexRepeatPattern::match(RegexState & state)
  1785. {
  1786. return match(state, minLimit, maxLimit);
  1787. }
  1788. RegexMatchAction RegexRepeatPattern::matchNextInstance(RegexState & state, unsigned curMin, unsigned curMax)
  1789. {
  1790. Owned<RegexRepeatInstance> instance = new RegexRepeatInstance(this, curMin ? curMin-1 : 0, curMax-1);
  1791. return def->match(state, instance);
  1792. }
  1793. RegexMatchAction RegexRepeatPattern::match(RegexState & state, unsigned curMin, unsigned curMax)
  1794. {
  1795. if (curMax == 0)
  1796. return matchNext(state);
  1797. checkStackOverflow((size32_t)(state.cur-state.start));
  1798. Owned<RegexRepeatInstance> instance = new RegexRepeatInstance(this, curMin ? curMin-1 : 0, curMax-1);
  1799. if (curMin != 0)
  1800. return def->match(state, instance);
  1801. const byte * saved = state.cur;
  1802. if (greedy)
  1803. {
  1804. RegexMatchAction ret = def->match(state, instance);
  1805. if (ret != RegexMatchBacktrack)
  1806. return ret;
  1807. state.cur = saved;
  1808. return matchNext(state);
  1809. }
  1810. else
  1811. {
  1812. RegexMatchAction ret = matchNext(state);
  1813. if (ret != RegexMatchBacktrack)
  1814. return ret;
  1815. state.cur = saved;
  1816. return def->match(state, instance);
  1817. }
  1818. }
  1819. void RegexRepeatPattern::dispose()
  1820. {
  1821. RegexPattern::dispose();
  1822. disposeName(def);
  1823. }
  1824. bool RegexRepeatPattern::gather(RegexSerializeState & state)
  1825. {
  1826. bool ok = RegexPattern::gather(state);
  1827. if (ok)
  1828. def->gather(state);
  1829. return ok;
  1830. }
  1831. void RegexRepeatPattern::serializePattern(MemoryBuffer & out)
  1832. {
  1833. RegexPattern::serializePattern(out);
  1834. out.append(minLimit);
  1835. out.append(maxLimit);
  1836. out.append(greedy);
  1837. }
  1838. void RegexRepeatPattern::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  1839. {
  1840. RegexPattern::serializeLinks(out, state);
  1841. serializeName(out, def, state);
  1842. }
  1843. void RegexRepeatPattern::deserializePattern(MemoryBuffer & in)
  1844. {
  1845. RegexPattern::deserializePattern(in);
  1846. in.read(minLimit);
  1847. in.read(maxLimit);
  1848. in.read(greedy);
  1849. }
  1850. void RegexRepeatPattern::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  1851. {
  1852. RegexPattern::deserializeLinks(in, state);
  1853. def.setown(deserializeName(in, state));
  1854. }
  1855. void RegexRepeatPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  1856. {
  1857. RegexPattern::toXMLattr(out, state);
  1858. out.appendf(" min=\"%d\" max=\"%d\" greedy=\"%d\" body=\"%d\"", minLimit, maxLimit, greedy, state.named.find(*def));
  1859. }
  1860. RegexMatchAction RegexRepeatInstance::match(RegexState & state)
  1861. {
  1862. return def->match(state, minLimit, maxLimit);
  1863. }
  1864. //--- stack friedly implementation
  1865. RegexMatchAction RegexRepeatPattern::beginMatch(RegexState & state)
  1866. {
  1867. return beginMatch(state, minLimit, maxLimit);
  1868. }
  1869. RegexMatchAction RegexRepeatPattern::beginMatchNextInstance(RegexState & state, unsigned curMin, unsigned curMax)
  1870. {
  1871. Owned<RegexRepeatInstance> instance = new RegexRepeatInstance(this, curMin ? curMin-1 : 0, curMax-1);
  1872. return def->match(state, instance);
  1873. }
  1874. RegexMatchAction RegexRepeatPattern::beginMatch(RegexState & state, unsigned curMin, unsigned curMax)
  1875. {
  1876. ActiveStage & stage = pushStage(state);
  1877. stage.nextFollow = 0;
  1878. if (curMax == 0)
  1879. {
  1880. stage.extra.repeatInstance = NULL;
  1881. stage.setState(RSfollowonly);
  1882. return RegexMatchContinue;
  1883. }
  1884. RegexRepeatInstance * instance = new RegexRepeatInstance(this, curMin ? curMin-1 : 0, curMax-1);
  1885. stage.extra.repeatInstance = instance;
  1886. if (curMin != 0)
  1887. stage.setState(RSrepeatonly);
  1888. else if (greedy)
  1889. stage.setState(RSrepeat);
  1890. else
  1891. stage.setState(RSnextfollow);
  1892. return RegexMatchContinue;
  1893. }
  1894. void RegexRepeatPattern::killStage(ActiveStage & stage, RegexState & state)
  1895. {
  1896. if (state.namedStack.ordinality() && stage.extra.repeatInstance)
  1897. {
  1898. if (&state.namedStack.tos() == stage.extra.repeatInstance)
  1899. state.namedStack.pop();
  1900. }
  1901. delete stage.extra.repeatInstance;
  1902. }
  1903. inline RegexMatchAction RegexRepeatPattern::nextRepeatMatch(ActiveStage & stage, RegexState & state)
  1904. {
  1905. state.namedStack.append(*stage.extra.repeatInstance);
  1906. return def->beginMatch(state);
  1907. }
  1908. RegexMatchAction RegexRepeatPattern::nextAction(ActiveStage & stage, RegexState & state)
  1909. {
  1910. switch (stage.getState())
  1911. {
  1912. case RSretry:
  1913. assertex(!greedy);
  1914. state.cur = stage.followPosition;
  1915. //fall through to repeat-only code.
  1916. case RSrepeatonly:
  1917. stage.setState(RSfinished);
  1918. return nextRepeatMatch(stage, state);
  1919. case RSrepeat:
  1920. stage.setState(RSdonerepeat); // ensure namedStack is popped before processing children
  1921. stage.nextFollow = 0;
  1922. return nextRepeatMatch(stage, state);
  1923. case RSdonerepeat:
  1924. state.namedStack.pop();
  1925. stage.setState(RSfollowonly);
  1926. stage.nextFollow = 0;
  1927. return RegexPattern::nextAction(stage, state);
  1928. default:
  1929. return RegexPattern::nextAction(stage, state);
  1930. }
  1931. }
  1932. RegexMatchAction RegexRepeatInstance::beginMatch(RegexState & state)
  1933. {
  1934. return def->beginMatch(state, minLimit, maxLimit);
  1935. }
  1936. //---------------------------------------------------------------------------
  1937. static const int MultiAcceptMask = 0x80000000;
  1938. AsciiDfa::AsciiDfa()
  1939. {
  1940. numStates = 0;
  1941. numTransitions = 0;
  1942. numAccepts = 0;
  1943. states = NULL;
  1944. transitions = NULL;
  1945. accepts = NULL;
  1946. }
  1947. AsciiDfa::~AsciiDfa()
  1948. {
  1949. delete [] states;
  1950. free(transitions);
  1951. free(accepts);
  1952. }
  1953. void AsciiDfa::init(unsigned _numStates)
  1954. {
  1955. numStates = _numStates;
  1956. states = new AsciiDfaState[numStates];
  1957. memset(states, 0, sizeof(*states)*numStates);
  1958. }
  1959. unsigned AsciiDfa::getAccepts(const AsciiDfaState & state, unsigned idx) const
  1960. {
  1961. unsigned acceptId = state.acceptID;
  1962. if (acceptId == NotFound) return NotFound;
  1963. if (acceptId & MultiAcceptMask)
  1964. {
  1965. unsigned * values = accepts + (acceptId & ~MultiAcceptMask);
  1966. return values[idx];
  1967. }
  1968. else
  1969. return (idx == 0) ? acceptId : NotFound;
  1970. }
  1971. void AsciiDfa::serialize(MemoryBuffer & out)
  1972. {
  1973. out.append(numStates).append(numTransitions).append(numAccepts);
  1974. out.append(numStates * sizeof(*states), states);
  1975. out.append(numTransitions * sizeof(*transitions), transitions);
  1976. out.append(numAccepts * sizeof(*accepts), accepts);
  1977. }
  1978. void AsciiDfa::deserialize(MemoryBuffer & in)
  1979. {
  1980. in.read(numStates).read(numTransitions).read(numAccepts);
  1981. states = new AsciiDfaState[numStates];
  1982. transitions = (unsigned *)malloc(numTransitions * sizeof(*transitions));
  1983. accepts = (unsigned *)malloc(numAccepts * sizeof(*accepts));
  1984. in.read(numStates * sizeof(*states), states);
  1985. in.read(numTransitions * sizeof(*transitions), transitions);
  1986. in.read(numAccepts * sizeof(*accepts), accepts);
  1987. }
  1988. void AsciiDfa::setEmpty()
  1989. {
  1990. init(1);
  1991. states[0].delta = 0;
  1992. states[0].min = 255;
  1993. states[0].max = 0;
  1994. states[0].acceptID = NotFound;
  1995. }
  1996. void AsciiDfa::toXML(StringBuffer & out, unsigned detail)
  1997. {
  1998. out.appendf(" numStates=\"%d\" numTransitions=\"%d\"", numStates, numTransitions);
  1999. if (detail > 100)
  2000. {
  2001. out.newline();
  2002. for (unsigned i=0; i < numStates; i++)
  2003. {
  2004. unsigned min = states[i].min;
  2005. unsigned max = states[i].max;
  2006. out.append("\t\t").append(i).append(": ").append(min).append("..").append(max);
  2007. if (states[i].accepts())
  2008. {
  2009. out.append(" Accepts:");
  2010. for (unsigned k = 0;;k++)
  2011. {
  2012. unsigned id = getAccepts(states[i], k);
  2013. if (id == NotFound) break;
  2014. out.append(" ").append(id);
  2015. }
  2016. }
  2017. for (unsigned j = min; j<= max; j++)
  2018. {
  2019. if (((j-min) & 15)==0)
  2020. out.newline().append("\t\t\t");
  2021. out.append(j).append("->").append(transitions[states[i].delta + j]).append(' ');
  2022. }
  2023. out.newline();
  2024. }
  2025. }
  2026. }
  2027. AsciiDfaBuilder::AsciiDfaBuilder(AsciiDfa & _dfa) : dfa(_dfa)
  2028. {
  2029. maxTransitions = 0;
  2030. }
  2031. void AsciiDfaBuilder::addTransition(unsigned next, unsigned nextState)
  2032. {
  2033. if (dfa.states[curState].min > next)
  2034. dfa.states[curState].min = next;
  2035. if (dfa.states[curState].max < next)
  2036. dfa.states[curState].max = next;
  2037. dfa.transitions[firstTransition+next] = nextState;
  2038. }
  2039. void AsciiDfaBuilder::init(unsigned _numStates)
  2040. {
  2041. dfa.init(_numStates);
  2042. }
  2043. void AsciiDfaBuilder::init(unsigned _numStates, unsigned approxTransitions)
  2044. {
  2045. dfa.init(_numStates);
  2046. reallocTransitions(approxTransitions+256*2);
  2047. }
  2048. void AsciiDfaBuilder::reallocTransitions(unsigned required)
  2049. {
  2050. if (required > maxTransitions)
  2051. {
  2052. if (maxTransitions < 0x1000)
  2053. maxTransitions = 0x1000;
  2054. while (maxTransitions < required)
  2055. maxTransitions += 0x1000;
  2056. dfa.transitions = (unsigned *)realloc(dfa.transitions, maxTransitions * sizeof(*dfa.transitions));
  2057. }
  2058. }
  2059. void AsciiDfaBuilder::beginState(unsigned id)
  2060. {
  2061. curState = id;
  2062. dfa.states[curState].min = 255;
  2063. dfa.states[curState].max = 0;
  2064. dfa.states[curState].acceptID = NotFound;
  2065. firstTransition = dfa.numTransitions;
  2066. //ensure there are enough transitions...
  2067. if (firstTransition + 256 > maxTransitions)
  2068. {
  2069. reallocTransitions(firstTransition + 256 );
  2070. assertex(dfa.transitions);
  2071. }
  2072. for (unsigned i =0; i < 256; i++)
  2073. dfa.transitions[firstTransition+i] = NotFound;
  2074. }
  2075. void AsciiDfaBuilder::setStateAccept(unsigned id)
  2076. {
  2077. AsciiDfaState & cur = dfa.states[curState];
  2078. assertex((id & MultiAcceptMask) == 0);
  2079. if (cur.acceptID != NotFound)
  2080. {
  2081. if (!(cur.acceptID & MultiAcceptMask))
  2082. {
  2083. accepts.append(cur.acceptID);
  2084. cur.acceptID = (accepts.ordinality()-1)|MultiAcceptMask;
  2085. }
  2086. accepts.append(id);
  2087. }
  2088. else
  2089. cur.acceptID = id;
  2090. }
  2091. void AsciiDfaBuilder::endState()
  2092. {
  2093. AsciiDfaState & cur = dfa.states[curState];
  2094. if ((cur.acceptID != NotFound) && (cur.acceptID & MultiAcceptMask))
  2095. accepts.append(NotFound);
  2096. unsigned minEntry = cur.min;
  2097. unsigned maxEntry = cur.max;
  2098. if (minEntry <= maxEntry)
  2099. {
  2100. for (unsigned i = minEntry; i <= maxEntry; i++)
  2101. dfa.transitions[firstTransition+i-minEntry] = dfa.transitions[firstTransition+i];
  2102. cur.delta = firstTransition-minEntry;
  2103. dfa.numTransitions += (maxEntry - minEntry + 1);
  2104. }
  2105. else
  2106. cur.delta = 0; // no transitions from this state.
  2107. }
  2108. void AsciiDfaBuilder::finished()
  2109. {
  2110. unsigned numAccepts = accepts.ordinality();
  2111. dfa.numAccepts = numAccepts;
  2112. dfa.accepts = (unsigned *)malloc(sizeof(unsigned)*numAccepts);
  2113. memcpy(dfa.accepts, accepts.getArray(), numAccepts*sizeof(unsigned));
  2114. }
  2115. //---------------------------------------------------------------------------
  2116. RegexAsciiDfaPattern::RegexAsciiDfaPattern(bool _matchesToken)
  2117. {
  2118. matchesToken = _matchesToken;
  2119. }
  2120. RegexMatchAction RegexAsciiDfaPattern::match(RegexState & state)
  2121. {
  2122. const byte * cur = state.cur;
  2123. const byte * end = state.end;
  2124. unsigned activeState = 0;
  2125. const AsciiDfaState * states = dfa.queryStates();
  2126. unsigned * transitions = dfa.queryTransitions();
  2127. if (matchesToken)
  2128. {
  2129. //MORE: Store only one because we know we could never be backtracked - e.g., because this is always a token.
  2130. const byte * best = NULL;
  2131. loop
  2132. {
  2133. if (states[activeState].accepts())
  2134. best = cur;
  2135. if (cur == end)
  2136. break;
  2137. byte next = *cur++;
  2138. if (next < states[activeState].min)
  2139. break;
  2140. if (next > states[activeState].max)
  2141. break;
  2142. activeState = transitions[states[activeState].delta + next];
  2143. if (activeState == NotFound)
  2144. break;
  2145. }
  2146. if (best)
  2147. {
  2148. state.cur = best;
  2149. RegexMatchAction ret = matchNext(state);
  2150. if (ret == RegexMatchBacktrackToken)
  2151. ret = RegexMatchBacktrack;
  2152. return ret;
  2153. }
  2154. return RegexMatchBacktrack;
  2155. }
  2156. else
  2157. {
  2158. ConstPointerArray & potentialMatches = state.cache.potentialMatches;
  2159. unsigned prevPotentialMatches = potentialMatches.ordinality();
  2160. loop
  2161. {
  2162. if (states[activeState].accepts())
  2163. potentialMatches.append(cur);
  2164. if (cur == end)
  2165. break;
  2166. byte next = *cur++;
  2167. if (next < states[activeState].min)
  2168. break;
  2169. if (next > states[activeState].max)
  2170. break;
  2171. activeState = transitions[states[activeState].delta + next];
  2172. if (activeState == NotFound)
  2173. break;
  2174. }
  2175. while (potentialMatches.ordinality() > prevPotentialMatches)
  2176. {
  2177. state.cur = (const byte *)potentialMatches.popGet();
  2178. RegexMatchAction ret = matchNext(state);
  2179. if (ret != RegexMatchBacktrack)
  2180. {
  2181. potentialMatches.trunc(prevPotentialMatches);
  2182. return ret;
  2183. }
  2184. }
  2185. return RegexMatchBacktrack;
  2186. }
  2187. }
  2188. void RegexAsciiDfaPattern::serializePattern(MemoryBuffer & out)
  2189. {
  2190. RegexDfaPattern::serializePattern(out);
  2191. dfa.serialize(out);
  2192. out.append(matchesToken);
  2193. }
  2194. void RegexAsciiDfaPattern::deserializePattern(MemoryBuffer & in)
  2195. {
  2196. RegexDfaPattern::deserializePattern(in);
  2197. dfa.deserialize(in);
  2198. in.read(matchesToken);
  2199. }
  2200. void RegexAsciiDfaPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  2201. {
  2202. RegexDfaPattern::toXMLattr(out, state);
  2203. dfa.toXML(out, state.detail);
  2204. if (matchesToken)
  2205. out.append(" token");
  2206. }
  2207. void RegexAsciiDfaPattern::killStage(ActiveStage & stage, RegexState & state)
  2208. {
  2209. ConstPointerArray & potentialMatches = state.cache.potentialMatches;
  2210. unsigned prevPotentialMatches = stage.extra.prevPotentialMatches;
  2211. potentialMatches.trunc(prevPotentialMatches);
  2212. }
  2213. RegexMatchAction RegexAsciiDfaPattern::beginMatch(RegexState & state)
  2214. {
  2215. const byte * cur = state.cur;
  2216. const byte * end = state.end;
  2217. unsigned activeState = 0;
  2218. const AsciiDfaState * states = dfa.queryStates();
  2219. unsigned * transitions = dfa.queryTransitions();
  2220. const byte * best = NULL;
  2221. ConstPointerArray & potentialMatches = state.cache.potentialMatches;
  2222. const unsigned prevPotentialMatches = potentialMatches.ordinality();
  2223. loop
  2224. {
  2225. if (states[activeState].accepts())
  2226. {
  2227. if (!best || matchesToken)
  2228. best = cur;
  2229. else
  2230. {
  2231. if (prevPotentialMatches == potentialMatches.ordinality())
  2232. potentialMatches.append(best);
  2233. potentialMatches.append(cur);
  2234. }
  2235. }
  2236. if (cur == end)
  2237. break;
  2238. byte next = *cur++;
  2239. if (next < states[activeState].min)
  2240. break;
  2241. if (next > states[activeState].max)
  2242. break;
  2243. activeState = transitions[states[activeState].delta + next];
  2244. if (activeState == NotFound)
  2245. break;
  2246. }
  2247. if (!best)
  2248. return RegexMatchBacktrack;
  2249. ActiveStage & stage = pushStage(state);
  2250. stage.extra.prevPotentialMatches = prevPotentialMatches;
  2251. if (matchesToken)
  2252. stage.flags |= RFbeginToken;
  2253. //Only a single match, therefore no need to backtrack.
  2254. if (prevPotentialMatches == potentialMatches.ordinality())
  2255. {
  2256. stage.followPosition = best;
  2257. stage.setMatched();
  2258. }
  2259. else
  2260. {
  2261. stage.setState(RSretry);
  2262. }
  2263. return RegexMatchContinue;
  2264. }
  2265. RegexMatchAction RegexAsciiDfaPattern::nextAction(ActiveStage & stage, RegexState & state)
  2266. {
  2267. ConstPointerArray & potentialMatches = state.cache.potentialMatches;
  2268. unsigned prevPotentialMatches = stage.extra.prevPotentialMatches;
  2269. assertex(prevPotentialMatches <= potentialMatches.ordinality());
  2270. switch (stage.getState())
  2271. {
  2272. case RSretry:
  2273. {
  2274. if (prevPotentialMatches < potentialMatches.ordinality())
  2275. {
  2276. stage.followPosition = (const byte *)potentialMatches.popGet();
  2277. stage.setMatched();
  2278. return RegexMatchContinue;
  2279. }
  2280. return RegexPattern::nextAction(stage, state);
  2281. }
  2282. default:
  2283. return RegexPattern::nextAction(stage, state);
  2284. }
  2285. }
  2286. //---------------------------------------------------------------------------
  2287. RegexUnicodeDfaPattern::RegexUnicodeDfaPattern()
  2288. {
  2289. }
  2290. RegexUnicodeDfaPattern::~RegexUnicodeDfaPattern()
  2291. {
  2292. }
  2293. RegexMatchAction RegexUnicodeDfaPattern::match(RegexState & state)
  2294. {
  2295. /*
  2296. const byte * cur = state.cur;
  2297. const byte * end = state.end;
  2298. unsigned activeState = 0;
  2299. ConstPointerArray matches;
  2300. loop
  2301. {
  2302. //MORE: It would be better to store only one if we knew we could never be backtracked - e.g., if this was always a token.
  2303. if (states[activeState].accepts)
  2304. matches.append(cur);
  2305. if (cur == end)
  2306. break;
  2307. byte next = *cur++;
  2308. if (next < states[activeState].min)
  2309. break;
  2310. if (next > states[activeState].max)
  2311. break;
  2312. activeState = transitions[states[activeState].delta + next];
  2313. }
  2314. while (matches.ordinality())
  2315. {
  2316. state.cur = (const byte *)matches.tos();
  2317. matches.pop();
  2318. RegexMatchAction ret = matchNext(state);
  2319. if (ret != RegexMatchBacktrack)
  2320. return ret;
  2321. }
  2322. */
  2323. return RegexMatchBacktrack;
  2324. }
  2325. RegexMatchAction RegexUnicodeDfaPattern::beginMatch(RegexState & state)
  2326. {
  2327. UNIMPLEMENTED;
  2328. return RegexMatchBacktrack;
  2329. }
  2330. void RegexUnicodeDfaPattern::serializePattern(MemoryBuffer & out)
  2331. {
  2332. }
  2333. void RegexUnicodeDfaPattern::deserializePattern(MemoryBuffer & in)
  2334. {
  2335. }
  2336. //---------------------------------------------------------------------------
  2337. RegexRepeatAnyPattern::RegexRepeatAnyPattern(unsigned _low, unsigned _high, bool _minimal)
  2338. {
  2339. low = _low;
  2340. high = _high;
  2341. minimal = _minimal;
  2342. }
  2343. RegexMatchAction RegexRepeatAnyPattern::match(RegexState & state)
  2344. {
  2345. unsigned max = (size32_t)(state.end - state.cur);
  2346. if (max > high)
  2347. max = high;
  2348. const byte * start = state.cur;
  2349. if (low > max)
  2350. return RegexMatchBacktrack;
  2351. if (minimal)
  2352. {
  2353. for (unsigned i = low; i <= max; i++)
  2354. {
  2355. state.cur = start+i;
  2356. RegexMatchAction ret = matchNext(state);
  2357. if (ret != RegexMatchBacktrack)
  2358. return ret;
  2359. }
  2360. return RegexMatchBacktrack;
  2361. }
  2362. else
  2363. {
  2364. unsigned i = max;
  2365. loop
  2366. {
  2367. state.cur = start+i;
  2368. RegexMatchAction ret = matchNext(state);
  2369. if (ret != RegexMatchBacktrack)
  2370. return ret;
  2371. if (i == low)
  2372. return RegexMatchBacktrack;
  2373. i--;
  2374. }
  2375. }
  2376. }
  2377. RegexMatchAction RegexRepeatAnyPattern::beginMatch(RegexState & state)
  2378. {
  2379. unsigned max = (size32_t)(state.end - state.cur);
  2380. if (max > high)
  2381. max = high;
  2382. const byte * start = state.cur;
  2383. if (low > max)
  2384. return RegexMatchBacktrack;
  2385. ActiveStage & stage = pushStage(state).setMatched();
  2386. if (minimal)
  2387. {
  2388. stage.followPosition = start+low;
  2389. stage.extra.limit = start+max;
  2390. }
  2391. else
  2392. {
  2393. stage.followPosition = start+max;
  2394. stage.extra.limit = start+low;
  2395. }
  2396. return RegexMatchContinue;
  2397. }
  2398. RegexMatchAction RegexRepeatAnyPattern::nextAction(ActiveStage & stage, RegexState & state)
  2399. {
  2400. switch (stage.getState())
  2401. {
  2402. case RSretry:
  2403. if (minimal)
  2404. {
  2405. if (stage.followPosition < stage.extra.limit)
  2406. {
  2407. stage.followPosition++;
  2408. stage.setMatched();
  2409. return RegexMatchContinue;
  2410. }
  2411. }
  2412. else
  2413. {
  2414. if (stage.followPosition > stage.extra.limit)
  2415. {
  2416. stage.followPosition++;
  2417. stage.setMatched();
  2418. return RegexMatchContinue;
  2419. }
  2420. }
  2421. return RegexPattern::nextAction(stage, state);
  2422. default:
  2423. return RegexPattern::nextAction(stage, state);
  2424. }
  2425. }
  2426. void RegexRepeatAnyPattern::serializePattern(MemoryBuffer & out)
  2427. {
  2428. RegexPattern::serializePattern(out);
  2429. out.append(low).append(high).append(minimal);
  2430. }
  2431. void RegexRepeatAnyPattern::deserializePattern(MemoryBuffer & in)
  2432. {
  2433. RegexPattern::deserializePattern(in);
  2434. in.read(low).read(high).read(minimal);
  2435. }
  2436. void RegexRepeatAnyPattern::toXMLattr(StringBuffer & out, RegexXmlState & state)
  2437. {
  2438. RegexPattern::toXMLattr(out, state);
  2439. out.appendf(" low=\"%u\" high=\"%u\" greedy=\"%d\"", low, high, !minimal);
  2440. }
  2441. //---------------------------------------------------------------------------
  2442. RegexMatchAction RegexNamed::match(RegexState & state, RegexPattern * instance, MatchState & matched)
  2443. {
  2444. MatchSaveState saved;
  2445. checkStackOverflow((size32_t)(state.cur-state.start));
  2446. state.pushMatch(matched, saved);
  2447. RegexMatchAction ret = match(state, instance);
  2448. state.popMatch(saved);
  2449. return ret;
  2450. }
  2451. RegexMatchAction RegexNamed::match(RegexState & state, RegexPattern * instance)
  2452. {
  2453. state.stack.append(*instance);
  2454. RegexMatchAction ret = first->MATCH(state);
  2455. state.stack.pop();
  2456. return ret;
  2457. }
  2458. void RegexNamed::serializeLinks(MemoryBuffer & out, RegexSerializeState & state)
  2459. {
  2460. serializeLink(out, first, state);
  2461. }
  2462. void RegexNamed::dispose()
  2463. {
  2464. disposeLink(first);
  2465. }
  2466. void RegexNamed::gather(RegexSerializeState & state)
  2467. {
  2468. if (state.named.find(*this) == NotFound)
  2469. {
  2470. state.named.append(OLINK(*this));
  2471. first->gather(state);
  2472. }
  2473. }
  2474. void RegexNamed::deserializeLinks(MemoryBuffer & in, RegexSerializeState & state)
  2475. {
  2476. first.setown(deserializeLink(in, state));
  2477. }
  2478. void RegexNamed::serializePattern(MemoryBuffer & out)
  2479. {
  2480. if (name)
  2481. {
  2482. StringBuffer lowerName;
  2483. lowerName.append(name->str()).toLowerCase();
  2484. out.append(lowerName.str());
  2485. }
  2486. else
  2487. out.append(name->str());
  2488. out.append(id);
  2489. }
  2490. void RegexNamed::deserializePattern(MemoryBuffer & in)
  2491. {
  2492. ::deserialize(in, name);
  2493. in.read(id);
  2494. }
  2495. void graphToXML(StringBuffer & out, RegexXmlState & state, RegexPattern * first)
  2496. {
  2497. state.reset();
  2498. state.addLink(*first);
  2499. while (state.toVisit.ordinality())
  2500. {
  2501. RegexPattern & next = state.toVisit.item(0);
  2502. state.toVisit.remove(0, true);
  2503. state.visited.append(next);
  2504. next.toXML(out, state);
  2505. }
  2506. }
  2507. void RegexNamed::toXML(StringBuffer & out, RegexXmlState & state)
  2508. {
  2509. StringBuffer lowerName;
  2510. lowerName.append(name->str()).toLowerCase();
  2511. out.appendf("<named id=\"%d\" name=\"%s\" matchid=\"%d\" first=\"%d\">", state.named.find(*this), lowerName.str(), id, state.patterns.find(*first)).newline();
  2512. graphToXML(out, state, first);
  2513. //first->toXML(out, state);
  2514. out.append("</named>").newline();
  2515. }
  2516. RegexMatchAction RegexNamed::beginMatch(RegexState & state)
  2517. {
  2518. return first->beginMatch(state);
  2519. }
  2520. //-----------------------------------------------------------------------
  2521. void regexToXml(StringBuffer & out, RegexPattern * root, unsigned detail)
  2522. {
  2523. RegexXmlState state;
  2524. state.detail = detail;
  2525. root->gather(state);
  2526. out.appendf("<regex root=\"%d\">", state.patterns.find(*root)).newline();
  2527. graphToXML(out, state, root);
  2528. ForEachItemIn(in, state.named)
  2529. state.named.item(in).toXML(out, state);
  2530. out.append("</regex>").newline();
  2531. }
  2532. void serializeRegex(MemoryBuffer & out, RegexPattern * root)
  2533. {
  2534. RegexSerializeState state;
  2535. root->gather(state);
  2536. unsigned version = REGEX_VERSION;
  2537. out.append(version);
  2538. out.append((unsigned)state.patterns.ordinality());
  2539. out.append((unsigned)state.named.ordinality());
  2540. ForEachItemIn(ip, state.patterns)
  2541. state.patterns.item(ip).serializePattern(out);
  2542. ForEachItemIn(in, state.named)
  2543. state.named.item(in).serializePattern(out);
  2544. ForEachItemIn(ip2, state.patterns)
  2545. state.patterns.item(ip2).serializeLinks(out, state);
  2546. ForEachItemIn(in2, state.named)
  2547. state.named.item(in2).serializeLinks(out, state);
  2548. ForEachItemIn(i, state.patterns)
  2549. state.patterns.item(i).clearGathered();
  2550. }
  2551. RegexPattern * deserializeRegex(MemoryBuffer & in)
  2552. {
  2553. RegexSerializeState state;
  2554. unsigned idx;
  2555. unsigned version;
  2556. unsigned numPatterns, numNamed;
  2557. in.read(version);
  2558. if (version != REGEX_VERSION)
  2559. throwError(REGEXERR_IncompatibleVersion);
  2560. in.read(numPatterns);
  2561. in.read(numNamed);
  2562. for (idx=0; idx < numPatterns; idx++)
  2563. {
  2564. byte _kind;
  2565. ThorRegexKind kind;
  2566. in.read(_kind);
  2567. kind = (ThorRegexKind)_kind;
  2568. RegexPattern * next;
  2569. switch (kind)
  2570. {
  2571. case ThorRegexNull: next = new RegexNullPattern(); break;
  2572. case ThorRegexAnyChar: next = new RegexAnyCharPattern(); break;
  2573. case ThorRegexAsciiDFA: next = new RegexAsciiDfaPattern(); break;
  2574. // case ThorRegexIDFA: next = new RegexIDFAPattern(); break;
  2575. case ThorRegexAscii: next = new RegexAsciiPattern(); break;
  2576. case ThorRegexAsciiI: next = new RegexAsciiIPattern(); break;
  2577. case ThorRegexAsciiSet: next = new RegexAsciiSetPattern(); break;
  2578. case ThorRegexAsciiISet: next = new RegexAsciiISetPattern(); break;
  2579. case ThorRegexUnicode: next = new RegexUnicodePattern(); break;
  2580. case ThorRegexUnicodeI: next = new RegexUnicodeIPattern(); break;
  2581. case ThorRegexUnicodeSet: next = new RegexUnicodeSetPattern(); break;
  2582. case ThorRegexUtf8: next = new RegexUtf8Pattern(); break;
  2583. case ThorRegexUtf8I: next = new RegexUtf8IPattern(); break;
  2584. // case ThorRegexUnicodeISet: next = new RegexUnicodeISetPattern(); break;
  2585. case ThorRegexStart: next = new RegexStartPattern(); break;
  2586. case ThorRegexFinish: next = new RegexFinishPattern(); break;
  2587. case ThorRegexBeginToken: next = new RegexBeginTokenPattern(); break;
  2588. case ThorRegexEndToken: next = new RegexEndTokenPattern(); break;
  2589. case ThorRegexBeginSeparator:next = new RegexBeginSeparatorPattern(); break;
  2590. case ThorRegexEndSeparator: next = new RegexEndSeparatorPattern(); break;
  2591. case ThorRegexRepeat: next = new RegexRepeatPattern(); break;
  2592. case ThorRegexCheck: next = new RegexCheckInPattern(); break;
  2593. case ThorRegexCheckLength: next = new RegexCheckLengthPattern(); break;
  2594. case ThorRegexBeginCheck: next = new RegexBeginCheckPattern(); break;
  2595. case ThorRegexAssertNext: next = new RegexAssertNextPattern(); break;
  2596. case ThorRegexAssertPrev: next = new RegexAssertPrevPattern(); break;
  2597. case ThorRegexNamed: next = new RegexNamedPattern(); break;
  2598. case ThorRegexEndNested: next = new RegexEndNestedPattern(); break;
  2599. case ThorRegexDone: next = new RegexDonePattern(); break;
  2600. case ThorRegexValidateAscAsAsc: next = new RegexValidateAscAsAscPattern(); break;
  2601. case ThorRegexValidateUniAsAsc: next = new RegexValidateUniAsAscPattern(); break;
  2602. case ThorRegexValidateUtf8AsAsc: next = new RegexValidateUtf8AsAscPattern(); break;
  2603. case ThorRegexValidateAscAsUni: next = new RegexValidateAscAsUniPattern(); break;
  2604. case ThorRegexValidateUniAsUni: next = new RegexValidateUniAsUniPattern(); break;
  2605. case ThorRegexValidateUtf8AsUni: next = new RegexValidateUtf8AsUniPattern(); break;
  2606. case ThorRegexRecursive: next = new RegexRecursivePattern(); break;
  2607. case ThorRegexEndRecursive: next = new RegexEndRecursivePattern(); break;
  2608. case ThorRegexPenalty: next = new RegexPenaltyPattern(); break;
  2609. case ThorRegexRepeatAny: next = new RegexRepeatAnyPattern(); break;
  2610. default:
  2611. UNIMPLEMENTED;
  2612. }
  2613. next->deserializePattern(in);
  2614. state.patterns.append(*next);
  2615. }
  2616. for (idx=0; idx < numNamed; idx++)
  2617. {
  2618. RegexNamed * next = new RegexNamed();
  2619. next->deserializePattern(in);
  2620. state.named.append(*next);
  2621. }
  2622. for (idx=0; idx < numPatterns; idx++)
  2623. state.patterns.item(idx).deserializeLinks(in, state);
  2624. for (idx=0; idx < numNamed; idx++)
  2625. state.named.item(idx).deserializeLinks(in, state);
  2626. return LINK(&state.patterns.item(0));
  2627. }
  2628. //---------------------------------------------------------------------------
  2629. RegexMatchState * RegexStateCache::createState(RegexNamed * def)
  2630. {
  2631. if (matchStates.ordinality())
  2632. {
  2633. RegexMatchState * ret = &matchStates.popGet();
  2634. ret->reset(def);
  2635. return ret;
  2636. }
  2637. return new RegexMatchState(def);
  2638. }
  2639. void RegexStateCache::destroyState(RegexMatchState * state)
  2640. {
  2641. matchStates.append(*state);
  2642. }
  2643. RegexMatchStateSave * RegexStateCache::createStateSave(RegexNamed * def)
  2644. {
  2645. if (matchStateSaves.ordinality())
  2646. {
  2647. RegexMatchStateSave * ret = &matchStateSaves.popGet();
  2648. ret->reset(def);
  2649. return ret;
  2650. }
  2651. return new RegexMatchStateSave(def);
  2652. }
  2653. RegexMatchStateSave * RegexStateCache::createStateSave(IAtom * _name, regexid_t _id)
  2654. {
  2655. if (matchStateSaves.ordinality())
  2656. {
  2657. RegexMatchStateSave * ret = &matchStateSaves.popGet();
  2658. ret->reset(_name, _id);
  2659. return ret;
  2660. }
  2661. return new RegexMatchStateSave(_name, _id);
  2662. }
  2663. void RegexStateCache::destroyStateSave(RegexMatchStateSave * state)
  2664. {
  2665. matchStateSaves.append(*state);
  2666. }
  2667. void RegexState::processPattern(RegexPattern * grammar)
  2668. {
  2669. if (implementation == NLPAregexStack)
  2670. {
  2671. grammar->MATCH(*this);
  2672. return;
  2673. }
  2674. RegexMatchAction action = grammar->beginMatch(*this);
  2675. switch (action)
  2676. {
  2677. case RegexMatchDone:
  2678. while (hasActiveStage())
  2679. popStage();
  2680. return;
  2681. case RegexMatchBacktrack:
  2682. case RegexMatchContinue:
  2683. break;
  2684. case RegexMatchBacktrackToken:
  2685. throwUnexpected();
  2686. break;
  2687. }
  2688. while (hasActiveStage())
  2689. {
  2690. #ifdef TRACE_REGEX
  2691. StringBuffer itemText;
  2692. itemText.appendf("[%p]", topStage().pattern);
  2693. #endif
  2694. action = topStage().nextAction(*this);
  2695. #ifdef TRACE_REGEX
  2696. DBGLOG("%*s%snextAction returned %s", patternDepth, "", itemText.str(), resultText[action]);
  2697. #endif
  2698. switch (action)
  2699. {
  2700. case RegexMatchDone:
  2701. {
  2702. while (hasActiveStage())
  2703. popStage();
  2704. return;
  2705. }
  2706. case RegexMatchContinue:
  2707. case RegexMatchBacktrack:
  2708. break;
  2709. case RegexMatchBacktrackToken:
  2710. {
  2711. bool finished = false;
  2712. do
  2713. {
  2714. finished = topStage().isBeginToken();
  2715. popStage();
  2716. } while (!finished);
  2717. break;
  2718. }
  2719. }
  2720. }
  2721. assertex(namedStack.ordinality() == 0);
  2722. assertex(curMatch == &top);
  2723. }
  2724. ActiveStage & RegexState::pushStage()
  2725. {
  2726. curActiveStage++;
  2727. if (!stages.isItem(curActiveStage))
  2728. {
  2729. ActiveStage temp;
  2730. //initialise not needed, but it stops a warning from the compiler
  2731. temp.pattern = NULL;
  2732. temp.state = RSinit;
  2733. stages.append(temp);
  2734. }
  2735. return stages.element(curActiveStage);
  2736. }
  2737. void RegexState::popStage()
  2738. {
  2739. #ifdef TRACE_REGEX
  2740. ActiveStage & tos = topStage();
  2741. StringBuffer t;
  2742. tos.pattern->getTraceText(t);
  2743. DBGLOG("%*s[%p]Pop %s", --patternDepth, "", tos.pattern, t.str());
  2744. #endif
  2745. stages.element(curActiveStage).cleanup(*this);
  2746. curActiveStage--;
  2747. }
  2748. /*
  2749. RegexMatchAction RegexDfa::beginMatch(RegexState & state)
  2750. {
  2751. //walk to find matches
  2752. if (only one then save it).
  2753. if (>1 create a list and add all items onto it)
  2754. if (matched)
  2755. {
  2756. if (single)
  2757. {
  2758. }
  2759. else
  2760. {
  2761. state.pushState(this).setStage(RSretry);
  2762. newState->extra.matches = matches;
  2763. }
  2764. state.namedAction.append(*end);
  2765. return firstElement->beginMatch(state);
  2766. }
  2767. RegexMatchAction RegexDfa::nextAction(ActiveStage & stage, RegexState & state)
  2768. {
  2769. if (stage.extra.matches->ordinality())
  2770. {
  2771. state.cur = stage.extra.matches.pop();
  2772. stage.setMatched();
  2773. return RegexMatchContinue;
  2774. }
  2775. return RegexMatchBacktrack;
  2776. }
  2777. */
  2778. //---------------------------------------------------------------------------
  2779. RegexMatchInfo * RegexMatches::createMatch()
  2780. {
  2781. RegexMatchInfo * row = new RegexMatchInfo(NULL);
  2782. results.append(*row);
  2783. return row;
  2784. }
  2785. void RegexMatches::reset()
  2786. {
  2787. results.kill();
  2788. }
  2789. //---------------------------------------------------------------------------
  2790. RegexAlgorithm::RegexAlgorithm(IOutputMetaData * _outRecordSize, byte _kind) : NlpAlgorithm(new CRegexMatchedResultInfo)
  2791. {
  2792. outRecordSize.set(_outRecordSize);
  2793. kind = _kind;
  2794. }
  2795. RegexAlgorithm::~RegexAlgorithm()
  2796. {
  2797. if (grammar)
  2798. grammar->dispose();
  2799. }
  2800. INlpParser * RegexAlgorithm::createParser(ICodeContext * ctx, unsigned activityId, INlpHelper * helper, IHThorParseArg * arg)
  2801. {
  2802. return new RegexParser(ctx, this, helper, activityId);
  2803. }
  2804. void RegexAlgorithm::init(IHThorParseArg & arg)
  2805. {
  2806. }
  2807. void RegexAlgorithm::serialize(MemoryBuffer & out)
  2808. {
  2809. out.append(kind);
  2810. NlpAlgorithm::serialize(out);
  2811. out.append(minPatternLength);
  2812. serializeRegex(out, grammar);
  2813. }
  2814. void RegexAlgorithm::deserialize(MemoryBuffer & in)
  2815. {
  2816. NlpAlgorithm::deserialize(in);
  2817. in.read(minPatternLength);
  2818. grammar.setown(deserializeRegex(in));
  2819. }
  2820. INlpParseAlgorithm * createRegexParser(MemoryBuffer & buffer, IOutputMetaData * outRecordSize, byte kind)
  2821. {
  2822. RegexAlgorithm * ret = new RegexAlgorithm(outRecordSize, kind);
  2823. ret->deserialize(buffer);
  2824. return ret;
  2825. }
  2826. void RegexAlgorithm::match(RegexState & state)
  2827. {
  2828. state.processPattern(grammar);
  2829. }
  2830. //---------------------------------------------------------------------------
  2831. RegexParser::RegexParser(ICodeContext * ctx, RegexAlgorithm * _algo, INlpHelper * _helper, unsigned _activityId) : matched(_algo->matchInfo)
  2832. {
  2833. algo = LINK(_algo);
  2834. IOutputMetaData * outputMeta = algo->outRecordSize;
  2835. outputAllocator.setown(ctx->getRowAllocator(outputMeta, _activityId));
  2836. helper = _helper;
  2837. results.first();
  2838. charWidth = algo->charWidth;
  2839. }
  2840. RegexParser::~RegexParser()
  2841. {
  2842. matched.kill();
  2843. algo->Release();
  2844. }
  2845. bool RegexParser::performMatch(IMatchedAction & action, const void * row, unsigned len, const void * data)
  2846. {
  2847. try
  2848. {
  2849. results.reset();
  2850. len *= charWidth;
  2851. size32_t maxSize = algo->maxLength*charWidth;
  2852. const byte * start = (const byte *)data;
  2853. const byte * endData = start + len;
  2854. const byte * end = endData - algo->minPatternLength;
  2855. RegexState state(cache, algo->kind, helper, this, algo->inputFormat, len, start);
  2856. state.row = row;
  2857. state.processor = &action;
  2858. state.best = NULL;
  2859. for (const byte * curScan = start; curScan <= end;)
  2860. {
  2861. state.cur = curScan;
  2862. state.top.start = curScan;
  2863. state.nextScanPosition = NULL;
  2864. state.score = 0;
  2865. if (!algo->singleChoicePerLine)
  2866. state.best = NULL;
  2867. if ((size32_t)(endData - curScan) > maxSize)
  2868. {
  2869. state.end = curScan + (maxSize + charWidth);
  2870. state.lengthIsLimited = true;
  2871. }
  2872. else
  2873. {
  2874. state.end = endData;
  2875. state.lengthIsLimited = false;
  2876. }
  2877. algo->match(state);
  2878. if (state.numMatched >= algo->keepLimit)
  2879. break;
  2880. if (state.numMatched > algo->atMostLimit)
  2881. {
  2882. results.reset();
  2883. return false;
  2884. }
  2885. if (algo->scanAction == INlpParseAlgorithm::NlpScanWhole)
  2886. break;
  2887. if (state.numMatched && (algo->scanAction == INlpParseAlgorithm::NlpScanNone))
  2888. break;
  2889. if (state.nextScanPosition && (algo->scanAction == INlpParseAlgorithm::NlpScanNext) && (curScan != state.nextScanPosition))
  2890. curScan = state.nextScanPosition;
  2891. else
  2892. curScan += charWidth;
  2893. }
  2894. if (state.numMatched == 0)
  2895. {
  2896. if (algo->notMatchedOnly || algo->notMatched)
  2897. {
  2898. //Create a row where nothing matches.
  2899. MatchState & top = state.top;
  2900. top.end = top.start;
  2901. matched.extractResults(top, state.start, algo->addedSeparators);
  2902. NlpMatchWalker walker(&top);
  2903. const void * matchRow = createMatchRow(state, walker);
  2904. if (matchRow)
  2905. results.appendOwnResult(matchRow);
  2906. }
  2907. }
  2908. else if (algo->notMatchedOnly)
  2909. {
  2910. results.reset();
  2911. }
  2912. //Now reduce the number of matches according to min/max/best
  2913. return results.first();
  2914. }
  2915. catch (IException *)
  2916. {
  2917. throw;
  2918. }
  2919. catch (...)
  2920. {
  2921. throwError1(REGEXERR_MatchFailure, 0);
  2922. return false;
  2923. }
  2924. }
  2925. const void * RegexParser::createMatchRow(RegexState & state, NlpMatchWalker & walker)
  2926. {
  2927. RtlDynamicRowBuilder row(outputAllocator);
  2928. unsigned rowSize = state.processor->onMatch(row, state.row, &matched, &walker);
  2929. if (rowSize)
  2930. return row.finalizeRowClear(rowSize);
  2931. return NULL;
  2932. }
  2933. bool RegexParser::onMatch(NlpState & _state)
  2934. {
  2935. if ((algo->scanAction == INlpParseAlgorithm::NlpScanWhole) && (_state.cur != _state.end))
  2936. return false;
  2937. RegexState & state = (RegexState &)_state;
  2938. if (state.lengthIsLimited && state.cur == state.end)
  2939. return false;
  2940. MatchState & top = state.top;
  2941. const byte * end = top.end;
  2942. unsigned length = (size32_t)(end - top.start);
  2943. RegexMatchInfo * result = NULL;
  2944. if (algo->chooseMin || algo->chooseMax || algo->chooseBest)
  2945. {
  2946. RegexMatchInfo * best = state.best;
  2947. if (best)
  2948. {
  2949. int comp = 0;
  2950. if (algo->chooseMin)
  2951. comp = (int)(length - best->length);
  2952. else if (algo->chooseMax)
  2953. comp = (int)(best->length - length);
  2954. if (algo->chooseBest && (comp == 0))
  2955. comp = (int)(best->score - state.score);
  2956. if (comp >= 0)
  2957. return false;
  2958. }
  2959. else
  2960. {
  2961. state.best = results.createMatch();
  2962. state.numMatched++;
  2963. }
  2964. result = state.best;
  2965. state.nextScanPosition = end;
  2966. }
  2967. else
  2968. {
  2969. if (!state.nextScanPosition || state.nextScanPosition > end)
  2970. state.nextScanPosition = end;
  2971. }
  2972. matched.extractResults(top, state.start, algo->addedSeparators);
  2973. NlpMatchWalker walker(&top);
  2974. const void * newRow = createMatchRow(state, walker);
  2975. if (!newRow)
  2976. return false;
  2977. if (!result)
  2978. {
  2979. result = results.appendOwnResult(newRow);
  2980. state.numMatched++;
  2981. }
  2982. else
  2983. {
  2984. result->setown(newRow);
  2985. }
  2986. result->score = state.score;
  2987. result->length = length;
  2988. if (algo->matchAction == INlpParseAlgorithm::NlpMatchAll)
  2989. {
  2990. if (state.numMatched >= algo->keepLimit)
  2991. return true;
  2992. if (state.numMatched > algo->atMostLimit)
  2993. return true;
  2994. return false;
  2995. }
  2996. return true;
  2997. }
  2998. /*
  2999. #if 0
  3000. RegexMatchAction RegexDFAPattern::match(MatchState & state)
  3001. {
  3002. const byte * savedCur = state.cur;
  3003. while (!fail)
  3004. {
  3005. if (consume & in a match state), add it to a list else fail
  3006. else
  3007. }
  3008. ForEachItemInrev(matches)
  3009. {
  3010. state.cur =matches.item(idx);
  3011. if (matchNext(state) == RegexMatchDone)
  3012. return RegexMatchDone;
  3013. }
  3014. state.cur = savedCur;
  3015. return RegexMatchBacktrack;
  3016. }
  3017. Converting a NFA:
  3018. States, transition(symbol)->*states
  3019. to a DFA
  3020. States, transition(symbol)->state
  3021. Create a set of set-of-nstates Dstates that can be reached from the initial.
  3022. ForEachUnmarkedDState(T)
  3023. ForEachSymbol(x),
  3024. U = possible states that could be reach after that
  3025. if U not in DStates, add it.
  3026. Save DTrans[T,a] = U
  3027. End
  3028. End
  3029. All states that can be reached at all onto a stack
  3030. regular expressions:
  3031. *+? have highest
  3032. then concat
  3033. then
  3034. r|(s|t) == (r|s)|t
  3035. (rs)t == r(st)
  3036. r(s|t) == rs|rt
  3037. er == r == re
  3038. r* = (r|e)*
  3039. r** = r*
  3040. Regular expression to NFA:
  3041. Fairly simple - gives a list of Node(All transitions and actions)
  3042. Running a NFA:
  3043. Simple algorithmn maintains a sets of possible states. So all calculated at the same time.
  3044. - Solves problem of repeatadly searching, but I don't think it could be used for matching text,
  3045. because no positioning information is maintained.
  3046. - Use an ordered list of next-states which
  3047. Lazy
  3048. }}}
  3049. #endif
  3050. */