예제 #1
0
파일: GoANBF.go 프로젝트: rainliu/GoABNF
func GenerateNFA(ruleName string, regularRuleList *list.List) *automata.NFA {
	rules := make(map[string]*abnf.Rule)
	for e := regularRuleList.Front(); e != nil; e = e.Next() {
		v := e.Value.(*abnf.Rule)
		rules[v.GetRuleName().String()] = v
	}
	startState := automata.NewNFAState()
	acceptingState := automata.NewNFAState()
	rules[ruleName].GetElements().GetNFAStates(startState, acceptingState, rules)
	return automata.NewNFA2(startState, acceptingState)
}
예제 #2
0
func (this *Concatenation) GetNFAStates(startState, acceptingState *automata.NFAState, rules map[string]*Rule) {
	current := startState
	e := this.repetitions.Front()
	var next *automata.NFAState
	for index := 0; index < this.repetitions.Len()-1; index++ {
		next = automata.NewNFAState()
		e.Value.(*Repetition).GetNFAStates(current, next, rules)
		current = next
		e = e.Next()
	}
	e.Value.(*Repetition).GetNFAStates(current, acceptingState, rules)
}
예제 #3
0
func (this *Concatenation) GetNFA(rules map[string]*Rule) *automata.NFA { //throws IllegalAbnfException {
	startState := automata.NewNFAState()
	acceptingState := automata.NewNFAState()
	this.GetNFAStates(startState, acceptingState, rules)
	return automata.NewNFA2(startState, acceptingState)
}
예제 #4
0
func (this *Repetition) GetNFAStates(startState, acceptingState *automata.NFAState, rules map[string]*Rule) {
	if this.repeat == nil {
		this.element.GetNFAStates(startState, acceptingState, rules)
		return
	}

	min := this.repeat.GetMin()
	max := this.repeat.GetMax()

	if min < 0 /*|| max < 0*/ {
		panic("Min value of a repeat element can not be less than zero.")
	}

	if max == -1 {
		if min == 0 {
			//              min == 0 && max == -1
			startState.AddTransitEpsilon(acceptingState)
			this.element.GetNFAStates(acceptingState, acceptingState, rules)
			return
		} else {
			//              min > 0 && max == -1
			current := startState
			for j := 0; j < min-1; j++ {
				next := automata.NewNFAState()
				this.element.GetNFAStates(current, next, rules)
				current = next
			}
			this.element.GetNFAStates(current, acceptingState, rules)
			this.element.GetNFAStates(acceptingState, acceptingState, rules)
			return
		}
	} else {
		if min == 0 {
			//              min == 0 && max > 0
			current := startState
			for j := 0; j < max-1; j++ {
				current.AddTransitEpsilon(acceptingState)
				next := automata.NewNFAState()
				this.element.GetNFAStates(current, next, rules)
				current = next
			}
			current.AddTransitEpsilon(acceptingState)
			this.element.GetNFAStates(current, acceptingState, rules)
			return
		} else if min == max {
			//              0 < min == max
			current := startState
			for j := 0; j < max-1; j++ {
				next := automata.NewNFAState()
				this.element.GetNFAStates(current, next, rules)
				current = next
			}
			this.element.GetNFAStates(current, acceptingState, rules)
			return
		} else if min < max {
			//              0 < min < max
			current := startState
			for j := 0; j < min; j++ {
				next := automata.NewNFAState()
				this.element.GetNFAStates(current, next, rules)
				current = next
			}
			for j := 0; j < max-min-1; j++ {
				current.AddTransitEpsilon(acceptingState)
				next := automata.NewNFAState()
				this.element.GetNFAStates(current, next, rules)
				current = next
			}
			current.AddTransitEpsilon(acceptingState)
			this.element.GetNFAStates(current, acceptingState, rules)
			return
		} else {
			panic("Max can not less than min")
		}
	}
}