DynGenPar
Dynamic Generalized Parser
dyngenpar.h
Go to the documentation of this file.
1 /* DynGenPar: Dynamic Generalized Parser
2  Copyright (C) 2010-2012 Kevin Kofler <kevin.kofler@chello.at>
3  Copyright (C) 2015-2018 DAGOPT Optimization Technologies GmbH
4  written by Kevin Kofler <kofler@dagopt.com>
5 
6  Support by the Austrian Science Fund FWF under contract numbers
7  P20631 and P23554 is gratefully acknowledged.
8 
9  This program is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 
22 // Don't use pragma once here, Qt Jambi doesn't support it.
23 #ifndef DYNGENPAR_H
24 #define DYNGENPAR_H
25 
26 #include <QString>
27 #include <QList>
28 #include <QStringList>
29 #include <QHash>
30 #include <QMultiHash>
31 #include <QSet>
32 #include <QPair>
33 #include <QQueue>
34 #include <QSharedData>
35 #include <QVariant>
36 #include <QVector>
37 #include <QDataStream>
38 
39 #include "priorityqueue.h"
40 
41 // Tell GCC that qFatal does not return.
42 // (In Qt 5, qFatal is already a macro and already gets this right.)
43 #if defined(__GNUC__) \
44  && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)) \
45  && QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
46 #define qFatal(x...) (qFatal(x), __builtin_unreachable())
47 #endif
48 
49 // Convenience macro to avoid copying&pasting namespace boilerplate
50 #define DYNGENPAR_DECLARE_TYPEINFO(type, typeclass) \
51  } /* end namespace DynGenPar */ \
52  Q_DECLARE_TYPEINFO(DynGenPar::type, typeclass); \
53  namespace DynGenPar {
54 
55 namespace DynGenPar {
56 
57 // --- general data structures (both context-free grammars and PMCFGs) ---
58 
59 #ifdef DYNGENPAR_INTEGER_CATEGORIES
60 typedef int Cat;
61 #define IS_EPSILON(cat) (!(cat))
62 typedef int CatArg;
63 #else
64 
71 typedef QString Cat;
72 #define IS_EPSILON(cat) ((cat).isNull())
73 
83 typedef const Cat &CatArg;
84 #endif
85 
89 
97 
105  bool operator==(const NextTokenConstraints &other) const {
106  return expect == other.expect && taboo == other.taboo;
107  }
109  QDataStream &writeExternal(QDataStream &stream) const {
110  return stream << expect << taboo;
111  }
113  QDataStream &readExternal(QDataStream &stream) {
114  return stream >> expect >> taboo;
115  }
116 };
117 uint qHash(const NextTokenConstraints &nextTokenConstraints);
118 DYNGENPAR_DECLARE_TYPEINFO(NextTokenConstraints, Q_MOVABLE_TYPE);
119 
121 class Action;
122 } // end namespace
123 
124 inline QDataStream &operator<<(QDataStream &stream,
125  const DynGenPar::Action *data);
126 inline QDataStream &operator>>(QDataStream &stream, DynGenPar::Action *&data);
127 
128 namespace DynGenPar {
129 class Rule : public QList<Cat> {
130  public:
131  static bool serializeLabels;
132  static bool serializeActions;
133  Rule() : QList<Cat>(), action(0) {}
134  explicit Rule(const QVariant &label)
135  : QList<Cat>(), action(0), lbl(label) {}
136  explicit Rule(const QList<Cat> &list)
137  : QList<Cat>(list), action(0), lbl() {}
138  Rule(const QList<Cat> &list, const QVariant &label)
139  : QList<Cat>(list), action(0), lbl(label) {}
140  QVariant label() const {return lbl;}
141  void setLabel(const QVariant &label) {lbl = label;}
144  Rule &operator+=(const QList<Cat> &other) {
145  QList<Cat>::operator+=(other);
146  return *this;
147  }
148  Rule &operator+=(const Cat &value) { // QList always wants a const &
149  QList<Cat>::operator+=(value);
150  return *this;
151  }
152  Rule &operator<<(const QList<Cat> &other) {
153  QList<Cat>::operator<<(other);
154  return *this;
155  }
156  Rule &operator<<(const Cat &value) { // QList always wants a const &
157  QList<Cat>::operator<<(value);
158  return *this;
159  }
161  void add(const Cat &value) { // QList always wants a const &
162  append(value);
163  }
165  QList<Cat> &toList() { return (QList<Cat> &) *this; }
167  QDataStream &writeExternal(QDataStream &stream, bool writeLabel = true,
168  bool writeAction = true) const {
169  return nextTokenConstraints.writeExternal(stream
170  << * (const QList<Cat> *) this
171  << (writeLabel ? lbl
172  : QVariant()))
173  << (writeAction ? action : static_cast<Action *>(0));
174  }
176  QDataStream &readExternal(QDataStream &stream) {
177  return nextTokenConstraints.readExternal(stream >> * (QList<Cat> *) this
178  >> lbl) >> action;
179  }
180 
181  private:
182  QVariant lbl;
183 };
184 DYNGENPAR_DECLARE_TYPEINFO(Rule, Q_MOVABLE_TYPE);
185 
186 typedef QHash<Cat, QList<Rule> > RuleSet;
187 typedef QSet<Cat> TokenSet;
188 
190 
193 struct Cfg {
195  Cfg() : rules(), tokens(), startCat() {}
196  Cfg(const RuleSet &r, const TokenSet &t, CatArg sc)
197  : rules(r), tokens(t), startCat(sc) {}
198  RuleSet rules;
199  TokenSet tokens;
201  bool isToken(CatArg cat) const {return tokens.contains(cat);}
202  void addToken(CatArg cat) {tokens.insert(cat);}
204  QDataStream &writeExternal(QDataStream &stream) const {
205  return stream << rules << tokens << startCat;
206  }
208  QDataStream &readExternal(QDataStream &stream) {
209  return stream >> rules >> tokens >> startCat;
210  }
211 };
212 DYNGENPAR_DECLARE_TYPEINFO(Cfg, Q_MOVABLE_TYPE);
213 
214 typedef QSet<Cat> Predictions;
215 
219  MultiPrediction() : fullLiteral(), cat() {}
220  MultiPrediction(const QList<Cat> &fullLit, CatArg c)
221  : fullLiteral(fullLit), cat(c) {}
224 
226  bool operator==(const MultiPrediction &other) const {
227  return fullLiteral == other.fullLiteral && cat == other.cat;
228  }
229 };
230 DYNGENPAR_DECLARE_TYPEINFO(MultiPrediction, Q_MOVABLE_TYPE);
231 
232 typedef QMultiHash<QList<Cat>, MultiPrediction> MultiPredictions;
233 typedef QMultiHash<Cat, NextTokenConstraints> ConstrainedPredictions;
234 
239  : fullLiteral(), cat(), nextTokenConstraints() {}
241  : fullLiteral(fullLit), cat(c), nextTokenConstraints() {}
244  : fullLiteral(fullLit), cat(c), nextTokenConstraints(ntc) {}
248 
250  bool operator==(const ConstrainedMultiPrediction &other) const {
251  return fullLiteral == other.fullLiteral && cat == other.cat
252  && nextTokenConstraints == other.nextTokenConstraints;
253  }
254 };
255 DYNGENPAR_DECLARE_TYPEINFO(ConstrainedMultiPrediction, Q_MOVABLE_TYPE);
256 
257 typedef QMultiHash<QList<Cat>, ConstrainedMultiPrediction>
259 
261 struct FullRule {
263  FullRule() : cat(), rule(), epsilonsSkipped(0), ruleno(0) {}
264  FullRule(CatArg c, const Rule &r, int epsSkipped, int n)
265  : cat(c), rule(r), epsilonsSkipped(epsSkipped), ruleno(n) {}
270 
272  int ruleno;
273 };
274 DYNGENPAR_DECLARE_TYPEINFO(FullRule, Q_MOVABLE_TYPE);
275 
277 struct Node;
278 class Alternative : public QList<Node> {
279  public:
281  explicit Alternative(const QVariant &label)
282  : QList<DynGenPar::Node>(), lbl(label) {}
283  explicit Alternative(const QList<DynGenPar::Node> &list)
284  : QList<DynGenPar::Node>(list), lbl() {}
285  Alternative(const QList<DynGenPar::Node> &list, const QVariant &label)
286  : QList<DynGenPar::Node>(list), lbl(label) {}
287  QVariant label() const {return lbl;}
288  void setLabel(const QVariant &label) {lbl = label;}
291  return *this;
292  }
295  return *this;
296  }
297  Alternative &operator<<(const QList<DynGenPar::Node> &other) {
299  return *this;
300  }
303  return *this;
304  }
306  void add(const DynGenPar::Node &value) {
307  append(value);
308  }
311  return (QList<DynGenPar::Node> &) *this;
312  }
313 
314  private:
315  QVariant lbl;
316 };
317 DYNGENPAR_DECLARE_TYPEINFO(Alternative, Q_MOVABLE_TYPE);
318 
320 struct Node {
321  Node() {}
322  Node(CatArg c) : cat(c) {children.append(Alternative());}
323  Node(CatArg c, const QVariant &d) : cat(c), data(d) {
324  children.append(Alternative());
325  }
327  QVariant data;
330  bool operator==(const Node &other) const {
331  return cat == other.cat && data == other.data && children == other.children;
332  }
333 };
334 DYNGENPAR_DECLARE_TYPEINFO(Node, Q_MOVABLE_TYPE);
335 
337 class PseudoCatScope;
339  public:
341 
346  QHash<Cat, QPair<QPair<Node, NextTokenConstraints>, int> > pConstraints;
348 
351  QHash<Cat, QPair<int, PseudoCatScope> > mcfgConstraints;
352 };
353 DYNGENPAR_DECLARE_TYPEINFO(PseudoCatScopeData, Q_MOVABLE_TYPE);
354 
356  public:
357  PseudoCatScope() : d() {}
358  QHash<Cat, QPair<QPair<Node, NextTokenConstraints>, int> > &pConstraints() {
359  ensureNonNull();
360  return d->pConstraints;
361  };
362  QHash<Cat, QPair<int, PseudoCatScope> > &mcfgConstraints() {
363  ensureNonNull();
364  return d->mcfgConstraints;
365  };
366  bool hasPConstraint(CatArg cat) const {
367  return d ? d->pConstraints.contains(cat) : false;
368  };
369  bool hasMcfgConstraint(CatArg cat) const {
370  return d ? d->mcfgConstraints.contains(cat) : false;
371  };
372  QPair<QPair<Node, NextTokenConstraints>, int> pConstraint(CatArg cat) const
373  {
374  return d ? d->pConstraints.value(cat)
375  : QPair<QPair<Node, NextTokenConstraints>, int>();
376  };
377  QPair<int, PseudoCatScope> mcfgConstraint(CatArg cat) const {
378  return d ? d->mcfgConstraints.value(cat) : QPair<int, PseudoCatScope>();
379  };
380  bool isNull() const { return !d.constData(); }
382  const PseudoCatScopeData *data() const { return d.constData(); }
383  bool operator==(const PseudoCatScope &other) const { return d == other.d; }
384  private:
385  QSharedDataPointer<PseudoCatScopeData> d;
386  void ensureNonNull() {
387  if (!d.constData()) d = new PseudoCatScopeData;
388  }
389 };
390 DYNGENPAR_DECLARE_TYPEINFO(PseudoCatScope, Q_MOVABLE_TYPE);
391 
392 inline uint qHash(const PseudoCatScope &scope) {
393  return qHash(scope.data());
394 }
395 
397 struct Match {
399  Match() : len(0), tree(), ruleno(0), scope(), nextTokenConstraints() {}
400  Match(int l, Node t, int n, PseudoCatScope s)
401  : len(l), tree(t), ruleno(n), scope(s), nextTokenConstraints() {}
402  Match(int l, Node t, int n, PseudoCatScope s, const NextTokenConstraints &nt)
403  : len(l), tree(t), ruleno(n), scope(s), nextTokenConstraints(nt) {}
404  int len;
406  int ruleno;
407 
410 };
411 DYNGENPAR_DECLARE_TYPEINFO(Match, Q_MOVABLE_TYPE);
412 
413 class Parser;
415 struct ActionInfo {
417  ActionInfo() : tree(), parser(0) {}
418  ActionInfo(const Node &t, Parser *p) : tree(t), parser(p) {}
421 };
422 DYNGENPAR_DECLARE_TYPEINFO(ActionInfo, Q_MOVABLE_TYPE);
423 
426  public:
427  virtual ~ActionDeserializer() {}
428  virtual Action *readAction(QDataStream &) = 0;
429 };
430 DYNGENPAR_DECLARE_TYPEINFO(ActionDeserializer, Q_MOVABLE_TYPE);
431 
433 class Action {
434  private:
435  static QHash<QString, ActionDeserializer *> deserializers;
436  protected:
437  static void registerDeserializer(const QString &name,
438  ActionDeserializer *deserializer) {
439  deserializers.insert(name, deserializer);
440  }
441  public:
442  virtual ~Action() {}
443  virtual void execute(const ActionInfo &info) = 0;
445 
447  virtual int lookaheadTokens() const { return 0; }
449  virtual void writeExternal(QDataStream &stream) const {
450  qWarning("action not serializable");
451  stream << QString();
452  }
454  static QDataStream &constructAndRead(QDataStream &stream, Action *&data) {
455  QString type;
456  stream >> type;
457  if (type.isEmpty()) {
458  data = 0;
459  return stream;
460  } else if (deserializers.contains(type)) {
461  data = deserializers.value(type)->readAction(stream);
462  return stream;
463  } else qFatal("action deserializer \"%s\" not found",
464  type.toLocal8Bit().data());
465  }
466 };
467 DYNGENPAR_DECLARE_TYPEINFO(Action, Q_MOVABLE_TYPE);
468 
469 
470 // --- data structures for DAG-structured parse stacks ---
471 
473 class StackItem;
474 class StackItemData : public QSharedData {
475  public:
476  StackItemData(int depth) : m_depth(depth) {}
477  virtual ~StackItemData() {}
478  virtual StackItemData *clone() = 0;
479  virtual int type() const = 0;
480  int depth() const {return m_depth;}
481  virtual void addParent(const StackItem &parent) = 0;
482  virtual void setParents(const QList<StackItem> &parents) = 0;
483  protected:
484  int m_depth;
485 };
486 DYNGENPAR_DECLARE_TYPEINFO(StackItemData, Q_MOVABLE_TYPE);
487 
488 class StackItem {
489  public:
490  StackItem() : d() {}
491  StackItem(const QList<StackItem> &parents, CatArg cat, CatArg effCat,
492  int pos, const PseudoCatScope &scope);
493  StackItem(const QList<StackItem> &parents, CatArg cat, CatArg effCat,
494  const PseudoCatScope &scope);
495  StackItem(const StackItem &parent, int dummy);
496  StackItem(const StackItem &parent, const Rule &rule, int len, int curr,
497  int i, const Node &tree, int ruleno,
498  const NextTokenConstraints &nextTokenConstraints);
499  StackItem(const StackItem &parent, CatArg target, int pos, int len);
501  StackItem(const StackItem &parent, CatArg cat,
502  const PseudoCatScope &scope);
503  StackItem(const StackItem &parent, const QList<Node> &leaves, int i,
504  const Node &tree, const PseudoCatScope &scope,
505  const NextTokenConstraints &nextTokenConstraints);
506  int type() const {return d ? d->type() : -1;}
507  int depth() const {return d ? d->depth() : -1;}
508  void addParent(const StackItem &parent) {d->addParent(parent);}
509  void setParents(const QList<StackItem> &parents) {d->setParents(parents);}
510  const StackItemData *data() const {return d.constData();}
511  bool operator<(const StackItem &other) const {
512  return depth() < other.depth();
513  }
514  private:
515  QSharedDataPointer<StackItemData> d;
516 };
517 DYNGENPAR_DECLARE_TYPEINFO(StackItem, Q_MOVABLE_TYPE);
518 
521  public:
522  StackItemType0(const QList<StackItem> &parents, CatArg cat, CatArg effCat,
523  int pos, const PseudoCatScope &scope)
524  : StackItemData(0), m_parents(parents), m_cat(cat), m_effCat(effCat),
525  m_pos(pos), m_scope(scope) {
526  foreach(const StackItem &parent, parents) {
527  int newDepth = parent.depth() + 1;
528  if (m_depth < newDepth) m_depth = newDepth;
529  }
530  }
531  virtual ~StackItemType0() {}
532  virtual StackItemData *clone() {return new StackItemType0(*this);}
533  virtual int type() const {return 0;}
534  virtual void addParent(const StackItem &parent) {
535  m_parents.append(parent);
536  int newDepth = parent.depth() + 1;
537  if (m_depth < newDepth) m_depth = newDepth;
538  }
539  virtual void setParents(const QList<StackItem> &parents) {
540  m_parents = parents;
541  m_depth = 0;
542  foreach(const StackItem &parent, parents) {
543  int newDepth = parent.depth() + 1;
544  if (m_depth < newDepth) m_depth = newDepth;
545  }
546  }
547  const QList<StackItem> &parents() const {return m_parents;}
548  Cat cat() const {return m_cat;}
549  Cat effCat() const {return m_effCat;}
550  int pos() const {return m_pos;}
551  PseudoCatScope scope() const {return m_scope;}
552  private:
553  QList<StackItem> m_parents;
554  Cat m_cat, m_effCat;
555  int m_pos;
556  PseudoCatScope m_scope;
557 };
558 DYNGENPAR_DECLARE_TYPEINFO(StackItemType0, Q_MOVABLE_TYPE);
559 
562  public:
563  StackItemType1(const QList<StackItem> &parents, CatArg cat, CatArg effCat,
564  const PseudoCatScope &scope) :
565  StackItemData(0), m_parents(parents), m_cat(cat), m_effCat(effCat),
566  m_scope(scope) {
567  foreach(const StackItem &parent, parents) {
568  int newDepth = parent.depth() + 1;
569  if (m_depth < newDepth) m_depth = newDepth;
570  }
571  }
572  virtual ~StackItemType1() {}
573  virtual StackItemData *clone() {return new StackItemType1(*this);}
574  virtual int type() const {return 1;}
575  virtual void addParent(const StackItem &) {
576  // this could be allowed, but is not needed anywhere, so detect misuse
577  qFatal("cannot call addParent on type 1 item");
578  }
579  virtual void setParents(const QList<StackItem> &) {
580  // this could be allowed, but is not needed anywhere, so detect misuse
581  qFatal("cannot call setParents on type 1 item");
582  }
583  const QList<StackItem> &parents() const {return m_parents;}
584  Cat cat() const {return m_cat;}
585  Cat effCat() const {return m_effCat;}
586  PseudoCatScope scope() const {return m_scope;}
587  private:
588  QList<StackItem> m_parents;
589  Cat m_cat, m_effCat;
590  PseudoCatScope m_scope;
591 };
592 DYNGENPAR_DECLARE_TYPEINFO(StackItemType1, Q_MOVABLE_TYPE);
593 
595 
597  public:
598  StackItemType2(const StackItem &parent) : StackItemData(parent.depth() + 1),
599  m_parent(parent) {}
600  virtual ~StackItemType2() {}
601  virtual StackItemData *clone() {return new StackItemType2(*this);}
602  virtual int type() const {return 2;}
603  virtual void addParent(const StackItem &) {
604  qFatal("cannot call addParent on type 2 item");
605  }
606  virtual void setParents(const QList<StackItem> &) {
607  qFatal("cannot call setParents on type 2 item");
608  }
609  const StackItem &parent() const {return m_parent;}
610  private:
611  StackItem m_parent;
612 };
613 DYNGENPAR_DECLARE_TYPEINFO(StackItemType2, Q_MOVABLE_TYPE);
614 
617  public:
618  StackItemType3(const StackItem &parent, const Rule &rule, int len, int curr,
619  int i, const Node &tree, int ruleno,
620  const NextTokenConstraints &nextTokenConstraints)
621  : StackItemData(parent.depth() + 1), m_parent(parent), m_rule(rule),
622  m_len(len), m_curr(curr), m_i(i), m_tree(tree), m_ruleno(ruleno),
623  m_nextTokenConstraints(nextTokenConstraints) {}
624  virtual ~StackItemType3() {}
625  virtual StackItemData *clone() {return new StackItemType3(*this);}
626  virtual int type() const {return 3;}
627  virtual void addParent(const StackItem &) {
628  qFatal("cannot call addParent on type 3 item");
629  }
630  virtual void setParents(const QList<StackItem> &) {
631  qFatal("cannot call setParents on type 3 item");
632  }
633  const StackItem &parent() const {return m_parent;}
634  Rule rule() const {return m_rule;}
635  int len() const {return m_len;}
636  int curr() const {return m_curr;}
637  int i() const {return m_i;}
638  Node tree() const {return m_tree;}
639  int ruleno() const {return m_ruleno;}
641  return m_nextTokenConstraints;
642  }
643  private:
644  StackItem m_parent;
645  Rule m_rule;
646  int m_len, m_curr, m_i;
647  Node m_tree;
648  int m_ruleno;
649  NextTokenConstraints m_nextTokenConstraints;
650 };
651 DYNGENPAR_DECLARE_TYPEINFO(StackItemType3, Q_MOVABLE_TYPE);
652 
654 
656  public:
657  StackItemType4(const StackItem &parent, CatArg target, int pos, int len)
658  : StackItemData(parent.depth() + 1), m_parent(parent), m_target(target),
659  m_pos(pos), m_len(len) {}
660  virtual ~StackItemType4() {}
661  virtual StackItemData *clone() {return new StackItemType4(*this);}
662  virtual int type() const {return 4;}
663  virtual void addParent(const StackItem &) {
664  qFatal("cannot call addParent on type 4 item");
665  }
666  virtual void setParents(const QList<StackItem> &) {
667  qFatal("cannot call setParents on type 4 item");
668  }
669  const StackItem &parent() const {return m_parent;}
670  Cat target() const {return m_target;}
671  int pos() const {return m_pos;}
672  int len() const {return m_len;}
673  private:
674  StackItem m_parent;
675  Cat m_target;
676  int m_pos, m_len;
677 };
678 DYNGENPAR_DECLARE_TYPEINFO(StackItemType4, Q_MOVABLE_TYPE);
679 
683  public:
684  StackItemType5(const StackItem &parent, CatArg cat,
685  const PseudoCatScope &scope)
686  : StackItemData(parent.depth() + 1), m_parent(parent), m_cat(cat),
687  m_scope(scope) {}
688  virtual ~StackItemType5() {}
689  virtual StackItemData *clone() {return new StackItemType5(*this);}
690  virtual int type() const {return 5;}
691  virtual void addParent(const StackItem &) {
692  qFatal("cannot call addParent on type 5 item");
693  }
694  virtual void setParents(const QList<StackItem> &) {
695  qFatal("cannot call setParents on type 5 item");
696  }
697  const StackItem &parent() const {return m_parent;}
698  Cat cat() const {return m_cat;}
699  PseudoCatScope scope() const {return m_scope;}
700  private:
701  StackItem m_parent;
702  Cat m_cat;
703  PseudoCatScope m_scope;
704 };
705 DYNGENPAR_DECLARE_TYPEINFO(StackItemType5, Q_MOVABLE_TYPE);
706 
709  public:
710  StackItemType6(const StackItem &parent, const QList<Node> &leaves, int i,
711  const Node &tree, const PseudoCatScope &scope,
712  const NextTokenConstraints &nextTokenConstraints)
713  : StackItemData(parent.depth() + 1), m_parent(parent), m_leaves(leaves),
714  m_i(i), m_tree(tree), m_scope(scope),
715  m_nextTokenConstraints(nextTokenConstraints) {}
716  virtual ~StackItemType6() {}
717  virtual StackItemData *clone() {return new StackItemType6(*this);}
718  virtual int type() const {return 6;}
719  virtual void addParent(const StackItem &) {
720  qFatal("cannot call addParent on type 6 item");
721  }
722  virtual void setParents(const QList<StackItem> &) {
723  qFatal("cannot call setParents on type 6 item");
724  }
725  const StackItem &parent() const {return m_parent;}
726  QList<Node> leaves() const {return m_leaves;}
727  int i() const {return m_i;}
728  Node tree() const {return m_tree;}
729  PseudoCatScope scope() const {return m_scope;}
731  return m_nextTokenConstraints;
732  }
733  private:
734  StackItem m_parent;
735  QList<Node> m_leaves;
736  int m_i;
737  Node m_tree;
738  PseudoCatScope m_scope;
739  NextTokenConstraints m_nextTokenConstraints;
740 };
741 DYNGENPAR_DECLARE_TYPEINFO(StackItemType6, Q_MOVABLE_TYPE);
742 
743 inline StackItem::StackItem(const QList<StackItem> &parents, CatArg cat,
744  CatArg effCat, int pos,
745  const PseudoCatScope &scope)
746 {
747  d = new StackItemType0(parents, cat, effCat, pos, scope);
748 }
749 
750 inline StackItem::StackItem(const QList<StackItem> &parents, CatArg cat,
751  CatArg effCat, const PseudoCatScope &scope)
752 {
753  d = new StackItemType1(parents, cat, effCat, scope);
754 }
755 
756 inline StackItem::StackItem(const StackItem &parent, int)
757 {
758  d = new StackItemType2(parent);
759 }
760 
761 inline StackItem::StackItem(const StackItem &parent, const Rule &rule, int len,
762  int curr, int i, const Node &tree, int ruleno,
763  const NextTokenConstraints &nextTokenConstraints)
764 {
765  d = new StackItemType3(parent, rule, len, curr, i, tree, ruleno,
766  nextTokenConstraints);
767 }
768 
769 inline StackItem::StackItem(const StackItem &parent, CatArg target, int pos,
770  int len)
771 {
772  d = new StackItemType4(parent, target, pos, len);
773 }
774 
775 inline StackItem::StackItem(const StackItem &parent, CatArg cat,
776  const PseudoCatScope &scope)
777 {
778  d = new StackItemType5(parent, cat, scope);
779 }
780 
781 inline StackItem::StackItem(const StackItem &parent, const QList<Node> &leaves,
782  int i, const Node &tree,
783  const PseudoCatScope &scope,
784  const NextTokenConstraints &nextTokenConstraints)
785 {
786  d = new StackItemType6(parent, leaves, i, tree, scope, nextTokenConstraints);
787 }
788 
789 
790 // --- token source abstraction ---
791 
794  public:
796  virtual AbstractLexerStateData *clone() = 0;
797 };
798 DYNGENPAR_DECLARE_TYPEINFO(AbstractLexerStateData, Q_MOVABLE_TYPE);
799 
800 class LexerState {
801  public:
802  LexerState() : d() {}
803  LexerState(AbstractLexerStateData *data) : d(data) {}
804  void clear() { d = 0; }
805  bool isNull() const { return !d.constData(); }
806  const AbstractLexerStateData *data() const { return d.constData(); }
807  bool operator==(const LexerState &other) const { return d == other.d; }
808  private:
809  QSharedDataPointer<AbstractLexerStateData> d;
810 };
811 DYNGENPAR_DECLARE_TYPEINFO(LexerState, Q_MOVABLE_TYPE);
812 
813 class TokenSource {
814  public:
815  TokenSource() : currPos(0) {}
816  virtual ~TokenSource() {}
819 
823  tree = Node();
824  Cat result = readToken();
825  if (!IS_EPSILON(result)) {
826  // If the implementation of readToken didn't create a parse tree, create
827  // the default one: a leaf node.
828  if (tree.children.isEmpty()) tree = Node(result);
829  currPos++;
830  }
831  return result;
832  }
835  return tree;
836  }
838 
845  virtual bool matchParseTree(const Node &treeToMatch) {
846  return treeToMatch.cat == tree.cat;
847  }
849  int currentPosition() {return currPos;}
851 
862  virtual bool rewindTo(int pos, const LexerState & = LexerState()) {
863  tree = Node();
864  return (pos == currPos);
865  }
868 
874  bool rewindTo(int pos, const Node &parseTree,
875  const LexerState &lexerState = LexerState()) {
876  bool ret = rewindTo(pos, lexerState);
877  tree = parseTree;
878  return ret;
879  }
881  virtual LexerState saveState() {return LexerState();}
882  protected:
884  virtual Cat readToken() = 0;
886 
887  bool simpleRewind(int pos, bool rewindOnly = false) {
888  tree = Node(); // destroy saved parse tree
889  if (rewindOnly && pos > currPos) // cannot rewind forward
890  return false;
891  currPos = pos;
892  return true;
893  }
894  int currPos;
896 
903 };
904 DYNGENPAR_DECLARE_TYPEINFO(TokenSource, Q_MOVABLE_TYPE);
905 
906 class ListTokenSource : public TokenSource {
907  public:
909  virtual ~ListTokenSource() {}
912  virtual bool rewindTo(int pos, const LexerState & = LexerState()) {
913  return simpleRewind(pos);
914  }
915  protected:
917  virtual Cat readToken() {
918  if (currPos < inputTokens.size())
919  return inputTokens.at(currPos);
920  return Cat();
921  }
922 };
923 DYNGENPAR_DECLARE_TYPEINFO(ListTokenSource, Q_MOVABLE_TYPE);
924 
926 
929 struct TextPosition {
930  TextPosition() : line(0), col(0) {}
931  TextPosition(int l, int c) : line(l), col(c) {}
932 
933  void reset() { line = col = 0; }
934 
936  void countCharacter(unsigned char c) {
937  // ignore CR
938  if (c == '\r') return;
939 
940  if (c == '\n') { // LF
941  line++;
942  col = 0;
943  } else col++; // horizontal character
944  }
945 
946  int line;
947  int col;
948 };
949 DYNGENPAR_DECLARE_TYPEINFO(TextPosition, Q_PRIMITIVE_TYPE);
950 
951 
952 // --- data structures for PMCFGs (in standard representation) ---
953 
955 struct Term {
957  Term() : arg(-1), component(0), token() {}
958  Term(int a, int c) : arg(a), component(c), token() {}
959  Term(CatArg t) : arg(-1), component(0), token(t) {}
960  int arg, component;
965  bool isComponent() const {return arg >= 0;}
966  bool isToken() const {return arg < 0;}
968  bool operator==(const Term &other) const {
969  return arg == other.arg && component == other.component
970  && token == other.token;
971  }
972 };
973 DYNGENPAR_DECLARE_TYPEINFO(Term, Q_MOVABLE_TYPE);
974 
976 class Sequence : public QList<Term> {
977  public:
979 
980  Sequence() : QList<Term>(), nextTokenConstraints() {}
981  explicit Sequence(const NextTokenConstraints &ntc)
982  : QList<Term>(), nextTokenConstraints(ntc) {}
983  explicit Sequence(const QList<Term> &list)
984  : QList<Term>(list), nextTokenConstraints() {}
985  Sequence(const QList<Term> &list, const NextTokenConstraints &ntc)
986  : QList<Term>(list), nextTokenConstraints(ntc) {}
987  Sequence &operator+=(const QList<Term> &other) {
989  return *this;
990  }
991  Sequence &operator+=(const Term &value) {
993  return *this;
994  }
995  Sequence &operator<<(const QList<Term> &other) {
997  return *this;
998  }
999  Sequence &operator<<(const Term &value) {
1000  QList<Term>::operator<<(value);
1001  return *this;
1002  }
1004  void add(const Term &value) {
1005  append(value);
1006  }
1009  return (QList<Term> &) *this;
1010  }
1011 };
1012 DYNGENPAR_DECLARE_TYPEINFO(Sequence, Q_MOVABLE_TYPE);
1013 
1015 class Function: public QList<Sequence> {
1016  public:
1018  explicit Function(const QList<Sequence> &list) : QList<Sequence>(list) {}
1021  return *this;
1022  }
1023  Function &operator+=(const Sequence &value) {
1025  return *this;
1026  }
1027  Function &operator<<(const QList<Sequence> &other) {
1029  return *this;
1030  }
1031  Function &operator<<(const Sequence &value) {
1033  return *this;
1034  }
1036  void add(const Sequence &value) {
1037  append(value);
1038  }
1041  return (QList<Sequence> &) *this;
1042  }
1043 };
1044 DYNGENPAR_DECLARE_TYPEINFO(Function, Q_MOVABLE_TYPE);
1045 
1047 struct Pmcfg {
1049 
1050 
1056 
1073  RuleSet rules;
1075 
1076  TokenSet tokens;
1078 
1081 
1088  RuleSet cfRules;
1090 
1092 
1093  QHash<int, QString> functionNames;
1094  QHash<QString, int> functionIndices;
1095  void addFunction(const QString &name, const Function &function) {
1096  int index = functions.size();
1097  functions.append(function);
1098  functionNames.insert(index, name);
1099  functionIndices.insert(name, index);
1100  }
1101  Function lookupFunction(const QVariant &id) const {
1102  if (id.type() == QVariant::Int) return functions.at(id.toInt());
1103 
1104  QString name = id.toString();
1105  if (!functionIndices.contains(name)) return Function();
1106  return functions.at(functionIndices.value(name));
1107  }
1109 };
1110 DYNGENPAR_DECLARE_TYPEINFO(Pmcfg, Q_MOVABLE_TYPE);
1111 
1116  : pmcfgRule(rule), argPositions(rule.size()) {}
1118  QVector<QVector<int> > argPositions;
1122 };
1123 DYNGENPAR_DECLARE_TYPEINFO(PmcfgComponentInfo, Q_MOVABLE_TYPE);
1124 
1125 Node parseTreeToPmcfgSyntaxTree(const Node &parseTree);
1126 
1127 
1128 // --- parse state struct, for bindings ---
1129 
1131 struct ParseState {
1133  : errorPos(-1), errorToken(), incrementalPos(-1), incrementalStacks(),
1134  incrementalMatches(), lexerState() {}
1135  // explicitly implement the default copy constructor to get it bound
1136  ParseState(const ParseState &other)
1137  : errorPos(other.errorPos), errorToken(other.errorToken),
1138  incrementalPos(other.incrementalPos),
1139  incrementalStacks(other.incrementalStacks),
1140  incrementalMatches(other.incrementalMatches), lexerState(other.lexerState)
1141  {}
1142 
1149 
1150  void reset() { *this = ParseState(); }
1151 };
1152 DYNGENPAR_DECLARE_TYPEINFO(ParseState, Q_MOVABLE_TYPE);
1153 
1154 
1155 // --- main class ---
1156 
1158 class Parser {
1159  public:
1160  // interface methods
1161  Parser(TokenSource *tokenSource)
1162  : inputSource(tokenSource), lastGeneratedCat(0) {}
1163  virtual ~Parser() {}
1164  bool isToken(CatArg cat) const {return tokens.contains(cat);}
1165  void addToken(CatArg cat) {tokens.insert(cat);}
1166  bool isLiteral(const QList<Cat> &list) const;
1167  void initCaches();
1168  void addRule(CatArg cat, const Rule &rule);
1169  void loadCfg(const Cfg &cfg) {
1170  rules = cfg.rules;
1171  tokens = cfg.tokens;
1172  startCat = cfg.startCat;
1173  initCaches();
1174  }
1176  Cfg getCfg() {return Cfg(rules, tokens, startCat);}
1177  bool loadPmcfg(const Pmcfg &pmcfg);
1178  bool addPmcfgRule(Pmcfg &pmcfg, CatArg cat, const Rule &rule);
1179  QList<Match> parse(int *errorPos = 0, Cat *errorToken = 0,
1180  int *incrementalPos = 0,
1181  QList<StackItem> *incrementalStacks = 0,
1182  QList<Match> *incrementalMatches = 0,
1183  LexerState *lexerState = 0);
1186  return parse(&parseState->errorPos, &parseState->errorToken,
1187  &parseState->incrementalPos, &parseState->incrementalStacks,
1188  &parseState->incrementalMatches, &parseState->lexerState);
1189  }
1192 
1196  void saveState(ParseState *parseState) {
1197  if (nextStacks.isEmpty() && currentMatches.isEmpty() && errPos < 0) {
1198  parseState->reset(); // no parse operation running
1199  } else {
1200  parseState->errorPos = errPos;
1201  parseState->errorToken = errToken;
1202  parseState->incrementalPos = inputSource->currentPosition();
1203  parseState->incrementalStacks = nextStacks;
1204  parseState->incrementalMatches = currentMatches;
1205  parseState->lexerState = inputSource->saveState();
1206  }
1207  }
1208  Predictions computePredictions(const QList<StackItem> &stacks) const;
1210  Predictions computePredictions(const ParseState &parseState) const {
1211  return computePredictions(parseState.incrementalStacks);
1212  }
1213  QHash<Cat, QSet<Cat> > expandNonterminalPrediction(CatArg cat) const;
1214  QHash<Cat, QSet<Cat> > expandNonterminalPredictionC(CatArg cat);
1215  MultiPredictions computeMultiPredictions(const QList<StackItem> &stacks)
1216  const;
1218  MultiPredictions computeMultiPredictions(const ParseState &parseState) const
1219  {
1220  return computeMultiPredictions(parseState.incrementalStacks);
1221  }
1222  QHash<Cat, QSet<QList<Cat> > >
1223  expandNonterminalPredictionMulti(CatArg cat) const;
1224  QHash<Cat, QSet<QList<Cat> > >
1225  expandNonterminalPredictionMultiC(CatArg cat);
1226  ConstrainedPredictions computeConstrainedPredictions(
1227  const QList<StackItem> &stacks) const;
1229  ConstrainedPredictions computeConstrainedPredictions(
1230  const ParseState &parseState) const {
1231  return computeConstrainedPredictions(parseState.incrementalStacks);
1232  }
1233  QHash<Cat, QSet<Cat> > expandNonterminalPredictionC(CatArg cat,
1234  const NextTokenConstraints &nextTokenConstraints);
1235  QHash<Cat, QSet<Cat> > expandNonterminalPredictionC(CatArg cat,
1236  const QList<NextTokenConstraints> &nextTokenConstraintsList);
1237  ConstrainedMultiPredictions computeConstrainedMultiPredictions(
1238  const QList<StackItem> &stacks) const;
1241  const ParseState &parseState) const
1242  {
1243  return computeConstrainedMultiPredictions(parseState.incrementalStacks);
1244  }
1245  QHash<Cat, QSet<QList<Cat> > >
1246  expandNonterminalPredictionMultiC(CatArg cat,
1247  const NextTokenConstraints &nextTokenConstraints);
1248  QHash<Cat, QSet<QList<Cat> > >
1249  expandNonterminalPredictionMultiC(CatArg cat,
1250  const QList<NextTokenConstraints> &nextTokenConstraintsList);
1251 
1253 
1254 
1258  RuleSet rules;
1260  TokenSet tokens;
1264 
1266 
1267 
1288  QHash<Cat, QPair<Cat, QList<Cat> > > pseudoCats;
1291 
1294  QHash<Cat, QPair<Cat, int> > componentCats;
1296 
1300  QHash<Cat, QList<Cat> > catComponents;
1302 
1303  protected:
1306 
1307  private:
1308  // helper methods
1309  Cat effectiveCat(CatArg cat) const;
1310  void processRule(CatArg cat, const Rule &rule, int skip, int ruleno,
1311  QQueue<Cat> &nullableQueue, bool &clearEpsilonMatches);
1312  bool computePmcfgDimension(CatArg cat, const Rule &rule,
1313  const Pmcfg &pmcfg);
1314  bool convertPmcfgRule(CatArg cat, const Rule &rule, const Pmcfg &pmcfg,
1315  bool updateCaches);
1316  bool reachable(CatArg cat, CatArg target, QSet<Cat> mark);
1317  QList<FullRule> neighborhood(CatArg cat, CatArg target);
1318  void finalizeMatches(QList<Match> &matches, CatArg cat,
1319  const PseudoCatScope &scope);
1320  void copyScope(QList<Match> &matches, const PseudoCatScope &scope);
1321  QList<Match> matchCFToEpsilon(CatArg cat, QSet<Cat> mark);
1322  QList<Match> matchEffectiveCatToEpsilon(CatArg cat, QSet<Cat> mark);
1323  QList<Match> matchToEpsilonRecurse(CatArg cat, QSet<Cat> mark,
1324  const PseudoCatScope &scope);
1325  QList<Match> matchToEpsilon(CatArg cat, const PseudoCatScope &scope);
1326  bool matchesTokenRecurse(CatArg cat, CatArg token, QSet<Cat> mark) const;
1327  bool matchesToken(CatArg cat, CatArg token) const;
1328  void collectLeaves(const Node &tree, QList<Node> &leaves);
1329  bool validateNextTokenConstraints(CatArg token,
1330  const NextTokenConstraints &nextTokenConstraints) const;
1331  QList<Match> match(CatArg cat, int pos, const PseudoCatScope &scope,
1332  const StackItem &stack,
1333  const NextTokenConstraints &nextTokenConstraints);
1334  bool verifyLookaheadRule(const Rule &rule, int i, int &curr,
1335  int &remaining, QSet<Cat> &mark);
1336  bool verifyLookahead(const StackItem &stack, CatArg cat, int pos,
1337  int nTokens);
1338  QList<Match> matchRemaining(const Rule &rule, int len, int curr, int i,
1339  const Node &tree, const PseudoCatScope &scope,
1340  int ruleno, const StackItem &stack,
1341  const NextTokenConstraints
1342  &nextTokenConstraints);
1343  Cat findFirstToken(const Node &tree);
1344  void unify(QList<Match> &matches);
1345  QList<Match> reduce(CatArg cat, CatArg target, int pos, int len,
1346  const Node &tree, const StackItem &stack,
1347  const PseudoCatScope &scope, int ruleno,
1348  const NextTokenConstraints &nextTokenConstraints,
1349  QSet<Cat> mark = QSet<Cat>());
1350  QList<Match> processStackItem(const StackItem &item,
1351  const QList<Match> &matches);
1352  QList<Match> processStack(const StackItem &stack, CatArg token);
1353  bool shift(int pos);
1354  void expandNonterminalPredictionRecurse(CatArg cat,
1355  QHash<Cat, QSet<Cat> > &result,
1356  QSet<Cat> &mark) const;
1357  void expandNonterminalPredictionRecurseC(CatArg cat,
1358  QHash<Cat, QSet<Cat> > &result,
1359  QSet<Cat> mark, int ruleno,
1360  const PseudoCatScope &scope,
1361  const NextTokenConstraints
1362  &nextTokenConstraints);
1363  void expandNonterminalPredictionMultiRecurse(CatArg cat,
1364  QHash<Cat, QSet<QList<Cat> > > &result, QSet<Cat> &mark) const;
1365  void expandNonterminalPredictionMultiRecurseC(CatArg cat,
1366  QHash<Cat, QSet<QList<Cat> > > &result, QSet<Cat> mark, int ruleno,
1367  const PseudoCatScope &scope,
1368  const NextTokenConstraints &nextTokenConstraints);
1369  int generateCat() { return --lastGeneratedCat; }
1370 
1372  QMultiHash<Cat, FullRule> initialGraph;
1374  QHash<QPair<Cat, Cat>, QList<FullRule> > neighborhoods;
1376  QSet<Cat> nullable;
1378  QHash<Cat, QList<Match> > epsilonMatches;
1379 
1381  QList<StackItem> nextStacks;
1383  QList<Match> currentMatches;
1385  LexerState currentLexerState;
1387  QHash<Cat, int> type0Indices;
1389 
1396  QHash<const StackItemData *, QPair<bool, QList<Match> > > collectedMatches;
1398  Private::PriorityQueue<StackItem> priorityQueue;
1400 
1401  bool branched;
1403  int errPos;
1405  Cat errToken;
1407  int lastGeneratedCat;
1408 };
1409 DYNGENPAR_DECLARE_TYPEINFO(Parser, Q_MOVABLE_TYPE);
1410 
1411 } // end namespace
1412 
1413 
1414 // --- utility functions in the global namespace ---
1415 
1416 Q_DECLARE_METATYPE(DynGenPar::PmcfgComponentInfo)
1417 
1418 uint qHash(const QList<DynGenPar::Cat> &list);
1419 
1420 template<>
1422  *QSharedDataPointer<DynGenPar::StackItemData>::clone()
1423 {
1424  return d->clone();
1425 }
1426 
1427 template<>
1429  *QSharedDataPointer<DynGenPar::AbstractLexerStateData>::clone()
1430 {
1431  return d->clone();
1432 }
1433 
1434 inline QDataStream &operator<<(QDataStream &stream,
1435  const DynGenPar::NextTokenConstraints &data) {
1436  return data.writeExternal(stream);
1437 }
1438 
1439 inline QDataStream &operator>>(QDataStream &stream,
1441  return data.readExternal(stream);
1442 }
1443 
1444 inline QDataStream &operator<<(QDataStream &stream,
1445  const DynGenPar::Rule &data) {
1446  return data.writeExternal(stream, DynGenPar::Rule::serializeLabels,
1448 }
1449 
1450 inline QDataStream &operator>>(QDataStream &stream, DynGenPar::Rule &data) {
1451  return data.readExternal(stream);
1452 }
1453 
1454 inline QDataStream &operator<<(QDataStream &stream,
1455  const DynGenPar::Cfg &data) {
1456  return data.writeExternal(stream);
1457 }
1458 
1459 inline QDataStream &operator>>(QDataStream &stream, DynGenPar::Cfg &data) {
1460  return data.readExternal(stream);
1461 }
1462 
1463 inline QDataStream &operator<<(QDataStream &stream,
1464  const DynGenPar::Action *data) {
1465  if (data) {
1466  data->writeExternal(stream);
1467  return stream;
1468  } else return stream << QString();
1469 }
1470 
1471 inline QDataStream &operator>>(QDataStream &stream, DynGenPar::Action *&data) {
1472  return DynGenPar::Action::constructAndRead(stream, data);
1473 }
1474 
1475 #endif // DYNGENPAR_H
const StackItem & parent() const
Definition: dyngenpar.h:725
ParseState(const ParseState &other)
Definition: dyngenpar.h:1136
const AbstractLexerStateData * data() const
Definition: dyngenpar.h:806
MultiPredictions computeMultiPredictions(const ParseState &parseState) const
overloaded version using ParseState, for bindings
Definition: dyngenpar.h:1218
virtual StackItemData * clone()
Definition: dyngenpar.h:717
PseudoCatScope scope() const
Definition: dyngenpar.h:729
virtual void writeExternal(QDataStream &stream) const
implementation of the QDataStream operator<<
Definition: dyngenpar.h:449
QList< Cat > fullLiteral
the entire literal completed by the prediction
Definition: dyngenpar.h:222
bool operator==(const Term &other) const
needed for QList
Definition: dyngenpar.h:968
void add(const DynGenPar::Node &value)
Java-style + the binding generator doesn&#39;t detect the inherited append.
Definition: dyngenpar.h:306
ConstrainedMultiPrediction(const QList< Cat > &fullLit, CatArg c)
Definition: dyngenpar.h:240
ConstrainedMultiPrediction(const QList< Cat > &fullLit, CatArg c, NextTokenConstraints ntc)
Definition: dyngenpar.h:242
Term()
dummy default constructor for bindings
Definition: dyngenpar.h:957
QList< Term > & toList()
for bindings
Definition: dyngenpar.h:1008
QDataStream & operator>>(QDataStream &stream, DynGenPar::Action *&data)
Definition: dyngenpar.h:1471
Function(const QList< Sequence > &list)
Definition: dyngenpar.h:1018
QHash< Cat, QPair< Cat, int > > componentCats
maps categories which represent components of a multi-component category to the category and componen...
Definition: dyngenpar.h:1294
Sequence(const QList< Term > &list)
Definition: dyngenpar.h:983
const StackItem & parent() const
Definition: dyngenpar.h:669
static QDataStream & constructAndRead(QDataStream &stream, Action *&data)
implementation of the QDataStream operator>>
Definition: dyngenpar.h:454
QHash< Cat, QList< Rule > > RuleSet
Definition: dyngenpar.h:186
PseudoCatScope scope() const
Definition: dyngenpar.h:551
type 6 item: during match, we&#39;re matching a P constraint
Definition: dyngenpar.h:708
virtual LexerState saveState()
saves the current lexer state, by default a null LexerState
Definition: dyngenpar.h:881
QDataStream & writeExternal(QDataStream &stream, bool writeLabel=true, bool writeAction=true) const
implementation of the QDataStream operator<<
Definition: dyngenpar.h:167
static void registerDeserializer(const QString &name, ActionDeserializer *deserializer)
Definition: dyngenpar.h:437
QPair< QPair< Node, NextTokenConstraints >, int > pConstraint(CatArg cat) const
Definition: dyngenpar.h:372
virtual int type() const
Definition: dyngenpar.h:626
Node(CatArg c)
Definition: dyngenpar.h:322
Sequence(const QList< Term > &list, const NextTokenConstraints &ntc)
Definition: dyngenpar.h:985
Match(int l, Node t, int n, PseudoCatScope s, const NextTokenConstraints &nt)
Definition: dyngenpar.h:402
QHash< Cat, QPair< int, PseudoCatScope > > mcfgConstraints
hash table recording MCFG constraints
Definition: dyngenpar.h:351
virtual Cat readToken()
just fetch the next token from the list
Definition: dyngenpar.h:917
void addParent(const StackItem &parent)
Definition: dyngenpar.h:508
virtual StackItemData * clone()
Definition: dyngenpar.h:532
An object representing a CFG (or a PMCFG in our internal representation)
Definition: dyngenpar.h:193
const QList< StackItem > & parents() const
Definition: dyngenpar.h:583
node in the parse tree
Definition: dyngenpar.h:320
QList< Cat > fullLiteral
the entire literal completed by the prediction
Definition: dyngenpar.h:245
Sequence(const NextTokenConstraints &ntc)
Definition: dyngenpar.h:981
data passed to parser actions
Definition: dyngenpar.h:415
bool operator==(const ConstrainedMultiPrediction &other) const
needed for QList, QMultiHash
Definition: dyngenpar.h:250
Alternative & operator+=(const DynGenPar::Node &value)
Definition: dyngenpar.h:293
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:663
TokenSet tokens
tokens
Definition: dyngenpar.h:1260
TokenSet tokens
Definition: dyngenpar.h:199
bool operator==(const Node &other) const
needed for QList
Definition: dyngenpar.h:330
void add(const Term &value)
Java-style (for consistency, even though append is detected here)
Definition: dyngenpar.h:1004
LexerState(AbstractLexerStateData *data)
Definition: dyngenpar.h:803
uint qHash(const NextTokenConstraints &nextTokenConstraints)
simple hash function for next token constraints
Definition: dyngenpar.cpp:452
bool hasPConstraint(CatArg cat) const
Definition: dyngenpar.h:366
virtual int type() const
Definition: dyngenpar.h:662
virtual int lookaheadTokens() const
the number of tokens to look ahead before deciding to execute the action
Definition: dyngenpar.h:447
interface for parser action deserializers
Definition: dyngenpar.h:425
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:579
NextTokenConstraints nextTokenConstraints
Definition: dyngenpar.h:409
virtual int type() const
Definition: dyngenpar.h:533
QList< Cat > expect
list of context-free categories the next token MUST match
Definition: dyngenpar.h:95
QString Cat
Category type: string or integer depending on DYNGENPAR_INTEGER_CATEGORIES.
Definition: dyngenpar.h:71
QHash< Cat, QPair< QPair< Node, NextTokenConstraints >, int > > & pConstraints()
Definition: dyngenpar.h:358
NextTokenConstraints nextTokenConstraints() const
Definition: dyngenpar.h:730
type 0 item: during match, we&#39;re waiting for a token to shift
Definition: dyngenpar.h:520
NextTokenConstraints nextTokenConstraints
only for nonterminals
Definition: dyngenpar.h:247
term in the expression of a component of a PMCFG function
Definition: dyngenpar.h:955
PseudoCatScope scope
Definition: dyngenpar.h:408
component of a PMCFG function, a sequence of terms
Definition: dyngenpar.h:976
const QList< StackItem > & parents() const
Definition: dyngenpar.h:547
virtual void addParent(const StackItem &parent)
Definition: dyngenpar.h:534
(possibly partial) match
Definition: dyngenpar.h:397
virtual int type() const
Definition: dyngenpar.h:574
void setLabel(const QVariant &label)
Definition: dyngenpar.h:141
StackItemType1(const QList< StackItem > &parents, CatArg cat, CatArg effCat, const PseudoCatScope &scope)
Definition: dyngenpar.h:563
QList< Cat > inputTokens
Definition: dyngenpar.h:910
#define IS_EPSILON(cat)
Definition: dyngenpar.h:72
QHash< int, QString > functionNames
Definition: dyngenpar.h:1093
bool simpleRewind(int pos, bool rewindOnly=false)
basic implementation of rewindTo for subclasses which support it
Definition: dyngenpar.h:887
Cfg()
dummy default constructor for bindings
Definition: dyngenpar.h:195
text position
Definition: dyngenpar.h:929
RuleSet cfRules
optional context-free rules
Definition: dyngenpar.h:1088
Match(int l, Node t, int n, PseudoCatScope s)
Definition: dyngenpar.h:400
QDataStream & operator<<(QDataStream &stream, const DynGenPar::Action *data)
Definition: dyngenpar.h:1463
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:719
Sequence & operator<<(const Term &value)
Definition: dyngenpar.h:999
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:575
Node parseTree()
get the parse tree for the last shifted token
Definition: dyngenpar.h:834
StackItemType5(const StackItem &parent, CatArg cat, const PseudoCatScope &scope)
Definition: dyngenpar.h:684
QList< DynGenPar::Node > & toList()
for bindings
Definition: dyngenpar.h:310
QHash< Cat, QPair< int, PseudoCatScope > > & mcfgConstraints()
Definition: dyngenpar.h:362
QList< Cat > & toList()
for bindings
Definition: dyngenpar.h:165
multi-token predictions
Definition: dyngenpar.h:217
const StackItem & parent() const
Definition: dyngenpar.h:697
TokenSet tokens
set of true tokens
Definition: dyngenpar.h:1076
void countCharacter(unsigned char c)
convenience method to count a character
Definition: dyngenpar.h:936
Alternative(const QList< DynGenPar::Node > &list)
Definition: dyngenpar.h:283
RuleSet rules
Definition: dyngenpar.h:198
MultiPrediction()
dummy default constructor for bindings
Definition: dyngenpar.h:219
QVariant label() const
Definition: dyngenpar.h:140
QHash< Cat, QPair< QPair< Node, NextTokenConstraints >, int > > pConstraints
hash table recording parallel constraints
Definition: dyngenpar.h:346
virtual ~Action()
Definition: dyngenpar.h:442
ConstrainedPredictions computeConstrainedPredictions(const ParseState &parseState) const
overloaded version using ParseState, for bindings
Definition: dyngenpar.h:1229
Rule & operator<<(const Cat &value)
Definition: dyngenpar.h:156
QHash< Cat, QList< Cat > > catComponents
maps multi-component categories to the list of their components
Definition: dyngenpar.h:1300
static bool serializeActions
whether the operator<<(QDataStream &, const Rule &) should serialize actions
Definition: dyngenpar.h:132
Predictions computePredictions(const ParseState &parseState) const
overloaded version using ParseState, for bindings
Definition: dyngenpar.h:1210
Function lookupFunction(const QVariant &id) const
Definition: dyngenpar.h:1101
Sequence & operator+=(const QList< Term > &other)
Definition: dyngenpar.h:987
virtual StackItemData * clone()=0
StackItemType6(const StackItem &parent, const QList< Node > &leaves, int i, const Node &tree, const PseudoCatScope &scope, const NextTokenConstraints &nextTokenConstraints)
Definition: dyngenpar.h:710
Cat startCat
start category
Definition: dyngenpar.h:1079
Rule & operator+=(const QList< Cat > &other)
Definition: dyngenpar.h:144
type 3 item: during matchRemaining, we&#39;re executing a match
Definition: dyngenpar.h:616
virtual int type() const
Definition: dyngenpar.h:718
attached to the parse trees as rule labels to allow obtaining syntax trees
Definition: dyngenpar.h:1113
bool isToken(CatArg cat) const
Definition: dyngenpar.h:1164
void saveState(ParseState *parseState)
saves the current parser state, only meaningful during a parse operation
Definition: dyngenpar.h:1196
void addToken(CatArg cat)
Definition: dyngenpar.h:202
type 1 item: during type 0 item processing, we&#39;re executing a reduce
Definition: dyngenpar.h:561
virtual StackItemData * clone()
Definition: dyngenpar.h:625
virtual void setParents(const QList< StackItem > &parents)
Definition: dyngenpar.h:539
QDataStream & readExternal(QDataStream &stream)
implementation of the QDataStream operator>>
Definition: dyngenpar.h:208
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:722
ConstrainedMultiPredictions computeConstrainedMultiPredictions(const ParseState &parseState) const
overloaded version using ParseState, for bindings
Definition: dyngenpar.h:1240
bool hasMcfgConstraint(CatArg cat) const
Definition: dyngenpar.h:369
QList< Cat > taboo
list of context-free categories the next token MUST NOT match
Definition: dyngenpar.h:103
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:630
Cfg(const RuleSet &r, const TokenSet &t, CatArg sc)
Definition: dyngenpar.h:196
virtual bool rewindTo(int pos, const LexerState &=LexerState())
rewind to an older position (requires buffering)
Definition: dyngenpar.h:862
PseudoCatScope scope() const
Definition: dyngenpar.h:586
TokenSource * inputSource
input source
Definition: dyngenpar.h:1305
QList< Match > incrementalMatches
Definition: dyngenpar.h:1147
virtual ~TokenSource()
Definition: dyngenpar.h:816
Action * action
Definition: dyngenpar.h:143
virtual AbstractLexerStateData * clone()=0
Rule & operator+=(const Cat &value)
Definition: dyngenpar.h:148
FullRule(CatArg c, const Rule &r, int epsSkipped, int n)
Definition: dyngenpar.h:264
Function & operator+=(const QList< Sequence > &other)
Definition: dyngenpar.h:1019
bool operator==(const LexerState &other) const
Definition: dyngenpar.h:807
QSet< Cat > Predictions
Definition: dyngenpar.h:214
StackItemType4(const StackItem &parent, CatArg target, int pos, int len)
Definition: dyngenpar.h:657
API for stateful lexers to save their state for rewinding.
Definition: dyngenpar.h:793
FullRule()
dummy default constructor for bindings
Definition: dyngenpar.h:263
QDataStream & writeExternal(QDataStream &stream) const
implementation of the QDataStream operator<<
Definition: dyngenpar.h:109
Match()
dummy default constructor for bindings
Definition: dyngenpar.h:399
Function & operator<<(const Sequence &value)
Definition: dyngenpar.h:1031
bool operator==(const PseudoCatScope &other) const
Definition: dyngenpar.h:383
Sequence & operator+=(const Term &value)
Definition: dyngenpar.h:991
Node(CatArg c, const QVariant &d)
Definition: dyngenpar.h:323
Rule(const QList< Cat > &list)
Definition: dyngenpar.h:136
ConstrainedMultiPrediction()
dummy default constructor for bindings
Definition: dyngenpar.h:238
StackItem()
invalid type
Definition: dyngenpar.h:490
QMultiHash< QList< Cat >, ConstrainedMultiPrediction > ConstrainedMultiPredictions
Definition: dyngenpar.h:258
Term(int a, int c)
Definition: dyngenpar.h:958
Cat cat
the nonterminal generating the literal
Definition: dyngenpar.h:223
QMultiHash< Cat, NextTokenConstraints > ConstrainedPredictions
Definition: dyngenpar.h:233
MultiPrediction(const QList< Cat > &fullLit, CatArg c)
Definition: dyngenpar.h:220
void add(const Sequence &value)
Java-style (for consistency, even though append is detected here)
Definition: dyngenpar.h:1036
RuleSet rules
set of PMCFG rules
Definition: dyngenpar.h:1073
Node tree
sub-parse-tree for hierarchical parsing
Definition: dyngenpar.h:902
virtual bool rewindTo(int pos, const LexerState &=LexerState())
overridden because lists can be rewound
Definition: dyngenpar.h:912
virtual StackItemData * clone()
Definition: dyngenpar.h:661
LexerState lexerState
Definition: dyngenpar.h:1148
int currentPosition()
get the current input position
Definition: dyngenpar.h:849
Rule(const QVariant &label)
Definition: dyngenpar.h:134
Cat startCat
start category
Definition: dyngenpar.h:1262
int ruleno
used for PMCFGs
Definition: dyngenpar.h:406
bool isNull() const
Definition: dyngenpar.h:805
TextPosition(int l, int c)
Definition: dyngenpar.h:931
StackItemType0(const QList< StackItem > &parents, CatArg cat, CatArg effCat, int pos, const PseudoCatScope &scope)
Definition: dyngenpar.h:522
int type() const
Definition: dyngenpar.h:506
QMultiHash< QList< Cat >, MultiPrediction > MultiPredictions
Definition: dyngenpar.h:232
StackItemType3(const StackItem &parent, const Rule &rule, int len, int curr, int i, const Node &tree, int ruleno, const NextTokenConstraints &nextTokenConstraints)
Definition: dyngenpar.h:618
type 4 item: during reduce, we&#39;re executing a matchRemaining
Definition: dyngenpar.h:655
QList< Function > functions
list of PMCFG functions
Definition: dyngenpar.h:1054
RuleSet rules
grammar rules
Definition: dyngenpar.h:1258
multi-token predictions with next token constraints
Definition: dyngenpar.h:236
virtual StackItemData * clone()
Definition: dyngenpar.h:573
interface for parser actions
Definition: dyngenpar.h:433
type 2 item: during reduce, we&#39;re recursively executing another reduce
Definition: dyngenpar.h:596
Parser(TokenSource *tokenSource)
Definition: dyngenpar.h:1161
virtual ~Parser()
Definition: dyngenpar.h:1163
Cat cat
the nonterminal generating the literal / the nonterminal itself
Definition: dyngenpar.h:246
const StackItem & parent() const
Definition: dyngenpar.h:609
const Cat & CatArg
Category type (string or integer) when passed as an argument.
Definition: dyngenpar.h:83
bool rewindTo(int pos, const Node &parseTree, const LexerState &lexerState=LexerState())
rewind to an older position (requires buffering) and restore the parse tree (needed for lookahead) ...
Definition: dyngenpar.h:874
QList< StackItem > incrementalStacks
Definition: dyngenpar.h:1146
virtual bool matchParseTree(const Node &treeToMatch)
match the parse tree for the last shifted token against the given tree
Definition: dyngenpar.h:845
void addFunction(const QString &name, const Function &function)
Definition: dyngenpar.h:1095
Term(CatArg t)
Definition: dyngenpar.h:959
ActionInfo(const Node &t, Parser *p)
Definition: dyngenpar.h:418
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:694
Alternative(const QVariant &label)
Definition: dyngenpar.h:281
bool isComponent() const
Definition: dyngenpar.h:965
bool operator==(const MultiPrediction &other) const
needed for QList, QMultiHash
Definition: dyngenpar.h:226
void add(const Cat &value)
Java-style + the binding generator doesn&#39;t detect the inherited append.
Definition: dyngenpar.h:161
Alternative & operator<<(const DynGenPar::Node &value)
Definition: dyngenpar.h:301
QHash< Cat, QPair< Cat, QList< Cat > > > pseudoCats
pseudo-categories, used to represent PMCFGs internally
Definition: dyngenpar.h:1288
virtual int type() const
Definition: dyngenpar.h:690
void setLabel(const QVariant &label)
Definition: dyngenpar.h:288
QHash< QString, int > functionIndices
Definition: dyngenpar.h:1094
QDataStream & readExternal(QDataStream &stream)
implementation of the QDataStream operator>>
Definition: dyngenpar.h:113
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:666
PmcfgComponentInfo(const Rule &rule)
Definition: dyngenpar.h:1115
QList< Sequence > & toList()
for bindings
Definition: dyngenpar.h:1040
QList< Node > leaves() const
Definition: dyngenpar.h:726
void setParents(const QList< StackItem > &parents)
Definition: dyngenpar.h:509
int ruleno
needed for PMCFGs (to match components of rules to each other)
Definition: dyngenpar.h:272
QDataStream & readExternal(QDataStream &stream)
implementation of the QDataStream operator>>
Definition: dyngenpar.h:176
PMCFG function.
Definition: dyngenpar.h:1015
QVariant label() const
Definition: dyngenpar.h:287
Alternative(const QList< DynGenPar::Node > &list, const QVariant &label)
Definition: dyngenpar.h:285
Cfg getCfg()
get a Cfg object back from the parser, for serialization
Definition: dyngenpar.h:1176
PseudoCatScope scope() const
Definition: dyngenpar.h:699
bool isToken() const
Definition: dyngenpar.h:966
StackItemType2(const StackItem &parent)
Definition: dyngenpar.h:598
QVector< QVector< int > > argPositions
Definition: dyngenpar.h:1118
full rule as found in the initial graph
Definition: dyngenpar.h:261
bool operator==(const NextTokenConstraints &other) const
needed for hash tables
Definition: dyngenpar.h:105
virtual StackItemData * clone()
Definition: dyngenpar.h:689
StackItemData(int depth)
Definition: dyngenpar.h:476
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:691
Rule(const QList< Cat > &list, const QVariant &label)
Definition: dyngenpar.h:138
Function & operator+=(const Sequence &value)
Definition: dyngenpar.h:1023
const StackItemData * data() const
Definition: dyngenpar.h:510
void loadCfg(const Cfg &cfg)
Definition: dyngenpar.h:1169
bool isToken(CatArg cat) const
Definition: dyngenpar.h:201
static bool serializeLabels
whether the operator<<(QDataStream &, const Rule &) should serialize labels
Definition: dyngenpar.h:131
virtual void setParents(const QList< StackItem > &)
Definition: dyngenpar.h:606
QDataStream & writeExternal(QDataStream &stream) const
implementation of the QDataStream operator<<
Definition: dyngenpar.h:204
int col
column, zero-based
Definition: dyngenpar.h:947
QVariant data
Definition: dyngenpar.h:327
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:603
NextTokenConstraints nextTokenConstraints
Definition: dyngenpar.h:142
const PseudoCatScopeData * data() const
needed for hash tables
Definition: dyngenpar.h:382
type 5 item: during match (of an MCFG constraint), we&#39;re executing a matchRemaining ...
Definition: dyngenpar.h:682
rule constraints affecting the next token, for scannerless parsing
Definition: dyngenpar.h:87
Node()
error node
Definition: dyngenpar.h:321
QList< Alternative > children
Definition: dyngenpar.h:328
int line
line, zero-based
Definition: dyngenpar.h:946
QList< Match > parse(ParseState *parseState)
overloaded version using ParseState, for bindings
Definition: dyngenpar.h:1185
QSet< Cat > TokenSet
Definition: dyngenpar.h:187
void addToken(CatArg cat)
Definition: dyngenpar.h:1165
virtual StackItemData * clone()
Definition: dyngenpar.h:601
Node parseTreeToPmcfgSyntaxTree(const Node &parseTree)
converts a parse tree obtained from a PMCFG to a PMCFG syntax tree
Definition: dyngenpar.cpp:539
QPair< int, PseudoCatScope > mcfgConstraint(CatArg cat) const
Definition: dyngenpar.h:377
Cat nextToken()
get the next token from the input, increment current position, save parse tree
Definition: dyngenpar.h:822
main class
Definition: dyngenpar.h:1158
bool operator<(const StackItem &other) const
Definition: dyngenpar.h:511
const StackItem & parent() const
Definition: dyngenpar.h:633
NextTokenConstraints nextTokenConstraints
Definition: dyngenpar.h:978
virtual void addParent(const StackItem &)
Definition: dyngenpar.h:627
Alternative & operator+=(const QList< DynGenPar::Node > &other)
Definition: dyngenpar.h:289
parse state struct, for bindings
Definition: dyngenpar.h:1131
int depth() const
Definition: dyngenpar.h:507
ActionInfo()
dummy default constructor for bindings
Definition: dyngenpar.h:417
virtual int type() const
Definition: dyngenpar.h:602
NextTokenConstraints nextTokenConstraints() const
Definition: dyngenpar.h:640