--TEST--
Generate parser for the grammar at http://en.wikipedia.org/wiki/Lr_parser
--FILE--
<?php
ini_set('include_path', realpath(dirname(__FILE__) . '/../../Structures_Grammar/') . ':' .
realpath(dirname(__FILE__) . '/../') . ':' .
ini_get('include_path'));
require_once('Structures/Grammar/Symbol.php');
require_once('Structures/Grammar/Rule.php');
require_once('Structures/Grammar.php');
require_once('Text/Parser/Generator/LR.php');
$grammar = new Structures_Grammar(true, false);
$grammar->addTerminal(Structures_Grammar_Symbol::create('0'));
$grammar->addTerminal(Structures_Grammar_Symbol::create('1'));
$grammar->addTerminal(Structures_Grammar_Symbol::create('+'));
$grammar->addTerminal(Structures_Grammar_Symbol::create('*'));
$grammar->addNonTerminal(Structures_Grammar_Symbol::create('E'));
$grammar->addNonTerminal(Structures_Grammar_Symbol::create('B'));
$grammar->addNonTerminal(Structures_Grammar_Symbol::create('S'));
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('S'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('E'));
$grammar->addRule($rule);
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('E'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('E'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('*'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('B'));
$grammar->addRule($rule);
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('E'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('E'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('+'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('B'));
$rule->addReductionFunctionSymbolmap(0, '$e');
$rule->addReductionFunctionSymbolmap(1, '$b');
$grammar->addRule($rule);
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('E'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('B'));
$rule->addReductionFunctionSymbolmap(0, '$b');
$grammar->addRule($rule);
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('B'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('0'));
$rule->addReductionFunctionSymbolmap(0, '$zero');
$grammar->addRule($rule);
$rule = new Structures_Grammar_Rule();
$rule->addSymbolToLeft(Structures_Grammar_Symbol::create('B'));
$rule->addSymbolToRight(Structures_Grammar_Symbol::create('1'));
$rule->addReductionFunctionSymbolmap(0, '$one');
$grammar->addRule($rule);
$generator = new Text_Parser_Generator_LR($grammar);
print($generator->generate('SampleParser'));
?>
--EXPECT--
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
require_once('Text/Parser/LR.php');
/**
*
* This is an automatically generated parser for the following grammar:
*
* [0] S->E
* [1] E->E*B
* [2] E->E+B
* [3] E->B
* [4] B->0
* [5] B->1
*
* -- Finite State Automaton States --
* ----------- 0 -----------
* --Itemset--
* S->•E
* +E->•E*B
* +E->•E+B
* +E->•B
* +B->•0
* +B->•1
* --Transitions--
* Goto on E to 1 because of S->•E
* Goto on E to 1 because of E->•E*B
* Goto on E to 1 because of E->•E+B
* Goto on B to 2 because of E->•B
* Shift on 0 to 3 because of B->•0
* Shift on 1 to 4 because of B->•1
* ----------- 1 -----------
* --Itemset--
* S->E•
* E->E•*B
* E->E•+B
* --Transitions--
* Accept on using S->E
* Shift on * to 5 because of E->E•*B
* Shift on + to 6 because of E->E•+B
* ----------- 2 -----------
* --Itemset--
* E->B•
* --Transitions--
* Reduce on 0 using E->B
* Reduce on 1 using E->B
* Reduce on + using E->B
* Reduce on * using E->B
* Reduce on using E->B
* ----------- 3 -----------
* --Itemset--
* B->0•
* --Transitions--
* Reduce on 0 using B->0
* Reduce on 1 using B->0
* Reduce on + using B->0
* Reduce on * using B->0
* Reduce on using B->0
* ----------- 4 -----------
* --Itemset--
* B->1•
* --Transitions--
* Reduce on 0 using B->1
* Reduce on 1 using B->1
* Reduce on + using B->1
* Reduce on * using B->1
* Reduce on using B->1
* ----------- 5 -----------
* --Itemset--
* E->E*•B
* +B->•0
* +B->•1
* --Transitions--
* Goto on B to 7 because of E->E*•B
* Shift on 0 to 3 because of B->•0
* Shift on 1 to 4 because of B->•1
* ----------- 6 -----------
* --Itemset--
* E->E+•B
* +B->•0
* +B->•1
* --Transitions--
* Goto on B to 8 because of E->E+•B
* Shift on 0 to 3 because of B->•0
* Shift on 1 to 4 because of B->•1
* ----------- 7 -----------
* --Itemset--
* E->E*B•
* --Transitions--
* Reduce on 0 using E->E*B
* Reduce on 1 using E->E*B
* Reduce on + using E->E*B
* Reduce on * using E->E*B
* Reduce on using E->E*B
* ----------- 8 -----------
* --Itemset--
* E->E+B•
* --Transitions--
* Reduce on 0 using E->E+B
* Reduce on 1 using E->E+B
* Reduce on + using E->E+B
* Reduce on * using E->E+B
* Reduce on using E->E+B
*
*/
class SampleParser extends Text_Parser_LR
{
/* Constructor {{{ */
/**
* Parser constructor
*
* @param Text_Tokenizer Tokenizer that will feed this parser
*/
public function __construct(&$tokenizer)
{
parent::__construct($tokenizer);
$this->_gotoTable = unserialize('a:3:{i:0;a:2:{s:1:"E";i:1;s:1:"B";i:2;}i:5;a:1:{s:1:"B";i:7;}i:6;a:1:{s:1:"B";i:8;}}');
$this->_actionTable = unserialize('a:9:{i:1;a:3:{s:0:"";a:1:{s:6:"action";s:6:"accept";}s:1:"*";a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:5;}s:1:"+";a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:6;}}i:0;a:2:{i:0;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:3;}i:1;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:4;}}i:5;a:2:{i:0;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:3;}i:1;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:4;}}i:6;a:2:{i:0;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:3;}i:1;a:2:{s:6:"action";s:5:"shift";s:9:"nextState";i:4;}}i:2;a:5:{i:0;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:2:"$b";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_3";}i:1;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:2:"$b";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_3";}s:1:"+";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:2:"$b";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_3";}s:1:"*";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:2:"$b";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_3";}s:0:"";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:2:"$b";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_3";}}i:3;a:5:{i:0;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:5:"$zero";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_4";}i:1;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:5:"$zero";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_4";}s:1:"+";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:5:"$zero";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_4";}s:1:"*";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:5:"$zero";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_4";}s:0:"";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:5:"$zero";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_4";}}i:4;a:5:{i:0;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:4:"$one";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_5";}i:1;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:4:"$one";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_5";}s:1:"+";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:4:"$one";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_5";}s:1:"*";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:4:"$one";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_5";}s:0:"";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:1:{i:0;s:4:"$one";}s:15:"leftNonTerminal";s:1:"B";s:8:"function";s:13:"reduce_rule_5";}}i:7;a:5:{i:0;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:0:"";i:1;s:0:"";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_1";}i:1;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:0:"";i:1;s:0:"";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_1";}s:1:"+";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:0:"";i:1;s:0:"";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_1";}s:1:"*";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:0:"";i:1;s:0:"";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_1";}s:0:"";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:0:"";i:1;s:0:"";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_1";}}i:8;a:5:{i:0;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:2:"$e";i:1;s:2:"$b";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_2";}i:1;a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:2:"$e";i:1;s:2:"$b";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_2";}s:1:"+";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:2:"$e";i:1;s:2:"$b";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_2";}s:1:"*";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:2:"$e";i:1;s:2:"$b";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_2";}s:0:"";a:4:{s:6:"action";s:6:"reduce";s:7:"symbols";a:3:{i:0;s:2:"$e";i:1;s:2:"$b";i:2;s:0:"";}s:15:"leftNonTerminal";s:1:"E";s:8:"function";s:13:"reduce_rule_2";}}}');
}
/* }}} */
/* reduce_rule_3 {{{ */
/**
* Reduction function for rule 3
*
* Rule 3 is:
* E->B
*
* @param Text_Tokenizer_Token Token of type 'B'
* @return Text_Tokenizer_Token Result token from reduction. It must be a 'E' token
*/
protected function reduce_rule_3($b)
{
require_once('Text/Tokenizer/Token.php');
$result = '';
return new Text_Tokenizer_Token('E', $result);
}
/* }}} */
/* reduce_rule_4 {{{ */
/**
* Reduction function for rule 4
*
* Rule 4 is:
* B->0
*
* @param Text_Tokenizer_Token Token of type '0'
* @return Text_Tokenizer_Token Result token from reduction. It must be a 'B' token
*/
protected function reduce_rule_4($zero)
{
require_once('Text/Tokenizer/Token.php');
$result = '';
return new Text_Tokenizer_Token('B', $result);
}
/* }}} */
/* reduce_rule_5 {{{ */
/**
* Reduction function for rule 5
*
* Rule 5 is:
* B->1
*
* @param Text_Tokenizer_Token Token of type '1'
* @return Text_Tokenizer_Token Result token from reduction. It must be a 'B' token
*/
protected function reduce_rule_5($one)
{
require_once('Text/Tokenizer/Token.php');
$result = '';
return new Text_Tokenizer_Token('B', $result);
}
/* }}} */
/* reduce_rule_1 {{{ */
/**
* Reduction function for rule 1
*
* Rule 1 is:
* E->E*B
*
* @return Text_Tokenizer_Token Result token from reduction. It must be a 'E' token
*/
protected function reduce_rule_1()
{
require_once('Text/Tokenizer/Token.php');
$result = '';
return new Text_Tokenizer_Token('E', $result);
}
/* }}} */
/* reduce_rule_2 {{{ */
/**
* Reduction function for rule 2
*
* Rule 2 is:
* E->E+B
*
* @param Text_Tokenizer_Token Token of type 'E'
* @param Text_Tokenizer_Token Token of type '+'
* @return Text_Tokenizer_Token Result token from reduction. It must be a 'E' token
*/
protected function reduce_rule_2($e,$b)
{
require_once('Text/Tokenizer/Token.php');
$result = '';
return new Text_Tokenizer_Token('E', $result);
}
/* }}} */
}