     }
     
     func recognize(source: String) -> (ok: Bool, tokens: [RecognizedToken]) {
+        //是否完全识别了输入的语言
         var ok: Bool = true
+        //识别到的token数组
         var tokens = [RecognizedToken]()
+        //当前正在识别的字符的位置
         var workingIndex = source.startIndex
+        //识别到的可能是token的字符串的位置（已经跳转到了某个状态）
         var workingStringLocation: String.Index? = nil
+        //最后一个识别到的终结符的位置
         var lastTerminatorParentIndex: String.Index? = nil
+        //在识别的过程中我们会不断深入到一颗前缀树的子树中，这个临时变量就是用来记录当前用于识别的前缀树
         var workingTrie = dfa
+        //遍历所有的输入字符
         while workingIndex < source.endIndex {
+            //取出当前用于识别的字符
             let codeUnit = source[workingIndex]
+            //无论如何，如果当前前缀树有终结符，我们都先记录下来
             if workingTrie.hasTernimatorChild() {
                 lastTerminatorParentIndex = workingIndex
             }
             if let exists = workingTrie.child(key: codeUnit) {
+                //如果没有记录过workingStringLocation，则说明当前字符是某个token的第一个字符
                 if workingStringLocation == nil {
                     workingStringLocation = workingIndex
                 }
+                //将工作位置往后移一位，并将匹配到的子树赋值给工作前缀树，用于识别下一个字符
                 workingIndex = source.index(after: workingIndex)
                 workingTrie = exists
-                if workingIndex == source.endIndex, workingTrie.hasTernimatorChild() {
-                    if let tokenFrom = workingStringLocation {
+                //已经到了文件末尾，要特殊处理一下，如果当前已经跳转到到了某个状态并且前缀树有终结符，那么我们就成功的识别到了最后一个token，反之，说明最后一个token并没有写完整，则识别失败。
+                if workingIndex == source.endIndex {
+                    if workingTrie.hasTernimatorChild(), let tokenFrom = workingStringLocation {
                         let tokenRange = Range(uncheckedBounds: (lower: tokenFrom, upper: workingIndex))
                         let tokenString = source.substring(with: tokenRange)
                         let token = RecognizedToken(range: tokenRange, string: tokenString)

            }
            
        }
        return (ok: ok, tokens: tokens)
    }
}

                    }
                }
            } else if let tokenTo = lastTerminatorParentIndex, let tokenFrom = workingStringLocation {
                //如果当前字符没有被当前前缀树识别，输出当前识别到的最长token，并将工作位置回退到该token的末尾，然后继续识别
                let tokenRange = Range(uncheckedBounds: (lower: tokenFrom, upper: tokenTo))
                let tokenString = source.substring(with: tokenRange)
                let token = RecognizedToken(range: tokenRange, string: tokenString)
