4 private $items; /* kernel */
7 public function __construct( $items, $grammar ) {
8 if( !is_array( $items ) )
9 $items = array( $items );
11 $this->items
= $items;
12 $this->grammar
= $grammar;
15 public function next_symbols() {
17 foreach( $this->closure() as $item ) {
18 $next = $item->next();
19 if( $next !== false && !in_array( $next, $symbols ) ) {
26 public function take( $symbol ) {
27 $next_items = array();
28 foreach( $this->closure() as $item ) {
29 $next_item = $item->take( $symbol );
30 if( $next_item !== false ) {
31 $next_items[] = $next_item;
34 return new self( $next_items, $this->grammar
);
37 public function closure() {
38 $items = $this->items
;
40 /* Don't use foreach. $items can grow in the loop, and the new items needs to be handled too */
41 for( $i = 0; $i<count($items); $i++
) {
42 $cur_item = $items[$i];
43 $next_symbol = $cur_item->next();
44 if( $next_symbol === false ) {
47 foreach( $this->grammar
->productions( $next_symbol ) as $new_item ) {
49 foreach( $items as $test_item ) {
50 if( $test_item->equals($new_item) ) {
63 public function errors() {
64 $items = $this->items
;
67 /* Don't use foreach. $items can grow in the loop, and the new items needs to be handled too */
68 for( $i = 0; $i<count($items); $i++
) {
69 $cur_item = $items[$i];
70 $next_symbol = $cur_item->next();
71 $rule = $this->grammar
->errors($next_symbol);
73 foreach( $rule->follow() as $follow ) {
74 $errors[$follow] = $rule;
81 public function __toString() {
83 foreach( $this->closure() as $item ) {
89 public function equals( $state ) {
90 if( count( $this->items
) != count( $state->items
) ) {
93 foreach( $this->items
as $itema ) {
95 foreach( $state->items
as $itemb ) {
96 if( $itema->equals( $itemb ) ) {
100 if( $exists == false )