PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/sergiosgc/Text/Parser/Generator/FSA/Transition.php

https://github.com/sergiosgc/Text_Parser_Generator
PHP | 135 lines | 61 code | 6 blank | 68 comment | 10 complexity | fc529722b6f4632dfa24d41099be280d MD5 | raw file
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. namespace sergiosgc;
  4. /**
  5. * Text_Parser_Generator_FSA_Transition represents an arc in a Text_Parser_Generator_FSA state graph
  6. *
  7. * A transition connects a specific item in the state's itemset with a target state (connecting, in fact, two states).
  8. * This class is abstract, as only Text_Parser_Generator_FSA_Transition_Reduce and Text_Parser_Generator_FSA_Transition_Shift
  9. * should be instantiated
  10. */
  11. abstract class Text_Parser_Generator_FSA_Transition
  12. {
  13. protected $advanceSymbol;
  14. /* getAdvanceSymbol {{{ */
  15. public function getAdvanceSymbol()
  16. {
  17. return $this->advanceSymbol;
  18. }
  19. /* }}} */
  20. /* setAdvanceSymbol {{{ */
  21. public function setAdvanceSymbol($symbol)
  22. {
  23. $this->advanceSymbol = $symbol;
  24. }
  25. /* }}} */
  26. protected $originItem;
  27. /* getOriginItem {{{ */
  28. public function getOriginItem()
  29. {
  30. return $this->originItem;
  31. }
  32. /* }}} */
  33. /* getOriginState {{{ */
  34. public function getOriginState()
  35. {
  36. return $this->originItem->getItemSet()->getState();
  37. }
  38. /* }}} */
  39. protected $lookahead = array();
  40. /* getLookahead {{{ */
  41. /**
  42. * Lookahead getter
  43. *
  44. * @return array Array of symbol sets specifying the lookahead that triggers this transition
  45. */
  46. public function getLookahead()
  47. {
  48. return $this->lookahead;
  49. }
  50. /* }}} */
  51. /* setLookahead {{{ */
  52. /**
  53. * Lookahead setter
  54. *
  55. * @param array Array of symbol sets specifying the lookahead for this transition
  56. */
  57. public function setLookahead($la)
  58. {
  59. $this->lookahead = $la;
  60. }
  61. /* }}} */
  62. /* removeLookaheadCommonWith {{{ */
  63. /**
  64. * Remove, from this transition's lookahead, symbols that would cause it to conflict with the argument transition
  65. *
  66. * Please note that this function will only remove lookahead symbols from the transition lookahead
  67. *
  68. * @param Text_Parser_Generator_FSA_Transition
  69. * @param Structures_Grammar Grammar to whose symbols the lookahead sets refer to
  70. */
  71. public function removeLookaheadCommonWith($other, $grammar)
  72. {
  73. foreach($other->getLookahead() as $i => $otherLookahead) {
  74. if (!array_key_exists($i, $this->lookahead)) $this->lookahead[$i] = $grammar->getNonTerminalSymbolSet();
  75. if ($this->lookahead[$i]->isDisjoint($otherLookahead)) break;
  76. $this->lookahead[$i]->complement($otherLookahead);
  77. }
  78. }
  79. /* }}} */
  80. /* Constructor {{{ */
  81. public function __construct($origin)
  82. {
  83. if (!$origin instanceof Text_Parser_Generator_Item) throw new Text_Parser_Generator_Exception('Origin of transition must be a Text_Parser_Generator_Item');
  84. $this->originItem = $origin;
  85. $this->getOriginState()->addTransition($this);
  86. }
  87. /* }}} */
  88. /* __equals {{{ */
  89. public function __equals($other)
  90. {
  91. return $other->getOriginItem() == $this->getOriginItem();
  92. }
  93. /* }}} */
  94. /**
  95. * Compute the lookahead for this transition
  96. *
  97. * The result is an array of symbols, at most N large, for an LR(N) parser (or LALR(N)).
  98. *
  99. * For an LALR(n) or LR(n) parser, the result contains at most N symbols. Naturally,
  100. * for an LR(0) parser, the result is an empty array.
  101. *
  102. * If, for an LALR(n) parser, a result row contains less than n symbols, it can be assumed that the
  103. * rightmost lookaheads (the ones closer to the end of the parsed document) are don't-cares/wildcards.
  104. *
  105. * @return array Array of symbol sets specifying the lookahead that triggers this transition
  106. */
  107. abstract public function computeLookahead($grammar);
  108. /* conflictsWith {{{ */
  109. /**
  110. * Test whether there is a conflict with another transition
  111. *
  112. * There's a conflict between two transitions originating from the same state if there is some
  113. * input sequence (expected input symbol + lookahead symbols) that triggers both transitions
  114. * and the two transitions produce different parser state evolutions
  115. *
  116. * @return boolean true iff the transitions conflict
  117. */
  118. public function conflictsWith($other)
  119. {
  120. if ($this->getOriginState() != $other->getOriginState()) return false;
  121. if ($this->getAdvanceSymbol() != $other->getAdvanceSymbol()) return false;
  122. $left = $this->getLookahead();
  123. $right = $other->getLookahead();
  124. for ($i=min(count($left), count($right)) - 1; $i>=0; $i--) if ($left[$i]->isDisjoint($right[$i])) return false;
  125. return true;
  126. }
  127. /* }}} */
  128. }
  129. ?>