예제 #1
0
파일: dfa.go 프로젝트: pschlump/lexie
// -----------------------------------------------------------------------------------------------------------------------------------------------
func (dfa *DFA_PoolType) DumpPoolOneState(ii int) string {
	pLnNo := com.DbOn("db_DFA_LnNo")
	IfLnNo := func(s string) string {
		if pLnNo {
			t := fmt.Sprintf("[%3s]", s)
			return t
		}
		return ""
	}
	vv := dfa.Pool[ii]
	s := ""
	s += fmt.Sprintf("%3d%s: ", ii, IfLnNo(vv.LineNo))
	s += fmt.Sprintf(" %12s %12s %s :", vv.StateName, com.SVar(vv.StateSet), com.ChkOrBlank(vv.Visited))
	if vv.Rv > 0 {
		s += fmt.Sprintf(" T:%04d ", vv.Rv)
	} else {
		s += fmt.Sprintf("        ")
	}
	s += fmt.Sprintf("\t E:")
	for _, ww := range vv.Next2 {
		if ww.IsLambda {
			s += fmt.Sprintf("{  ERROR!! \u03bb  %2d -> %2d  %s}  ", ww.From, ww.To, ww.LineNo)
		} else {
			s += fmt.Sprintf("{ \"%s\" %2d -> %2d  %s}  ", ww.On, ww.From, ww.To, IfLnNo(ww.LineNo))
		}
	}
	s += "\n"
	if vv.Info.Action != 0 || vv.Info.MatchLength != 0 {
		s += fmt.Sprintf("\t\t\tDFA.Info: %s", nfa.DumpInfo(vv.Info))
	}
	s += "\n"
	return s
}
예제 #2
0
파일: dfa.go 프로젝트: pschlump/lexie
func (dfa *DFA_PoolType) ConvNDA_to_DFA(nn *nfa.NFA_PoolType) {
	StartState := nn.InitState
	dfa.NoneVisited()

	nn.Sigma = nn.GenerateSigma()
	dfa.Sigma = nn.Sigma
	com.DbPrintf("dfa2", "Sigma at top ->%s<-\n", dfa.Sigma)

	// Build initial state
	dfa_set := nn.LambdaClosure([]int{StartState}) // Find all the lambda closures from specified state
	dfa_set = append(dfa_set, StartState)          // Add in initial state
	dfa_set = com.USortIntSlice(dfa_set)           // Make set unique
	com.DbPrintf("db_DFAGen", "\nStart: %s, \u03a3 =->%s<-, %s\n", com.SVar(dfa_set), dfa.Sigma, com.LF())
	A := dfa.GetDFAName(dfa_set)
	if r, is, info, Is0Ch := nn.IsTerminalState(dfa_set); is {
		dfa.Pool[A].Rv = r
		dfa.Pool[A].Is0Ch = Is0Ch
		dfa.Pool[A].Info = info
	} else {
		dfa.Pool[A].Info = info
	}
	if com.DbOn("db_DFAGen") {
		dfa.DumpPool(false)
	}
	// Look at all the locaitons we can get to from this "state"
	for _, S := range dfa.Sigma {
		StateSet := nn.LambdaClosureSet(dfa_set, string(S))
		com.DbPrintf("db_DFAGen", "FOR INITIAL state ->%s<- StateSet=%s, %s\n", string(S), com.SVar(StateSet), com.LF())
		if len(StateSet) > 0 {
			com.DbPrintf("db_DFAGen", "Have a non-empty result, %s\n", com.LF())
			com.DbPrintf("db_DFAGen", "<><><> this is the point where we should check to see if 'S' is DOT or NCCL, %s\n", com.LF())

			StateSetT := nn.LambdaClosure(StateSet) // need to lambda complete the state set
			StateSet = append(StateSet, StateSetT...)
			StateSet = com.USortIntSlice(StateSet) // Make set unique
			com.DbPrintf("db_DFAGen", "    Output Is %s, %s\n", com.SVar(StateSet), com.LF())
			B := 0
			if t := dfa.HaveStateAlready(StateSet); t != -1 { // Have Already
				B = t
				com.DbPrintf("db_DFAGen", "    Already have this state at location %d, %s\n", t, com.LF())
			} else {
				B = dfa.GetDFAName(StateSet)
				com.DbPrintf("db_DFAGen", "    *** New state %d, %s\n", B, com.LF())
			}
			dfa.AddEdge(A, B, string(S))
			com.DbPrintf("db_DFAGen", "    *** Before (top) %s\n", com.LF())
			if r, is, info, Is0Ch := nn.IsTerminalState(StateSet); is {
				dfa.Pool[B].Rv = r
				dfa.Pool[B].Is0Ch = Is0Ch
				dfa.Pool[B].Info = info
				com.DbPrintf("db_DFAGen", "    *** New state %d, %s\n", B, com.LF())
			} else if _, is, info, Is0Ch := nn.IsNonTerminalPushPopState(StateSet); is {
				dfa.Pool[B].Is0Ch = Is0Ch
				dfa.Pool[B].Info = info
				com.DbPrintf("db_DFAGen", "    *** New info for state %d, %s\n", B, com.LF())
			} else {
				dfa.Pool[B].Info = info
				com.DbPrintf("db_DFAGen", "    *** NO State Info for state %d, %s\n", B, com.LF())
			}
			com.DbPrintf("db_DFAGen", "    *** After (top) %s\n", com.LF())
			if com.DbOn("db_DFAGen") {
				fmt.Printf("for %s StateSet=%s, A=%d, B=%s %s\n", string(S), com.SVar(StateSet), A, com.SVar(B), com.LF())
				dfa.DumpPool(false)
			}
		}
	}
	dfa.Pool[A].Visited = true

	com.DbPrintf("db_DFAGen", "\nBefore Main Loop, %s\n", com.LF())
	limit := 0
	for stateToDo := dfa.FindNotVisited(); stateToDo != -1; stateToDo = dfa.FindNotVisited() {
		com.DbPrintf("db_DFAGen", "\nMain Loop: !!TOP!! State:%d\n", stateToDo)
		// -----------------------------------------------------------------------------------------------------------
		if !dfa.Pool[stateToDo].Visited {
			dfa_set := nn.LambdaClosure(dfa.Pool[stateToDo].StateSet)  // Find all the lambda closures from specified state
			dfa_set = append(dfa_set, dfa.Pool[stateToDo].StateSet...) // Add in initial state
			dfa_set = com.USortIntSlice(dfa_set)                       // Make set unique
			for _, S := range dfa.Sigma {
				StateSet := nn.LambdaClosureSet(dfa_set, string(S))
				com.DbPrintf("db_DFAGen", "    for initial state %s StateSet=%s, %s\n", string(S), com.SVar(StateSet), com.LF())
				com.DbPrintf("db_DFAGen", "<><><> this is the point where we should check to see if 'S' is DOT or NCCL, %s\n", com.LF())
				if len(StateSet) > 0 {
					com.DbPrintf("db_DFAGen", "    >>> Have a non-empty result, Input Is %s, %s\n", com.SVar(StateSet), com.LF())
					StateSetT := nn.LambdaClosure(StateSet) // need to lambda complete the state set
					StateSet = append(StateSet, StateSetT...)
					StateSet = com.USortIntSlice(StateSet) // Make set unique
					com.DbPrintf("db_DFAGen", "    >>> Output Is %s, %s\n", com.SVar(StateSet), com.LF())
					B := 0
					if t := dfa.HaveStateAlready(StateSet); t != -1 { // Have Already
						B = t
						com.DbPrintf("db_DFAGen", "    Already have this state at location %d, %s\n", t, com.LF())
					} else {
						B = dfa.GetDFAName(StateSet)
					}
					dfa.AddEdge(stateToDo, B, string(S))
					com.DbPrintf("db_DFAGen", "    *** Before %s\n", com.LF())
					if r, is, info, Is0Ch := nn.IsTerminalState(StateSet); is {
						dfa.Pool[B].Rv = r
						dfa.Pool[B].Is0Ch = Is0Ch
						dfa.Pool[B].Info = info
						com.DbPrintf("db_DFAGen", "    *** New state %d, %s\n", B, com.LF())
					} else if _, is, info, Is0Ch := nn.IsNonTerminalPushPopState(StateSet); is {
						dfa.Pool[B].Is0Ch = Is0Ch
						dfa.Pool[B].Info = info
						com.DbPrintf("db_DFAGen", "    *** New info for state %d, %s\n", B, com.LF())
					} else {
						com.DbPrintf("db_DFAGen", "    *** NO State Info for state %d, %s\n", B, com.LF())
						dfa.Pool[B].Info = info
					}
					com.DbPrintf("db_DFAGen", "    *** After %s\n", com.LF())
					if com.DbOn("db_DFAGen") {
						fmt.Printf("    Add New Edge on %s fr %d to %d, %s\n", string(S), stateToDo, B, com.LF())
						fmt.Printf("    for %s StateSet=%s, A(stateToDo)=%d, %s\n", string(S), com.SVar(StateSet), stateToDo, com.LF())
						dfa.DumpPool(false)
					}
				}
			}
		}
		// -----------------------------------------------------------------------------------------------------------
		dfa.Pool[stateToDo].Visited = true
		limit++
		if limit > 50000 {
			break
		}
	}
	dfa.VerifyMachine()

}
예제 #3
0
파일: dfa.go 프로젝트: pschlump/lexie
func (dfa *DFA_PoolType) DumpPool(all bool) {
	if all {
		com.DbPrintf("db_DumpDFAPool", "Cur: %d Top: %d NextFree %d\n", dfa.Cur, dfa.Top, dfa.NextFree)
	}
	com.DbPrintf("db_DumpDFAPool", "\n---------------------------- DFA Output -----------------------------------------------\n")
	com.DbPrintf("db_DumpDFAPool", "\nDFA InitState: %d, Sigma ->%s<-\n\n", dfa.InitState, dfa.Sigma)
	pLnNo := com.DbOn("db_DFA_LnNo")
	IfLnNo := func(s string) string {
		if pLnNo {
			t := fmt.Sprintf("[%3s]", s)
			return t
		}
		return ""
	}
	com.DbPrintf("db_DumpDFAPool", "%3s%s: ", "St", IfLnNo("/Ln"))
	com.DbPrintf("db_DumpDFAPool", " %12s %12s \u2714              \tEdges", "StateName", "StateSet")
	com.DbPrintf("db_DumpDFAPool", "\n\n")
	for ii, vv := range dfa.Pool {
		if all || vv.IsUsed {
			com.DbPrintf("db_DumpDFAPool", "%3d%s: ", ii, IfLnNo(vv.LineNo))
			com.DbPrintf("db_DumpDFAPool", " %12s %12s %s :", vv.StateName, com.SVar(vv.StateSet), com.ChkOrBlank(vv.Visited))
			if vv.Rv > 0 {
				if vv.Is0Ch {
					com.DbPrintf("db_DumpDFAPool", " \u03c4:Tau:%04d ", vv.Rv)
				} else {
					com.DbPrintf("db_DumpDFAPool", " T:%04d ", vv.Rv)
				}
			} else {
				com.DbPrintf("db_DumpDFAPool", "        ")
			}
			if com.DbOn("db_DumpDFAPool") {
				fmt.Printf("\t E:")
				for _, ww := range vv.Next2 {
					if ww.Is0ChMatch {
						fmt.Printf("//Found  \u03c4 (%s) //", com.LF()) // Show a Tau(t) for a lambda that matchiens on else conditions.
					}
					if ww.IsLambda {
						fmt.Printf("{  ERROR!! \u03bb  %2d -> %2d  %s}  ", ww.From, ww.To, ww.LineNo)
					} else {
						// fmt.Printf("{ \"%s\" %2d -> %2d  %s}  ", ww.On, ww.From, ww.To, IfLnNo(ww.LineNo))
						on, _ := utf8.DecodeRune([]byte(ww.On))
						son := fmt.Sprintf("%q", ww.On)
						switch on {
						case re.R_DOT: // = '\uF8FA' // Any char in Sigma
							son = "DOT/uF8FA"
						case re.R_BOL: // = '\uF8F3' // Beginning of line
							son = "BOL/uF8F3"
						case re.R_EOL: // = '\uF8F4' // End of line
							son = "EOL/uF8F4"
						case re.R_NUMERIC: // = '\uF8F5'
							son = "NUMERIC/uF8F5"
						case re.R_LOWER: // = '\uF8F6'
							son = "LOWER/uF8F6"
						case re.R_UPPER: // = '\uF8F7'
							son = "UPPER/uF8F7"
						case re.R_ALPHA: // = '\uF8F8'
							son = "ALPHA/uF8F8"
						case re.R_ALPHNUM: // = '\uF8F9'
							son = "ALPHANUM/uF8F9"
						case re.R_EOF: // = '\uF8FB'
							son = "EOF/uF8FB"
						case re.R_not_CH: // = '\uF8FC' // On input lookup if the char is NOT in Signa then it is returned as this.
							son = "else_CH/uF8Fc"
						case re.R_N_CCL: // = '\uF8FD' // If char is not matched in this state then take this path
							son = "N_CCL/uF8Fd"
						case re.R_LAMBDA_MATCH: // = '\uF8FE'
							son = "LambdaM/uF8FE"
						}
						fmt.Printf("{ %s  %2d -> %2d  %s}  ", son, ww.From, ww.To, IfLnNo(ww.LineNo))
					}
				}
				fmt.Printf("\n")
				if vv.Info.Action != 0 || vv.Info.MatchLength != 0 {
					// fmt.Printf("\t\t\tInfo: %s\n", com.SVar(vv.Info))		// xyzzy - output Info
					// xyzzy - NextState info
					fmt.Printf("\t\t\tDFA.Info: %s", nfa.DumpInfo(vv.Info))
					// if ((vv.Info.Action&com.A_Pop) != 0 || (vv.Info.Action&com.A_Push) != 0 || (vv.Info.Action&com.A_Reset) != 0) && !vv.Info.HardMatch {		// xyzzy8
					fmt.Printf(" IsHard=%v (((false imples else case Rv!)))\n", vv.Info.HardMatch)
				}
				fmt.Printf("\n")
			}
		}
	}
}
예제 #4
0
파일: tok.go 프로젝트: pschlump/lexie
func (tl *TokenList) FlushTokenBuffer(TokStart int, isHard bool, atEof bool) {
	ok := true

	if !isHard {
		n := len(tl.TL) - 1
		if tl.TL[n].AToken.TokNo != tl.IgnoreToken {
			tl.TokenData = append(tl.TokenData, tl.TL[n].AToken)
		}
		tl.TL = tl.TL[:0]
		tl.EndIdx = make(map[int]int)
		return
	}

	if com.DbOn("db_FlushTokenBeforeBefore") {
		fmt.Printf("Before Flush, TokStart=%d, eof = %v\n", TokStart, atEof)
		tl.DumpTokenBuffer()
	}

	keepTok := make([]int, 0, len(tl.TL)) // Set of tokens to keepTokerve

	//com.DbPrintf("db_tok01","tl.EndIdx = %+v\n", tl.EndIdx)
	// Walk Backwards Creating List
	limit := 15
	for ii := len(tl.TL) - 1; ii >= 0 && limit > 0; limit-- {
		top_ii := ii
		com.DbPrintf("db_tok01", "At top of loop, ii = %d, tl.TL[ii]=%+v\n", ii, tl.TL[ii])
		keepTok = append(keepTok, ii)
		if ii <= 0 {
			break
		}
		end := tl.TL[ii].Start
		ii, ok = tl.EndIdx[end]
		if atEof {
			ii--
		}
		com.DbPrintf("db_tok01", "CCC ii=%d ok=%v end=%d atEof=%v\n", ii, ok, end, atEof)
		if !ok {
			if com.DbOn("OutputErrors") {
				fmt.Printf("Note: Failed to flush - invalid token set, ii=%v, end=%v, %s\n", ii, end, com.LF())
			}
			break
		}
		if end == 0 {
			fmt.Printf("Reached and end of 0\n")
			break
		}

		l := tl.TL[top_ii].End - tl.TL[top_ii].Start
		d := len(tl.TL[top_ii].AToken.Match)
		//com.DbPrintf("db_tok01","DDD top_ii=%d l=%d d=%d before ->%s<-\n", top_ii, l, d, tl.TL[top_ii].AToken.Match)
		if d-l >= 0 && d-l < d && top_ii >= 0 && top_ii < len(tl.TL) {
			tl.TL[top_ii].AToken.Match = tl.TL[top_ii].AToken.Match[d-l:]
		}
		//com.DbPrintf("db_tok01","EEE top_ii=%d l=%d d=%d after  ->%s<-\n", top_ii, l, d, tl.TL[top_ii].AToken.Match)
		if tl.TL[top_ii].AToken.IsRepl {
			tl.TL[top_ii].AToken.Val = tl.TL[top_ii].AToken.ReplStr
		} else {
			tl.TL[top_ii].AToken.Val = tl.TL[top_ii].AToken.Val[d-l:]
		}
	}

	last := len(tl.TokenData) - 1
	com.DbPrintf("db_tok01", "keepTok = %s, last=%d\n", com.SVar(keepTok), last)
	for ii := len(keepTok) - 1; ii >= 0; ii-- {
		vv := keepTok[ii]
		// xyzzy - if not an Ignore token then
		if tl.TL[vv].AToken.TokNo != tl.IgnoreToken {
			tl.TokenData = append(tl.TokenData, tl.TL[vv].AToken)
		}
	}

	// send EOF token -- Handeled in matcher better
	//if atEof {
	//	tl.TokenData = append(tl.TokenData, Token{TokNo: 37}) // tl.TokenData = append(tl.TokenData, Token{TokNo: Tok_EOF})
	//}

	tl.TL = tl.TL[:0]
	tl.EndIdx = make(map[int]int)

	if com.DbOn("db_FlushTokenBeforeAfter") {
		fmt.Printf("After Flush\n")
		fmt.Printf("--------------------------------------------------------\n")
		tl.DumpTokenBuffer()
		fmt.Printf("--------------------------------------------------------\n")
	}
}