func (item *EarleyItem) isCompleted() bool {
	return item.RulePos == item.Rule.length()
}
complete means that dot reaches the end
package earley
import (
	"fmt"
	"strings"
)
type EarleyItem struct {
	id      ItemId
	Rule    *GrammarRule
	RulePos int  
	originatingIndex int
	cause            StateType  
	from                    []ItemId
	terminalSymbolsConsumed int
	ctx                     *completionContext
}
type ItemId struct {
	StateSetIndex int
	ItemIndex     int
}
func newPredictItem(r *GrammarRule, index int, from []ItemId, ctx *completionContext) *EarleyItem {
	return &EarleyItem{
		Rule:             r,
		RulePos:          0,
		originatingIndex: index,
		cause:            PREDICT_STATE,
		ctx:              ctx,
		from:             from,
	}
}
func newScanItem(sourceState *EarleyItem, index int, from []ItemId, ctx *completionContext) *EarleyItem {
	return &EarleyItem{
		Rule:                    sourceState.Rule,
		RulePos:                 sourceState.RulePos + 1,
		originatingIndex:        index,
		ctx:                     ctx,
		terminalSymbolsConsumed: sourceState.terminalSymbolsConsumed + 1,
		cause:                   SCAN_STATE,
		from:                    from,
	}
}
func newCompleteItem(sourceState *EarleyItem, from []ItemId, ctx *completionContext) *EarleyItem {
	return &EarleyItem{
		Rule:                    sourceState.Rule,
		RulePos:                 sourceState.RulePos + 1,
		originatingIndex:        sourceState.originatingIndex,
		terminalSymbolsConsumed: sourceState.terminalSymbolsConsumed,
		ctx:                     ctx,
		cause:                   COMPLETE_STATE,
		from:                    from,
	}
}
func (item *EarleyItem) String() string {
	rightStrings := make([]string, len(item.Rule.right))
	for i, r := range item.Rule.right {
		rightStrings[i] = r.String()
	}
	fromStr := "root"
	if item.from != nil {
		fromStrings := make([]string, len(item.from))
		for i, r := range item.from {
			fromStrings[i] = fmt.Sprintf("S[%d][%d]", r.StateSetIndex, r.ItemIndex)
		}
		fromStr = strings.Join(fromStrings, ",")
	}
	return fmt.Sprintf("Rule(%v) -> %v %v %v (%d) (cause:%v) (tokensConsumed:%v) (from: %v)\n",
		item.Rule.left.String(),
		strings.Join(rightStrings[0:item.RulePos], " "),
		Cursor,
		strings.Join(rightStrings[item.RulePos:], " "),
		item.originatingIndex,
		item.cause,
		item.terminalSymbolsConsumed,
		fromStr,
	)
}
func (item *EarleyItem) badhash() uint64 {
	return uint64(item.Rule.grammarRuleId)<<32 | uint64(item.RulePos)<<16 | uint64(item.originatingIndex)
}