function collect_symbols(){
		if( ! $this->length ){
			return null;
		}
		$Rule = $this->reset();
		do {
			if( $Rule->length !== 6 ){
				// empty rule most likely
				continue;
			}
			// collect rule name - guaranteed to be nontermainal
			$Name = $Rule->get_child( 1 );
			$n = $Name->evaluate();
			$nts[ $n ] = $n;
			
			// assume first nt is start symbol
			if( is_null( $this->startsymbol ) ){
				$this->startsymbol = $n;
			}
			
			$Expr = $Rule->get_child( 4 );
			// lists in Expression
			$List = $Expr->reset();
			do {
				// terms in list - may be terminal or nonterminal
				$Term = $List->reset();
				do {
					$s = $Term->evaluate();
					switch( $Term->length ){
					case 1:
						// "terminal" or terminal
						if( $s === P_EPSILON || $s === P_EOF ){
							// mandatory symbols already known
							break;
						}
						$ts[ $s ] = (string) $Term;
						break;
					case 3:
						// angle-bracketed <nonterminal>
						$nts[ $s ] = (string) $Term;
						break;
					}
				}
				while(
					$Term = $List->next()
				);
			}
			while( 
				$Expr->next() && $List = $Expr->next()
			);
			
		}
		while(
			$Rule = $this->next()
		);

		return array( $ts, $nts );
	}
function collect_symbols(){
		if( ! $this->length ){
			return null;
		}
		$Rule = $this->reset();
		do {
			if( $Rule->length !== 6 ){
				// empty rule most likely
				continue;
			}
			// collect rule name - guaranteed to be nontermainal
			$Name = $Rule->get_child( 1 );
			$n = $Name->evaluate();
			$nts[ $n ] = $n;
			
			// assume first nt is start symbol
			if( is_null( $this->startsymbol ) ){
				$this->startsymbol = $n;
			}
			
			$Expr = $Rule->get_child( 4 );
			// lists in Expression
			$List = $Expr->reset();
			do {
				// terms in list - may be terminal or nonterminal
				$Term = $List->reset();
				do {
					$s = $Term->evaluate();
					switch( $Term->length ){
					case 1:
						// "terminal" or terminal
						if( $s === P_EPSILON || $s === P_EOF ){
							// mandatory symbols already known
							break;
						}
						$ts[ $s ] = (string) $Term;
						break;
					case 3:
						// angle-bracketed <nonterminal>
						$nts[ $s ] = (string) $Term;
						break;
					}
				}
				while(
					$Term = $List->next()
				);
			}
			while( 
				$Expr->next() && $List = $Expr->next()
			);
			
		}
		while(
			$Rule = $this->next()
		);

		return array( $ts, $nts );
	}
function collect_symbols ( ) { if ( ! $ this -> length ) { return null ; } $ Rule = $ this -> reset ( ) ; do { if ( $ Rule -> length !== 6 ) { // empty rule most likely continue ; } // collect rule name - guaranteed to be nontermainal $ Name = $ Rule -> get_child ( 1 ) ; $ n = $ Name -> evaluate ( ) ; $ nts [ $ n ] = $ n ; // assume first nt is start symbol if ( is_null ( $ this -> startsymbol ) ) { $ this -> startsymbol = $ n ; } $ Expr = $ Rule -> get_child ( 4 ) ; // lists in Expression $ List = $ Expr -> reset ( ) ; do { // terms in list - may be terminal or nonterminal $ Term = $ List -> reset ( ) ; do { $ s = $ Term -> evaluate ( ) ; switch ( $ Term -> length ) { case 1 : // "terminal" or terminal if ( $ s === P_EPSILON || $ s === P_EOF ) { // mandatory symbols already known break ; } $ ts [ $ s ] = ( string ) $ Term ; break ; case 3 : // angle-bracketed <nonterminal> $ nts [ $ s ] = ( string ) $ Term ; break ; } } while ( $ Term = $ List -> next ( ) ) ; } while ( $ Expr -> next ( ) && $ List = $ Expr -> next ( ) ) ; } while ( $ Rule = $ this -> next ( ) ) ; return array ( $ ts , $ nts ) ; }
Recursively collect terminal and nonterminal strings from Term nodes.
@todo could take this opportunity to test for redundant or unreachable non-terminals
@return array [ [terminala,terminalb,..], [nonterminalX,nonterminalY,..] ]
Recursively collect terminal and nonterminal strings from Term nodes .