thortalgo.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  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. #include "jliball.hpp"
  14. #include "eclrtl.hpp"
  15. #include "rtlds_imp.hpp"
  16. #include "thortalgo.ipp"
  17. #include "thortparse.ipp"
  18. IEngineRowAllocator * TomitaParserCallback::queryAllocator(IOutputMetaData * searchMeta) const
  19. {
  20. ForEachItemIn(i, allocators)
  21. {
  22. IEngineRowAllocator & cur = allocators.item(i);
  23. if (cur.queryOutputMeta() == searchMeta)
  24. return &cur;
  25. }
  26. return NULL;
  27. }
  28. void TomitaStateInformation::set(const TomitaStateInformation & other)
  29. {
  30. action = other.action;
  31. row = other.row;
  32. inputText = other.inputText;
  33. lengthInputText = other.lengthInputText;
  34. helper = other.helper;
  35. helperArg = other.helperArg;
  36. }
  37. //---------------------------------------------------------------------------
  38. GrammarSymbol * TomitaMatchSearchInstance::findInChildren(GrammarSymbol * top, const TomitaMatchPath & path, unsigned depth)
  39. {
  40. unsigned prevExactMatchDepth = lastExactMatchDepth;
  41. for (unsigned i = 0;; i++)
  42. {
  43. GrammarSymbol * child = top->queryChild(i);
  44. if (!child)
  45. return NULL;
  46. GrammarSymbol * ret = find(child, path, depth);
  47. if (prevExactMatchDepth != lastExactMatchDepth)
  48. return ret;
  49. }
  50. return NULL;
  51. }
  52. GrammarSymbol * TomitaMatchSearchInstance::find(GrammarSymbol * top, const TomitaMatchPath & path, unsigned depth)
  53. {
  54. if (top->isPacked())
  55. top = top->queryPacked(choices->getInstance(top));
  56. regexid_t id = path.getId(depth);
  57. if (top->getId() == id)
  58. {
  59. bool matchAny = path.matchAny(depth);
  60. if (matchAny || (nextIndex == 1))
  61. {
  62. if (depth+1 == path.numItems())
  63. {
  64. lastExactMatchDepth = depth+1;
  65. return top;
  66. }
  67. if (!matchAny)
  68. {
  69. lastExactMatchDepth = depth+1;
  70. nextIndex = path.nextExactMatchIndex(depth+1);
  71. }
  72. return findInChildren(top, path, depth+1);
  73. }
  74. else
  75. {
  76. nextIndex--;
  77. return NULL;
  78. }
  79. }
  80. else
  81. return findInChildren(top, path, depth);
  82. }
  83. IMatchedElement * TomitaMatchPath::getMatch(GrammarSymbol * top, PackedSymbolChoice & choice) const
  84. {
  85. TomitaMatchSearchInstance search;
  86. search.lastExactMatchDepth = 0;
  87. search.nextIndex = nextExactMatchIndex(0);
  88. search.choices = &choice;
  89. GrammarSymbol * state = search.find(top, *this, 0);
  90. if (!state)
  91. return NULL;
  92. return LINK(state);
  93. }
  94. void CTomitaMatchedResults::extractResults(GrammarSymbol * top, PackedSymbolChoice & choice, const byte * _in)
  95. {
  96. in = _in;
  97. notMatched.ptr = in;
  98. ForEachItemIn(idx, def->matchResults)
  99. {
  100. ::Release(matched[idx]);
  101. matched[idx] = ((TomitaMatchPath &)def->matchResults.item(idx)).getMatch(top, choice);
  102. if (!matched[idx]) matched[idx] = LINK(&notMatched);
  103. }
  104. rootResult = top->queryResultRow();
  105. }
  106. //---------------------------------------------------------------------------
  107. FeatureInfo::FeatureInfo()
  108. {
  109. numMask = 0;
  110. numFlat = 0;
  111. defaults = NULL;
  112. }
  113. FeatureInfo::~FeatureInfo()
  114. {
  115. free(defaults);
  116. }
  117. void FeatureInfo::deserialize(MemoryBuffer & in)
  118. {
  119. in.read(numMask);
  120. in.read(numFlat);
  121. unsigned size = getSize();
  122. defaults = malloc(size);
  123. in.read(size, defaults);
  124. }
  125. void FeatureInfo::serialize(MemoryBuffer & out)
  126. {
  127. out.append(numMask);
  128. out.append(numFlat);
  129. out.append(getSize(), defaults);
  130. }
  131. //---------------------------------------------------------------------------
  132. FeatureAction::FeatureAction()
  133. {
  134. featureKind = 0;;
  135. srcSymbol = 0;
  136. srcFeatureIndex = 0;
  137. tgtFeatureIndex = 0;
  138. }
  139. void FeatureAction::deserialize(MemoryBuffer & in)
  140. {
  141. in.read(featureKind).read(srcSymbol).read(srcFeatureIndex).read(tgtFeatureIndex);
  142. }
  143. void FeatureAction::serialize(MemoryBuffer & out)
  144. {
  145. out.append(featureKind).append(srcSymbol).append(srcFeatureIndex).append(tgtFeatureIndex);
  146. }
  147. void ProductionFeatureInfo::deserialize(MemoryBuffer & in)
  148. {
  149. result.deserialize(in);
  150. extra.deserialize(in);
  151. unsigned numActions;
  152. in.read(numActions);
  153. for (unsigned i = 0; i < numActions; numActions++)
  154. {
  155. FeatureAction & cur = * new FeatureAction;
  156. cur.deserialize(in);
  157. actions.append(cur);
  158. }
  159. }
  160. void ProductionFeatureInfo::serialize(MemoryBuffer & out)
  161. {
  162. result.serialize(out);
  163. extra.serialize(out);
  164. unsigned numActions = actions.ordinality();
  165. out.append(numActions);
  166. ForEachItemIn(i, actions)
  167. actions.item(i).serialize(out);
  168. }
  169. //---------------------------------------------------------------------------
  170. inline bool isMaskValid(mask_feature_t & value, const mask_feature_t test)
  171. {
  172. return (value &= test) != 0;
  173. }
  174. inline bool isFlatValid(flat_feature_t & value, const flat_feature_t test)
  175. {
  176. if (value == UNKNOWN_FEATURE)
  177. value = test;
  178. else if ((value != test) && (test != UNKNOWN_FEATURE))
  179. return false;
  180. return true;
  181. }
  182. bool mergeFeatures(FeatureValue & result, const ProductionFeatureInfo * info, GrammarSymbol * * symbols)
  183. {
  184. if (info->totalFeatures() == 0)
  185. return true;
  186. //Features come in two types - masks and flat. For masks we perform intersection, flat must be equal.
  187. //A production may have associated features (in result), and may also have features checked within the production (extra)
  188. mask_feature_t * resultMaskFeature = NULL;
  189. flat_feature_t * resultFlatFeature = NULL;
  190. if (info->result.getNum() != 0)
  191. {
  192. unsigned size = info->result.getSize();
  193. void * resultFeatures = result.values.allocate(size);
  194. memcpy(resultFeatures, info->result.defaults, size);
  195. resultMaskFeature = (mask_feature_t *)resultFeatures;
  196. resultFlatFeature = (flat_feature_t *)(resultMaskFeature + info->result.numMask);
  197. }
  198. mask_feature_t * extraMaskFeature = NULL;
  199. flat_feature_t * extraFlatFeature = NULL;
  200. MemoryAttr featuresTemp;
  201. if (info->extra.getNum() != 0)
  202. {
  203. unsigned size = info->extra.getSize();
  204. void * extraFeatures = featuresTemp.allocate(size);
  205. memcpy(extraFeatures, info->extra.defaults, size);
  206. extraMaskFeature = (mask_feature_t *)extraFeatures;
  207. extraFlatFeature = (flat_feature_t *)(extraMaskFeature + info->extra.numMask);
  208. }
  209. ForEachItemIn(i, info->actions)
  210. {
  211. const FeatureAction & cur = info->actions.item(i);
  212. const GrammarSymbol * srcSymbol = symbols[cur.srcSymbol];
  213. const FeatureValue & src = srcSymbol->features;
  214. const mask_feature_t * srcMaskValues = (const mask_feature_t *)src.values.get();
  215. unsigned tgtFeatureIndex = cur.tgtFeatureIndex;
  216. switch (cur.featureKind)
  217. {
  218. case FKmask:
  219. {
  220. mask_feature_t srcValue = srcMaskValues[cur.srcFeatureIndex];
  221. if (!isMaskValid(resultMaskFeature[tgtFeatureIndex], srcValue))
  222. return false;
  223. break;
  224. }
  225. case FKflat:
  226. {
  227. unsigned numSrcMask = srcSymbol->features.info->numMask;
  228. flat_feature_t * srcFlatValues = (flat_feature_t *)(srcMaskValues + numSrcMask);
  229. flat_feature_t srcValue = srcFlatValues[cur.srcFeatureIndex];
  230. if (!isFlatValid(resultFlatFeature[tgtFeatureIndex], srcValue))
  231. return false;
  232. break;
  233. }
  234. case FKemask:
  235. {
  236. mask_feature_t srcValue = srcMaskValues[cur.srcFeatureIndex];
  237. if (!isMaskValid(extraMaskFeature[tgtFeatureIndex], srcValue))
  238. return false;
  239. break;
  240. }
  241. case FKeflat:
  242. {
  243. unsigned numSrcMask = srcSymbol->features.info->numMask;
  244. flat_feature_t * srcFlatValues = (flat_feature_t *)(srcMaskValues + numSrcMask);
  245. flat_feature_t srcValue = srcFlatValues[cur.srcFeatureIndex];
  246. if (!isFlatValid(extraFlatFeature[tgtFeatureIndex], srcValue))
  247. return false;
  248. break;
  249. }
  250. }
  251. }
  252. result.info = &info->result;
  253. return true;
  254. }
  255. //---------------------------------------------------------------------------
  256. LRValidator::LRValidator()
  257. {
  258. kind = LRVnone;
  259. dfa = NULL;
  260. }
  261. LRValidator::~LRValidator()
  262. {
  263. delete dfa;
  264. }
  265. void LRValidator::deserialize(MemoryBuffer & in)
  266. {
  267. in.read(kind);
  268. switch (kind)
  269. {
  270. case LRVnone:
  271. case LRVfirst:
  272. case LRVlast:
  273. break;
  274. case LRVvalidateasc:
  275. case LRVvalidateuni:
  276. in.read(validatorIndex);
  277. break;
  278. case LRVchecklength:
  279. in.read(minExpectedBytes).read(maxExpectedBytes);
  280. break;
  281. case LRVcheckin:
  282. case LRVbefore:
  283. dfa = new AsciiDfa;
  284. dfa->deserialize(in);
  285. break;
  286. case LRVafter:
  287. in.read(minExpectedBytes).read(maxExpectedBytes);
  288. dfa = new AsciiDfa;
  289. dfa->deserialize(in);
  290. break;
  291. default:
  292. UNIMPLEMENTED;
  293. }
  294. }
  295. void LRValidator::serialize(MemoryBuffer & out)
  296. {
  297. out.append(kind);
  298. switch (kind)
  299. {
  300. case LRVnone:
  301. case LRVfirst:
  302. case LRVlast:
  303. break;
  304. case LRVvalidateasc:
  305. case LRVvalidateuni:
  306. out.append(validatorIndex);
  307. break;
  308. case LRVchecklength:
  309. out.append(minExpectedBytes).append(maxExpectedBytes);
  310. break;
  311. case LRVcheckin:
  312. case LRVbefore:
  313. dfa->serialize(out);
  314. break;
  315. case LRVafter:
  316. out.append(minExpectedBytes).append(maxExpectedBytes);
  317. dfa->serialize(out);
  318. break;
  319. default:
  320. UNIMPLEMENTED;
  321. }
  322. }
  323. StringBuffer & LRValidator::trace(StringBuffer & out)
  324. {
  325. switch (kind)
  326. {
  327. case LRVfirst:
  328. return out.append(" valid(first)");
  329. case LRVlast:
  330. return out.append(" valid(last)");
  331. case LRVvalidateasc:
  332. return out.appendf(" valid(asc:%d)", validatorIndex);
  333. case LRVvalidateuni:
  334. return out.appendf(" valid(uni:%d)", validatorIndex);
  335. case LRVchecklength:
  336. return out.appendf(" valid(length:%d..%d)", minExpectedBytes, maxExpectedBytes);
  337. case LRVcheckin:
  338. return out.append(" valid(in)");
  339. case LRVbefore:
  340. return out.append(" valid(before)");
  341. case LRVafter:
  342. return out.appendf(" valid(after:%d..%d)", minExpectedBytes, maxExpectedBytes);
  343. }
  344. return out;
  345. }
  346. bool LRValidator::isValid(unsigned numSymbols, GrammarSymbol * * symbols, const byte * reducePtr, const TomitaParserCallback & state)
  347. {
  348. switch (kind)
  349. {
  350. case LRVnone:
  351. return true;
  352. case LRVfirst:
  353. if (numSymbols != 0)
  354. return (symbols[0]->queryStartPtr() == state.inputText);
  355. return (reducePtr == state.inputText);
  356. case LRVlast:
  357. if (numSymbols != 0)
  358. return (symbols[0]->queryEndPtr() == state.inputText+state.lengthInputText);
  359. return (reducePtr == state.inputText+state.lengthInputText);
  360. case LRVvalidateasc:
  361. {
  362. IStringValidator * validator = (IStringValidator *)state.helper->queryValidator(validatorIndex);
  363. unsigned len = 0;
  364. const byte * start = NULL;
  365. if (numSymbols)
  366. {
  367. start = symbols[0]->queryStartPtr();
  368. len = (size32_t)(symbols[numSymbols-1]->queryEndPtr() - start);
  369. }
  370. if (state.inputFormat == NlpAscii)
  371. return validator->isValid(len, (const char *)start);
  372. unsigned asciiLen;
  373. char * asciiText;
  374. if (state.inputFormat == NlpUnicode)
  375. rtlUnicodeToStrX(asciiLen, asciiText, len/sizeof(UChar), (const UChar *)start);
  376. else
  377. rtlUtf8ToStrX(asciiLen, asciiText, rtlUtf8Length(len, start), (const char *)start);
  378. bool ok = validator->isValid(asciiLen, asciiText);
  379. rtlFree(asciiText);
  380. return ok;
  381. }
  382. case LRVvalidateuni:
  383. {
  384. IUnicodeValidator * validator = (IUnicodeValidator *)state.helper->queryValidator(validatorIndex);
  385. unsigned len = 0;
  386. const byte * start = NULL;
  387. if (numSymbols)
  388. {
  389. start = symbols[0]->queryStartPtr();
  390. len = (size32_t)(symbols[numSymbols-1]->queryEndPtr() - start);
  391. }
  392. if (state.inputFormat == NlpUnicode)
  393. return validator->isValid(len/sizeof(UChar), (const UChar *)start);
  394. unsigned unicodeLen;
  395. UChar * unicodeText;
  396. if (state.inputFormat == NlpAscii)
  397. rtlStrToUnicodeX(unicodeLen, unicodeText, len, (const char *)start);
  398. else
  399. rtlUtf8ToUnicodeX(unicodeLen, unicodeText, rtlUtf8Length(len, start), (const char *)start);
  400. bool ok = validator->isValid(unicodeLen, unicodeText);
  401. rtlFree(unicodeText);
  402. return ok;
  403. }
  404. case LRVchecklength:
  405. {
  406. unsigned len = 0;
  407. if (numSymbols)
  408. {
  409. const byte * start = symbols[0]->queryStartPtr();
  410. len = (size32_t)(symbols[numSymbols-1]->queryEndPtr() - start);
  411. if (state.inputFormat == NlpUtf8)
  412. len = rtlUtf8Length(len, start);
  413. }
  414. return (len >= minExpectedBytes) && (len <= maxExpectedBytes);
  415. }
  416. case LRVcheckin:
  417. {
  418. unsigned len = 0;
  419. const byte * start = NULL;
  420. if (numSymbols)
  421. {
  422. start = symbols[0]->queryStartPtr();
  423. len = (size32_t)(symbols[numSymbols-1]->queryEndPtr() - start);
  424. }
  425. return (getMaximumMatchLength(*dfa, len, start) == len);
  426. }
  427. case LRVbefore:
  428. {
  429. const byte * nextPtr = reducePtr;
  430. if (numSymbols)
  431. nextPtr = symbols[numSymbols-1]->queryEndPtr();
  432. const byte * startInputText = state.inputText;
  433. const byte * endInputText = startInputText + state.lengthInputText;
  434. return (getMaximumMatchLength(*dfa, (size32_t)(endInputText - nextPtr), nextPtr) != NotFound);
  435. }
  436. case LRVafter:
  437. {
  438. const byte * startPtr = reducePtr;
  439. if (numSymbols)
  440. startPtr = symbols[0]->queryStartPtr();
  441. const byte * startInputText = state.inputText;
  442. const byte * firstPtr = (startPtr >= startInputText + maxExpectedBytes) ? startPtr - maxExpectedBytes : startInputText;
  443. const byte * lastPtr = (startPtr >= startInputText + minExpectedBytes) ? startPtr - minExpectedBytes : startInputText;
  444. for (const byte * ptr = firstPtr; ptr <= lastPtr; ptr++)
  445. {
  446. if (getMaximumMatchLength(*dfa, (size32_t)(startPtr-ptr), ptr) != NotFound)
  447. return true;
  448. }
  449. return false;
  450. }
  451. default:
  452. UNIMPLEMENTED;
  453. }
  454. }
  455. //---------------------------------------------------------------------------
  456. class ProductionCallback : public CInterface, implements IProductionCallback
  457. {
  458. public:
  459. ProductionCallback(const TomitaParserCallback & _state, unsigned _numSymbols, GrammarSymbol * * _symbols) : state(_state)
  460. {
  461. numSymbols = _numSymbols;
  462. symbols = _symbols;
  463. }
  464. virtual void getText(size32_t & outlen, char * & out, unsigned idx)
  465. {
  466. assertex(idx < numSymbols);
  467. const GrammarSymbol * cur = symbols[idx];
  468. const byte * start = cur->queryStartPtr();
  469. size32_t size = (size32_t)(cur->queryEndPtr() - start);
  470. switch (state.inputFormat)
  471. {
  472. case NlpAscii:
  473. rtlStrToStrX(outlen, out, size, start);
  474. break;
  475. case NlpUtf8:
  476. {
  477. unsigned len = rtlUtf8Length(size, start);
  478. rtlUtf8ToStrX(outlen, out, len, (const char *)start);
  479. break;
  480. }
  481. case NlpUnicode:
  482. rtlUnicodeToStrX(outlen, out, size/sizeof(UChar), (const UChar *)start);
  483. break;
  484. }
  485. }
  486. virtual void getUnicode(size32_t & outlen, UChar * & out, unsigned idx)
  487. {
  488. assertex(idx < numSymbols);
  489. const GrammarSymbol * cur = symbols[idx];
  490. const byte * start = cur->queryStartPtr();
  491. size32_t size = (size32_t)(cur->queryEndPtr() - start);
  492. switch (state.inputFormat)
  493. {
  494. case NlpAscii:
  495. rtlStrToUnicodeX(outlen, out, size, (const char *)start);
  496. break;
  497. case NlpUtf8:
  498. {
  499. unsigned len = rtlUtf8Length(size, start);
  500. rtlUtf8ToUnicodeX(outlen, out, len, (const char *)start);
  501. break;
  502. }
  503. case NlpUnicode:
  504. rtlUnicodeToUnicodeX(outlen, out, size/sizeof(UChar), (const UChar*)start);
  505. break;
  506. }
  507. }
  508. virtual void getUtf8(size32_t & outlen, char * & out, unsigned idx)
  509. {
  510. assertex(idx < numSymbols);
  511. const GrammarSymbol * cur = symbols[idx];
  512. const byte * start = cur->queryStartPtr();
  513. size32_t size = (size32_t)(cur->queryEndPtr() - start);
  514. switch (state.inputFormat)
  515. {
  516. case NlpAscii:
  517. rtlStrToUtf8X(outlen, out, size, (const char *)start);
  518. break;
  519. case NlpUtf8:
  520. {
  521. unsigned len = rtlUtf8Length(size, start);
  522. rtlUtf8ToUtf8X(outlen, out, len, (const char*)start);
  523. break;
  524. }
  525. case NlpUnicode:
  526. rtlUnicodeToUtf8X(outlen, out, size/sizeof(UChar), (const UChar*)start);
  527. break;
  528. }
  529. }
  530. virtual byte * queryResult(unsigned idx)
  531. {
  532. assertex(idx < numSymbols);
  533. return symbols[idx]->queryResultRow();
  534. }
  535. protected:
  536. const TomitaParserCallback & state;
  537. unsigned numSymbols;
  538. GrammarSymbol * * symbols;
  539. };
  540. //---------------------------------------------------------------------------
  541. LRProduction::LRProduction()
  542. {
  543. prodId = NotFound;
  544. ruleId = NotFound;
  545. numSymbols = 0;
  546. ruleName = NULL;
  547. transformClonesFirstSymbol = false;
  548. }
  549. void LRProduction::deserialize(unsigned _prodId, MemoryBuffer & in)
  550. {
  551. prodId = _prodId;
  552. StringAttr temp;
  553. unsigned numSymbolsMask;
  554. in.read(ruleId).read(numSymbolsMask).read(penalty);
  555. numSymbols = (unsigned short)numSymbolsMask;
  556. transformClonesFirstSymbol = (numSymbolsMask & NSFclonesFirstSymbol) != 0;
  557. ::deserialize(in, temp);
  558. ruleName = createAtom(temp);
  559. feature.deserialize(in);
  560. validator.deserialize(in);
  561. }
  562. void LRProduction::serialize(MemoryBuffer & out)
  563. {
  564. unsigned numSymbolsMask = numSymbols;
  565. if (transformClonesFirstSymbol)
  566. numSymbolsMask |= NSFclonesFirstSymbol;
  567. out.append(ruleId).append(numSymbolsMask).append(penalty);
  568. ::serialize(out, ruleName->str());
  569. feature.serialize(out);
  570. validator.serialize(out);
  571. }
  572. void LRProduction::setMetaData(IOutputMetaData * size)
  573. {
  574. resultSize.set(size);
  575. }
  576. GrammarSymbol * LRProduction::reduce(GrammarSymbol * * symbols, const byte * reducePtr, const TomitaParserCallback & state)
  577. {
  578. FeatureValue resultFeatures;
  579. //check whether guard conditions are met.
  580. if (!mergeFeatures(resultFeatures, &feature, symbols))
  581. return NULL;
  582. //Is the user
  583. if (!validator.isValid(numSymbols, symbols, reducePtr, state))
  584. return NULL;
  585. size32_t rowSize = 0;
  586. const void * rowData = NULL;
  587. if (resultSize)
  588. {
  589. if (transformClonesFirstSymbol)
  590. {
  591. //Need to clone from the first (and only) symbol that has an associated row
  592. GrammarSymbol * match = NULL;
  593. for (unsigned i = 0; i < numSymbols; i++)
  594. {
  595. GrammarSymbol * cur = symbols[i];
  596. if (cur->queryResultRow())
  597. {
  598. assertex(!match);
  599. match = cur;
  600. }
  601. }
  602. rowSize = match->queryResultSize();
  603. //Avoid cloning the transform information
  604. void * matchRow = match->queryResultRow();
  605. assertex(matchRow);
  606. rowData = rtlLinkRow(matchRow);
  607. }
  608. else
  609. {
  610. IEngineRowAllocator * allocator = state.queryAllocator(resultSize);
  611. ProductionCallback callback(state, numSymbols, symbols);
  612. RtlDynamicRowBuilder rowBuilder(allocator);
  613. try
  614. {
  615. rowSize = state.helperArg->executeProduction(rowBuilder, prodId, &callback);
  616. }
  617. catch (...)
  618. {
  619. allocator->releaseRow(rowData);
  620. throw;
  621. }
  622. if (rowSize == 0)
  623. {
  624. //more: executeProduction could throw an exception
  625. return NULL;
  626. }
  627. rowData = rowBuilder.finalizeRowClear(rowSize);
  628. }
  629. }
  630. GrammarSymbol * ret = new NonTerminal(ruleId, ruleName, resultFeatures, numSymbols, symbols, reducePtr, rowSize, (byte *)rowData);
  631. ret->addPenalty(penalty);
  632. return ret;
  633. }
  634. StringBuffer & LRProduction::trace(StringBuffer & out, unsigned id)
  635. {
  636. out.appendf("\t[%d] rule:%d pop:%d", id, ruleId, numSymbols);
  637. validator.trace(out);
  638. return out.newline();
  639. }
  640. //---------------------------------------------------------------------------
  641. StringBuffer & LRAction::trace(StringBuffer & out)
  642. {
  643. switch (getAction())
  644. {
  645. case AcceptAction: return out.append("A");
  646. case ShiftAction: return out.append("S").append(getExtra());
  647. case ReduceAction: return out.append("R").append(getExtra());
  648. default:
  649. UNIMPLEMENTED;
  650. }
  651. }
  652. //---------------------------------------------------------------------------
  653. LRState::LRState(LRTable * _table, LRAction * _actions, unsigned * _gotos)
  654. {
  655. table = _table;
  656. actions = _actions;
  657. gotos = _gotos;
  658. }
  659. LRState::~LRState()
  660. {
  661. }
  662. bool LRState::canAccept(token_id sym) const
  663. {
  664. LRAction & cur = actions[sym];
  665. ActionKind action = cur.getAction();
  666. if (action == MultiAction)
  667. {
  668. LRAction * multi = table->extraActions + cur.getExtra();
  669. loop
  670. {
  671. action = multi->getAction();
  672. if (action == NoAction)
  673. return false;
  674. else if (action == AcceptAction)
  675. return true;
  676. multi++;
  677. }
  678. }
  679. return action == AcceptAction;
  680. }
  681. state_id LRState::getGoto(symbol_id sym) const
  682. {
  683. return gotos[sym-table->numTokens];
  684. }
  685. state_id LRState::getShift(token_id sym) const
  686. {
  687. LRAction & cur = actions[sym];
  688. ActionKind action = cur.getAction();
  689. if (action == MultiAction)
  690. {
  691. LRAction * multi = table->extraActions + cur.getExtra();
  692. loop
  693. {
  694. action = multi->getAction();
  695. if (action == NoAction)
  696. return false;
  697. else if (action == ShiftAction)
  698. return multi->getExtra();
  699. multi++;
  700. }
  701. }
  702. if (action == ShiftAction)
  703. return cur.getExtra();
  704. return NotFound;
  705. }
  706. unsigned LRState::numReductions(token_id sym) const
  707. {
  708. LRAction & cur = actions[sym];
  709. ActionKind action = cur.getAction();
  710. if (action == MultiAction)
  711. {
  712. unsigned count = 0;
  713. LRAction * multi = table->extraActions + cur.getExtra();
  714. loop
  715. {
  716. action = multi->getAction();
  717. if (action == NoAction)
  718. return count;
  719. else if (action == ReduceAction)
  720. count++;
  721. multi++;
  722. }
  723. }
  724. if (action == ReduceAction)
  725. return 1;
  726. return 0;
  727. }
  728. unsigned LRState::queryReduction(token_id sym, unsigned idx) const
  729. {
  730. LRAction & cur = actions[sym];
  731. ActionKind action = cur.getAction();
  732. if (action == MultiAction)
  733. {
  734. LRAction * multi = table->extraActions + cur.getExtra();
  735. loop
  736. {
  737. action = multi->getAction();
  738. if (action == NoAction)
  739. return NotFound;
  740. else if (action == ReduceAction)
  741. {
  742. if (idx == 0)
  743. return multi->getExtra();
  744. idx--;
  745. }
  746. multi++;
  747. }
  748. }
  749. if ((action == ReduceAction) && (idx == 0))
  750. return cur.getExtra();
  751. return NotFound;
  752. }
  753. StringBuffer & LRState::trace(StringBuffer & out, unsigned id) const
  754. {
  755. out.appendf("\t[%d]\t", id);
  756. if (id < 10) out.append('\t');
  757. #if 1
  758. for (unsigned i=0; i < table->numTokens; i++)
  759. {
  760. LRAction & cur = actions[i];
  761. ActionKind action = cur.getAction();
  762. if (action != NoAction)
  763. {
  764. if (action == MultiAction)
  765. {
  766. out.append("{");
  767. LRAction * multi = table->extraActions + cur.getExtra();
  768. loop
  769. {
  770. action = multi->getAction();
  771. if (action == NoAction)
  772. break;
  773. multi->trace(out);
  774. multi++;
  775. }
  776. out.append("}");
  777. }
  778. else
  779. cur.trace(out);
  780. out.append("\t");
  781. }
  782. else
  783. out.append("\t");
  784. }
  785. out.append("\tGoto: ");
  786. for (unsigned j = table->numTokens; j < table->numSymbols; j++)
  787. {
  788. if (gotos[j-table->numTokens])
  789. out.append(j).append("->").append(gotos[j-table->numTokens]).append(" ");
  790. }
  791. #else
  792. for (unsigned i=0; i < table->numTokens; i++)
  793. {
  794. LRAction & cur = actions[i];
  795. ActionKind action = cur.getAction();
  796. if (action != NoAction)
  797. {
  798. out.append(i).append(":");
  799. if (action == MultiAction)
  800. {
  801. out.append("{");
  802. LRAction * multi = table->extraActions + cur.getExtra();
  803. loop
  804. {
  805. action = multi->getAction();
  806. if (action == NoAction)
  807. break;
  808. multi->trace(out);
  809. multi++;
  810. }
  811. out.append("}");
  812. }
  813. else
  814. cur.trace(out);
  815. out.append(" ");
  816. }
  817. }
  818. out.newline();
  819. out.append("\t\t\tGoto: ");
  820. for (unsigned j = table->numTokens; j < table->numSymbols; j++)
  821. {
  822. if (gotos[j-table->numTokens])
  823. out.append(j).append("->").append(gotos[j-table->numTokens]).append(" ");
  824. }
  825. #endif
  826. return out.newline();
  827. }
  828. //---------------------------------------------------------------------------
  829. LRTable::LRTable()
  830. {
  831. allActions = NULL;
  832. extraActions = NULL;
  833. allGotos = NULL;
  834. productions = NULL;
  835. states = NULL;
  836. rootState = NotFound;
  837. numStates = 0;
  838. numProductions = 0;
  839. numExtraActions = 0;
  840. numSymbols = 0;
  841. numTokens = 0;
  842. }
  843. LRTable::~LRTable()
  844. {
  845. for (unsigned i=0; i < numStates; i++)
  846. delete states[i];
  847. delete [] allActions;
  848. delete [] extraActions;
  849. delete [] allGotos;
  850. delete [] productions;
  851. delete [] states;
  852. }
  853. void LRTable::alloc()
  854. {
  855. unsigned numNonTerminals = (numSymbols-numTokens);
  856. allActions = new LRAction[numStates * numTokens];
  857. extraActions = numExtraActions ? new LRAction[numExtraActions] : NULL;
  858. allGotos = new unsigned[numStates * numNonTerminals];
  859. memset(allGotos, 0, sizeof(unsigned) * numStates * numNonTerminals);
  860. productions = new LRProduction[numProductions];
  861. states = new LRState * [numStates];
  862. for (unsigned i=0; i < numStates; i++)
  863. states[i] = new LRState(this, &allActions[i*numTokens], &allGotos[i*numNonTerminals]);
  864. }
  865. void LRTable::deserialize(MemoryBuffer & in)
  866. {
  867. in.read(numStates).read(numTokens).read(numSymbols).read(numProductions).read(numExtraActions);
  868. in.read(rootState);
  869. alloc();
  870. unsigned numNonTerminals = (numSymbols-numTokens);
  871. in.read(numStates*numTokens*sizeof(*allActions), allActions);
  872. in.read(numExtraActions*sizeof(*extraActions), extraActions);
  873. in.read(numStates*numNonTerminals*sizeof(*allGotos), allGotos);
  874. for (unsigned j=0; j < numProductions; j++)
  875. productions[j].deserialize(j, in);
  876. }
  877. void LRTable::serialize(MemoryBuffer & out)
  878. {
  879. out.append(numStates).append(numTokens).append(numSymbols).append(numProductions).append(numExtraActions);
  880. out.append(rootState);
  881. unsigned numNonTerminals = (numSymbols-numTokens);
  882. out.append(numStates*numTokens*sizeof(*allActions), allActions);
  883. out.append(numExtraActions*sizeof(*extraActions), extraActions);
  884. out.append(numStates*numNonTerminals*sizeof(*allGotos), allGotos);
  885. for (unsigned j=0; j < numProductions; j++)
  886. productions[j].serialize(out);
  887. }
  888. StringBuffer & LRTable::trace(StringBuffer & out)
  889. {
  890. out.append("States:\n");
  891. out.appendf("\tRoot=%d",rootState).newline();
  892. for (unsigned i = 0; i < numStates; i++)
  893. states[i]->trace(out, i);
  894. out.append("Productions:\n");
  895. for (unsigned j = 0; j < numProductions; j++)
  896. productions[j].trace(out, j);
  897. return out;
  898. }
  899. //---------------------------------------------------------------------------
  900. //-- LRTableBuilder --
  901. static int compareActions(CInterface * * _left, CInterface * * _right)
  902. {
  903. LRActionItem * left = static_cast<LRActionItem *>(*_left);
  904. LRActionItem * right = static_cast<LRActionItem *>(*_right);
  905. if (left->id < right->id) return -1;
  906. if (left->id > right->id) return +1;
  907. if (left->action.getValue() < right->action.getValue()) return -1;
  908. if (left->action.getValue() > right->action.getValue()) return +1;
  909. return 0;
  910. }
  911. LRTableBuilder::LRTableBuilder(LRTable & _table) : table(_table)
  912. {
  913. curState = NULL;
  914. ambiguous = false;
  915. }
  916. LRTableBuilder::~LRTableBuilder()
  917. {
  918. }
  919. void LRTableBuilder::init(unsigned _numStates, unsigned _numTokens, unsigned _numSymbols, unsigned _numProductions)
  920. {
  921. table.numStates = _numStates;
  922. table.numTokens = _numTokens;
  923. table.numSymbols = _numSymbols;
  924. table.numProductions = _numProductions;
  925. table.numExtraActions = 0;
  926. table.alloc();
  927. }
  928. void LRTableBuilder::addAccept(token_id id)
  929. {
  930. assertex(id < table.numTokens);
  931. actions.append(* new LRActionItem(id, AcceptAction, 0));
  932. }
  933. void LRTableBuilder::addShift(token_id id, unsigned newState)
  934. {
  935. assertex(id < table.numTokens);
  936. actions.append(* new LRActionItem(id, ShiftAction, newState));
  937. }
  938. void LRTableBuilder::addGoto(symbol_id id, unsigned newState)
  939. {
  940. assertex(id >= table.numTokens && id < table.numSymbols);
  941. curState->gotos[id - table.numTokens] = newState;
  942. }
  943. void LRTableBuilder::addProduction(unsigned id, unsigned ruleId, IAtom * ruleName, unsigned numToPop, int penalty, bool transformClonesFirstSymbol)
  944. {
  945. assertex(id < table.numProductions);
  946. LRProduction & cur = table.productions[id];
  947. cur.prodId = id;
  948. cur.numSymbols = numToPop;
  949. cur.ruleId = ruleId;
  950. cur.ruleName = ruleName;
  951. cur.penalty = penalty;
  952. cur.transformClonesFirstSymbol = transformClonesFirstSymbol;
  953. }
  954. void LRTableBuilder::addValidator(unsigned prodId, byte kind, unsigned low, unsigned high, AsciiDfa * dfa)
  955. {
  956. LRProduction & cur = table.productions[prodId];
  957. LRValidator & validator = cur.validator;
  958. assertex(validator.kind == LRVnone);
  959. validator.kind = kind;
  960. validator.minExpectedBytes = low;
  961. validator.maxExpectedBytes = high;
  962. validator.dfa = dfa;
  963. validator.validatorIndex = low;
  964. }
  965. void LRTableBuilder::addReduce(token_id id, unsigned prod)
  966. {
  967. assertex(id < table.numTokens && prod < table.numProductions);
  968. actions.append(* new LRActionItem(id, ReduceAction, prod));
  969. }
  970. void LRTableBuilder::beginState(unsigned id)
  971. {
  972. assertex(!curState);
  973. curState = table.states[id];
  974. }
  975. void LRTableBuilder::endState()
  976. {
  977. assertex(curState);
  978. actions.sort(compareActions);
  979. removeDuplicateShiftStates();
  980. unsigned max = actions.ordinality();
  981. for (unsigned i = 0; i < max; i++)
  982. {
  983. LRActionItem & cur = actions.item(i);
  984. unsigned j;
  985. for (j = i+1; j < max; j++)
  986. {
  987. if (actions.item(j).id != cur.id)
  988. break;
  989. }
  990. if (j - i > 1)
  991. {
  992. //Multiple entries.
  993. curState->actions[cur.id].set(MultiAction, extraActions.ordinality());
  994. for (unsigned k=i; k < j; k++)
  995. extraActions.append(actions.item(k).action.getValue());
  996. extraActions.append(0);
  997. i = j-1;
  998. ambiguous = true;
  999. }
  1000. else
  1001. curState->actions[cur.id].setValue(cur.action.getValue());
  1002. }
  1003. actions.kill();
  1004. curState = NULL;
  1005. }
  1006. void LRTableBuilder::finished(unsigned rootId)
  1007. {
  1008. assertex(sizeof(LRAction) == sizeof(unsigned));
  1009. table.rootState = rootId;
  1010. table.numExtraActions = extraActions.ordinality();
  1011. table.extraActions = new LRAction[table.numExtraActions];
  1012. memcpy(table.extraActions, extraActions.getArray(), sizeof(unsigned) * table.numExtraActions);
  1013. }
  1014. void LRTableBuilder::removeDuplicateShiftStates()
  1015. {
  1016. //Easiest way of handling duplicate shift states is to remove them in post-processing.
  1017. unsigned max = actions.ordinality();
  1018. if (max <= 1)
  1019. return;
  1020. for (unsigned i=max-1; i--; )
  1021. {
  1022. LRActionItem & cur = actions.item(i);
  1023. if (cur.action.getAction() == ShiftAction)
  1024. {
  1025. LRActionItem & next = actions.item(i+1);
  1026. if (cur.id == next.id && next.action.getAction() == ShiftAction)
  1027. {
  1028. assertex(cur.action.getValue() == next.action.getValue());
  1029. actions.remove(i+1);
  1030. }
  1031. }
  1032. }
  1033. }
  1034. //---------------------------------------------------------------------------
  1035. TomitaAlgorithm::TomitaAlgorithm(IRecordSize * _outRecordSize) : NlpAlgorithm(new CTomitaMatchedResultInfo)
  1036. {
  1037. outRecordSize.set(_outRecordSize);
  1038. }
  1039. TomitaAlgorithm::~TomitaAlgorithm()
  1040. {
  1041. }
  1042. void TomitaAlgorithm::init(IHThorParseArg & arg)
  1043. {
  1044. for (unsigned i=0; i < table.numProductions; i++)
  1045. {
  1046. IOutputMetaData * rs = arg.queryProductionMeta(i);
  1047. if (rs)
  1048. {
  1049. LRProduction & production = table.productions[i];
  1050. production.setMetaData(rs);
  1051. }
  1052. }
  1053. }
  1054. void TomitaAlgorithm::serialize(MemoryBuffer & out)
  1055. {
  1056. out.append((byte)NLPAtomita);
  1057. NlpAlgorithm::serialize(out);
  1058. table.serialize(out);
  1059. tokenDfa.serialize(out);
  1060. skipDfa.serialize(out);
  1061. out.append(eofId);
  1062. unsigned num = endTokenChars.ordinality();
  1063. out.append(num);
  1064. for (unsigned i=0; i < num; i++)
  1065. out.append(endTokenChars.item(i));
  1066. }
  1067. void TomitaAlgorithm::deserialize(MemoryBuffer & in)
  1068. {
  1069. NlpAlgorithm::deserialize(in);
  1070. table.deserialize(in);
  1071. tokenDfa.deserialize(in);
  1072. skipDfa.deserialize(in);
  1073. in.read(eofId);
  1074. unsigned num;
  1075. in.read(num);
  1076. for (unsigned i=0; i < num; i++)
  1077. {
  1078. unsigned temp;
  1079. in.read(temp);
  1080. endTokenChars.append(temp);
  1081. }
  1082. }
  1083. INlpParser * TomitaAlgorithm::createParser(ICodeContext * ctx, unsigned activityId, INlpHelper * helper, IHThorParseArg * arg)
  1084. {
  1085. return new TomitaParser(ctx, this, activityId, helper, arg);
  1086. }
  1087. INlpParseAlgorithm * createTomitaParser(MemoryBuffer & buffer, IOutputMetaData * outRecordSize)
  1088. {
  1089. TomitaAlgorithm * ret = new TomitaAlgorithm(outRecordSize);
  1090. ret->deserialize(buffer);
  1091. return ret;
  1092. }