示例#1
0
 /// <summary>
 /// 构造器
 /// </summary>
 public SceneFunction(string callname, string parent, SceneAction sa = null)
 {
     this.ParentSceneName = parent;
     this.Callname = callname;
     this.Param = null;
     this.Sa = sa;
 }
示例#2
0
 /// <summary>
 /// 为当前动作创建一个副本
 /// </summary>
 /// <param name="pureClone">是否保留关系</param>
 /// <returns>原动作的深拷贝副本</returns>
 public SceneAction Clone(bool pureClone)
 {
     SceneAction resSa = new SceneAction();
     resSa.ArgsDict = new Dictionary<string, string>();
     foreach (var kv in this.ArgsDict)
     {
         resSa.ArgsDict.Add(kv.Key, kv.Value);
     }
     resSa.Tag = this.Tag;
     resSa.Type = this.Type;
     resSa.FuncName = this.FuncName;
     resSa.IsBelongFunc = this.IsBelongFunc;
     resSa.NodeName = this.NodeName;
     if (pureClone == false)
     {
         resSa.CondPolish = this.CondPolish;
         resSa.DialogDirtyBit = this.DialogDirtyBit;
         resSa.Next = this.Next;
         resSa.NodeName = this.NodeName;
         resSa.TrueRouting = new List<SceneAction>();
         foreach (var tr in this.TrueRouting)
         {
             resSa.TrueRouting.Add(tr);
         }
         resSa.FalseRouting = new List<SceneAction>();
         foreach (var fr in this.FalseRouting)
         {
             resSa.FalseRouting.Add(fr);
         }
     }
     return resSa;
 }
示例#3
0
 /// <summary>
 /// 将动作序列绑定到一个新的场景函数
 /// </summary>
 /// <param name="funcSa">动作序列</param>
 /// <returns>场景函数</returns>
 private SceneFunction ConstructSceneFunction(SceneAction funcSa)
 {
     if (funcSa.IsBelongFunc != true)
     {
         throw new InterpreterException()
         {
             Message = "一个非函数节点被作为函数声明处理",
             HitLine = Convert.ToInt32((funcSa.Tag.Split('-'))[0]),
             HitColumn = Convert.ToInt32((funcSa.Tag.Split('-'))[1]),
             HitPhase = InterpreterException.InterpreterPhase.Sematicer,
             SceneFileName = this.scenario
         };
     }
     // 获得函数签名
     string signature = funcSa.ArgsDict["sign"];
     string[] signItem = signature.Split(new char[] {'(', ')'}, StringSplitOptions.RemoveEmptyEntries);
     if (signItem.Length < 1 || !IsSymbol(signItem[0].Trim()))
     {
         throw new InterpreterException()
         {
             Message = "函数签名不合法",
             HitLine = Convert.ToInt32((funcSa.Tag.Split('-'))[0]),
             HitColumn = Convert.ToInt32((funcSa.Tag.Split('-'))[1]),
             HitPhase = InterpreterException.InterpreterPhase.Sematicer,
             SceneFileName = this.scenario
         };
     }
     List<string> funcParas = new List<string>();
     // 如果没有参数就跳过参数遍历
     if (signItem.Length > 1)
     {
         string[] varItem = signItem[1].Split(new char[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
         foreach (string ivar in varItem)
         {
             if (ivar.StartsWith("$") && IsSymbol(ivar.Substring(1)))
             {
                 funcParas.Add(ivar);
             }
             else
             {
                 throw new InterpreterException()
                 {
                     Message = "函数签名的参数列表不合法",
                     HitLine = Convert.ToInt32((funcSa.Tag.Split('-'))[0]),
                     HitColumn = Convert.ToInt32((funcSa.Tag.Split('-'))[1]),
                     HitPhase = InterpreterException.InterpreterPhase.Sematicer,
                     SceneFileName = this.scenario
                 };
             }
         }
     }
     return new SceneFunction(signItem[0].Trim(), this.scenario, funcSa);
 }
示例#4
0
 /// <summary>
 /// 递归遍历动作序列,回填控制流程,进行代码优化
 /// </summary>
 /// <param name="saNode">要处理的动作序列头部</param>
 /// <param name="parent">当前序列头部的双亲</param>
 /// <param name="funcFlag">函数序列标记</param>
 /// <returns>函数实例</returns>
 private SceneFunction BackpatchOptimizer(SceneAction saNode, SceneAction parent, bool funcFlag)
 {
     switch (saNode.Type)
     {
         case SActionType.NOP:
         case SActionType.act_function:
             if (saNode.TrueRouting == null || saNode.TrueRouting.Count == 0)
             {
                 break;
             }
             // 递归访问子节点
             for (int i = 0; i < saNode.TrueRouting.Count - 1; i++)
             {
                 this.BackpatchOptimizer(saNode.TrueRouting[i], saNode, false);
             }
             // 清理要移除的节点
             while (this.removeQueueDict.ContainsKey(saNode) && this.removeQueueDict[saNode].Count != 0)
             {
                 saNode.TrueRouting.Remove(this.removeQueueDict[saNode].Dequeue());
             }
             // 最后一个孩子的下一节点修改为它母节点的后继
             SceneAction lastNop = saNode.TrueRouting[saNode.TrueRouting.Count - 1];
             if (lastNop.Type != SActionType.act_break && lastNop.Type != SActionType.act_endfor)
             {
                 this.BackpatchOptimizer(lastNop, saNode, false);
                 lastNop.Next = saNode.Next;
             }
             else
             {
                 this.BackpatchOptimizer(lastNop, saNode, false);
             }
             break;
         case SActionType.act_dialog:
             // 合并dialog项
             if (saNode.DialogDirtyBit) { break; }
             SceneAction basePtr = saNode;
             SceneAction iterPtr = saNode;
             string dialogBuilder = iterPtr.Tag;
             iterPtr = iterPtr.Next;
             // 有可能是最后一个孩子递归时DT已经被移除了
             if (iterPtr == null)
             {
                 break;
             }
             if (this.removeQueueDict.ContainsKey(parent) == false)
             {
                 this.removeQueueDict[parent] = new Queue<SceneAction>();
             }
             while (iterPtr.Type != SActionType.act_dialogTerminator)
             {
                 iterPtr.DialogDirtyBit = true;
                 dialogBuilder += iterPtr.Tag;
                 this.removeQueueDict[parent].Enqueue(iterPtr);
                 iterPtr = iterPtr.Next;
             }
             this.removeQueueDict[parent].Enqueue(iterPtr);
             if (iterPtr.Next != null &&
                 (iterPtr.Next.Type == SActionType.act_dialog ||
                 iterPtr.Next.Type == SActionType.act_a))
             {
                 dialogBuilder += "#1";
             }
             else
             {
                 dialogBuilder += "#0";
             }
             basePtr.Tag = dialogBuilder;
             basePtr.Next = iterPtr.Next;
             break;
         case SActionType.act_dialogTerminator:
             // 处理对话继续标志位
             if (saNode.Next != null &&
                 (saNode.Next.Type == SActionType.act_dialog ||
                 saNode.Next.Type == SActionType.act_a))
             {
                 saNode.Tag += "#1";
             }
             else
             {
                 saNode.Tag += "#0";
             }
             break;
         case SActionType.act_for:
             this.forStack.Push(saNode);
             if (saNode.TrueRouting == null || saNode.TrueRouting.Count == 0)
             {
                 break;
             }
             // 递归访问子节点
             for (int i = 0; i < saNode.TrueRouting.Count - 1; i++)
             {
                 this.BackpatchOptimizer(saNode.TrueRouting[i], saNode, false);
             }
             // 清理要移除的节点
             while (this.removeQueueDict.ContainsKey(saNode) && this.removeQueueDict[saNode].Count != 0)
             {
                 saNode.TrueRouting.Remove(this.removeQueueDict[saNode].Dequeue());
             }
             // 最后一个孩子的下一节点修改为for子句本身
             SceneAction lastFor = saNode.TrueRouting[saNode.TrueRouting.Count - 1];
             if (lastFor.Type != SActionType.act_break && lastFor.Type != SActionType.act_endfor)
             {
                 lastFor.Next = saNode.Next;
             }
             else
             {
                 this.BackpatchOptimizer(lastFor, saNode, false);
             }
             break;
         case SActionType.act_endfor:
             // endfor节点的下一节点是她的for母节点
             saNode.Next = parent;
             // 弹for结构栈
             this.forStack.Pop();
             break;
         case SActionType.act_return:
             // 下一节点是null,这样运行时环境就会弹栈
             saNode.Next = null;
             break;
         case SActionType.act_break:
             // break节点的下一节点是她的for母节点的后继
             if (this.forStack.Count > 0)
             {
                 saNode.Next = this.forStack.Peek().Next;
             }
             else
             {
                 throw new InterpreterException("break必须存在for结构的内部");
             }
             break;
         case SActionType.act_if:
             // 处理真分支
             if (saNode.TrueRouting == null || saNode.TrueRouting.Count == 0)
             {
                 break;
             }
             // 递归访问子节点
             for (int i = 0; i < saNode.TrueRouting.Count - 1; i++)
             {
                 this.BackpatchOptimizer(saNode.TrueRouting[i], saNode, false);
             }
             // 清理要移除的节点
             while (this.removeQueueDict.ContainsKey(saNode) && this.removeQueueDict[saNode].Count != 0)
             {
                 saNode.TrueRouting.Remove(this.removeQueueDict[saNode].Dequeue());
             }
             // 最后一个孩子的下一节点修改为if子句节点的后继
             SceneAction lastIfTrue = saNode.TrueRouting[saNode.TrueRouting.Count - 1];
             // 考虑要更变next属性的节点
             if (lastIfTrue.Type != SActionType.act_break
                 && lastIfTrue.Type != SActionType.act_endfor
                 && lastIfTrue.Type != SActionType.act_return)
             {
                 lastIfTrue.Next = saNode.Next;
             }
             else
             {
                 this.BackpatchOptimizer(lastIfTrue, saNode, false);
             }
             // 处理假分支
             if (saNode.FalseRouting == null || saNode.FalseRouting.Count == 0)
             {
                 break;
             }
             // 递归访问子节点
             for (int i = 0; i < saNode.FalseRouting.Count - 1; i++)
             {
                 this.BackpatchOptimizer(saNode.FalseRouting[i], saNode, false);
             }
             // 清理要移除的节点
             while (this.removeQueueDict.ContainsKey(saNode) && this.removeQueueDict[saNode].Count != 0)
             {
                 saNode.FalseRouting.Remove(this.removeQueueDict[saNode].Dequeue());
             }
             // 最后一个孩子的下一节点修改为if子句节点的后继
             SceneAction lastIfFalse = saNode.FalseRouting[saNode.FalseRouting.Count - 1];
             // 考虑要更变next属性的节点
             if (lastIfFalse.Type != SActionType.act_break
                 && lastIfFalse.Type != SActionType.act_endfor
                 && lastIfFalse.Type != SActionType.act_return)
             {
                 lastIfFalse.Next = saNode.Next;
             }
             else
             {
                 this.BackpatchOptimizer(lastIfFalse, saNode, false);
             }
             break;
         default:
             break;
     }
     // 如果是函数序列就返回一个函数实例
     SceneFunction retSF = null;
     if (funcFlag)
     {
         retSF = this.ConstructSceneFunction(saNode);
     }
     // 最后让递归过程去修改子节点的属性
     saNode.IsBelongFunc = funcFlag;
     return retSF;
 }
示例#5
0
 /// <summary>
 /// 递归遍历抽象语法树,构造动作序列
 /// </summary>
 /// <param name="mynode">递归节点</param>
 /// <param name="curSa">当前场景的动作序列头部</param>
 /// <param name="funcSaVec">依附在该场景下的函数的动作序列向量</param>
 private void AST(SyntaxTreeNode mynode, ref SceneAction curSa, List<SceneAction> funcSaVec)
 {
     // 设置SA的行列属性
     if (curSa != null)
     {
         curSa.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
     }
     // 自顶向下递归遍历语法树
     switch (mynode.NodeSyntaxType)
     {
         case SyntaxType.case_kotori:
             // 如果是总的根节点
             if (curSa == null)
             {
                 curSa = new SceneAction();
                 curSa.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
             }
             if (mynode.Children == null)
             {
                 break;
             }
             List<SceneAction> kotoriTrueList = new List<SceneAction>();
             curSa.TrueRouting = kotoriTrueList;
             // 递归遍历
             foreach (SyntaxTreeNode child in mynode.Children)
             {
                 SceneAction sa = new SceneAction();
                 sa.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
                 sa.Type = (SActionType)Enum.Parse(typeof(SActionType), "act_" + child.NodeSyntaxType.ToString().Replace("synr_", ""));
                 // 跳过增广文法节点,拷贝参数字典
                 if (child.NodeSyntaxType.ToString().StartsWith("synr_")
                     && child.ParamDict != null)
                 {
                     foreach (KeyValuePair<string, SyntaxTreeNode> kvp in child.ParamDict)
                     {
                         if (kvp.Value.Children != null)
                         {
                             sa.ArgsDict.Add(kvp.Key, this.Folding(this.ConstructArgPolish(kvp.Value.Children[0]), mynode));
                         }
                         else
                         {
                             sa.ArgsDict.Add(kvp.Key, "");
                         }
                     }
                 }
                 // 如果不是函数定义的话递归就这个孩子,加到真分支去
                 if (child.NodeSyntaxType != SyntaxType.synr_function)
                 {
                     kotoriTrueList.Add(sa);
                 }
                 this.AST(child, ref sa, funcSaVec);
             }
             // 处理序列关系
             for (int i = 0; i < kotoriTrueList.Count - 1; i++)
             {
                 kotoriTrueList[i].Next = kotoriTrueList[i + 1];
             }
             break;
         case SyntaxType.synr_if:
             // 处理条件指针
             curSa.CondPolish = this.Folding(this.ConstructArgPolish(mynode.ParamDict["cond"]), mynode);
             // 处理真分支
             curSa.TrueRouting = new List<SceneAction>();
             if (mynode.Children[0] == null)
             {
                 break;
             }
             SceneAction saIfTrue = new SceneAction();
             saIfTrue.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
             this.AST(mynode.Children[0], ref saIfTrue, funcSaVec);
             for (int i = 0; i < saIfTrue.TrueRouting.Count; i++)
             {
                 curSa.TrueRouting.Add(saIfTrue.TrueRouting[i]);
             }
             // 处理假分支
             curSa.FalseRouting = new List<SceneAction>();
             if (mynode.Children[1] == null || (mynode.Children[1].NodeSyntaxType == SyntaxType.synr_endif))
             {
                 break;
             }
             SceneAction saIfFalse = new SceneAction();
             saIfFalse.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
             this.AST(mynode.Children[1], ref saIfFalse, funcSaVec);
             for (int i = 0; i < saIfFalse.TrueRouting.Count; i++)
             {
                 // 这里之所以是trueRouting是因为kotori节点的缘故
                 curSa.FalseRouting.Add(saIfFalse.TrueRouting[i]);
             }
             break;
         case SyntaxType.synr_for:
             // 处理条件指针
             if (mynode.ParamDict.ContainsKey("cond"))
             {
                 curSa.CondPolish = this.Folding(this.ConstructArgPolish(mynode.ParamDict["cond"]), mynode);
             }
             // 处理真分支
             curSa.TrueRouting = new List<SceneAction>();
             if (mynode.Children[0] == null)
             {
                 break;
             }
             SceneAction saForTrue = new SceneAction();
             saForTrue.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
             this.AST(mynode.Children[0], ref saForTrue, funcSaVec);
             for (int i = 0; i < saForTrue.TrueRouting.Count; i++)
             {
                 curSa.TrueRouting.Add(saForTrue.TrueRouting[i]);
             }
             break;
         case SyntaxType.synr_function:
             // 处理真分支
             if (mynode.Children[0] == null)
             {
                 break;
             }
             SceneAction saFuncTrue = new SceneAction();
             saFuncTrue.Tag = mynode.Line.ToString() + "-" + mynode.Column.ToString();
             curSa.TrueRouting = new List<SceneAction>();
             this.AST(mynode.Children[0], ref saFuncTrue, funcSaVec);
             for (int i = 0; i < saFuncTrue.TrueRouting.Count; i++)
             {
                 curSa.TrueRouting.Add(saFuncTrue.TrueRouting[i]);
             }
             curSa.IsBelongFunc = true;
             // 加到函数向量里
             funcSaVec.Add(curSa);
             break;
         case SyntaxType.synr_label:
             string labelKey = mynode.ParamDict["name"].Children[0].NodeValue;
             curSa.Tag = labelKey;
             this.blockDict[labelKey] = curSa;
             break;
         case SyntaxType.synr_jump:
             break;
         case SyntaxType.synr_dialog:
             curSa.Tag = mynode.NodeValue;
             break;
         default:
             break;
     }
     // 给节点命名
     curSa.NodeName = String.Format("{0}_{1}@{2}", this.scenario, mynode.Line, curSa.Type.ToString());
 }
示例#6
0
 /// <summary>
 /// 将动作序列和从属于它的动作序列全部IL化
 /// </summary>
 /// <param name="saRoot">递归开始节点</param>
 /// <returns>IL字符串</returns>
 private string ILGenerator(SceneAction saRoot)
 {
     StringBuilder resSb = new StringBuilder("");
     Stack<SceneAction> processStack = new Stack<SceneAction>();
     processStack.Push(saRoot);
     while (processStack.Count != 0)
     {
         SceneAction topSa = processStack.Pop();
         // 栈,先处理falseRouting
         if (topSa.FalseRouting != null)
         {
             for (int i = topSa.FalseRouting.Count - 1; i >= 0; i--)
             {
                 processStack.Push(topSa.FalseRouting[i]);
             }
         }
         // 处理trueRouting
         if (topSa.TrueRouting != null)
         {
             for (int i = topSa.TrueRouting.Count - 1; i >= 0; i--)
             {
                 processStack.Push(topSa.TrueRouting[i]);
             }
         }
         resSb.AppendLine(topSa.ToIL());
     }
     return resSb.ToString();
 }
示例#7
0
 /// <summary>
 /// 构造器
 /// </summary>
 /// <param name="scenario">场景名称</param>
 /// <param name="mainSa">主动作序列</param>
 /// <param name="funcVec">函数向量</param>
 public PackageScene(string scenario, SceneAction mainSa, List<SceneFunction> funcVec)
 {
     this.Scenario = scenario;
     this.Ctor = mainSa;
     this.FuncContainer = funcVec;
 }