/// <summary> /// 编译模板 /// </summary> /// <param name="template"></param> /// <param name="output"></param> /// <returns></returns> public Expression <Action <DynamicModel> > Build(string template, OutPutProvide output) { var buffer = Encoding.UTF8.GetBytes(template); using var memory = new MemoryStream(buffer); using var reader = new StreamReader(memory); var scope = new ScopeBlockContext(); CreateNodeContextRange(reader, scope, output); scope.ConvertToExpression(); return(Expression.Lambda <Action <DynamicModel> >(scope.NdExpression, scope.Root)); }
/// <summary> /// 指定输出类创建表达式提供类 /// </summary> /// <param name="outPut"></param> public PrintExpressionProvide(OutPutProvide outPut) { _outPut = outPut; }
/// <summary> /// 将语法解析为节点树 /// </summary> /// <param name="reader"></param> /// <param name="ParentNode"></param> /// <param name="output"></param> private void CreateNodeContextRange(StreamReader reader, NodeBlockContext ParentNode, OutPutProvide output) { while (true) { string line = reader.ReadLine(); if (line == null) { return; } _lineNumber++; NodeType type = GetNodeType(line); NodeContext last = ParentNode.Nodes.LastOrDefault(); if (last?.NdType == NodeType.IF || last?.NdType == NodeType.ELSEIF) { if (type != NodeType.ELSEIF && type != NodeType.ELSE) { for (int i = ParentNode.Nodes.Count - 1; i >= 0; i--) { NodeContext item = ParentNode.Nodes[i]; if (item.NdType != NodeType.ELSEIF && item.NdType != NodeType.IF) { break; } item.ConvertToExpression(); } } } switch (type) { case NodeType.IF: NodeBlockContext block = new IFNodeContext(line, ParentNode, output); CreateNodeContextRange(reader, block, output); ParentNode.Nodes.Add(block); break; case NodeType.ELSEIF: block = new ELSEIFNodeContext(line, ParentNode, output); CreateNodeContextRange(reader, block, output); if (last is IFNodeContext ifnd1) { ifnd1.ELSENode = block; } else if (last is ELSEIFNodeContext elnd1) { elnd1.ELSENode = block; } else { throw new Exception($"第{_lineNumber}行语法错误,elseif必须在 if 或 elseif 之后"); } ParentNode.Nodes.Add(block); break; case NodeType.ELSE: block = new ELSENodeContext(line, ParentNode, output); CreateNodeContextRange(reader, block, output); block.ConvertToExpression(); if (last is IFNodeContext ifnd) { ifnd.ELSENode = block; } else if (last is ELSEIFNodeContext elnd) { elnd.ELSENode = block; } else { throw new Exception($"第{_lineNumber}行语法错误,else 必须在 if 或 elseif之后"); } for (int i = ParentNode.Nodes.Count - 1; i >= 0; i--) { NodeContext item = ParentNode.Nodes[i]; if (item.NdType != NodeType.ELSEIF && item.NdType != NodeType.IF) { break; } item.ConvertToExpression(); } ParentNode.Nodes.Add(block); break; case NodeType.EACH: block = new EACHNodeContext(line, ParentNode, output); CreateNodeContextRange(reader, block, output); block.ConvertToExpression(); ParentNode.Nodes.Add(block); break; case NodeType.PRINT: NodeContext node = new PRINTNodeContext(line, ParentNode, output); node.ConvertToExpression(); ParentNode.Nodes.Add(node); break; case NodeType.STRING: node = new STRINGNodeContext(line, ParentNode, output); node.ConvertToExpression(); ParentNode.Nodes.Add(node); break; case NodeType.SET: node = new SETNodeContext(line, ParentNode, output); node.ConvertToExpression(); ParentNode.Nodes.Add(node); break; case NodeType.OPER: node = new OperNodeContext(line, ParentNode, output); node.ConvertToExpression(); ParentNode.Nodes.Add(node); break; case NodeType.ENDIF: case NodeType.ENDELSEIF: case NodeType.ENDELSE: case NodeType.ENDEACH: return; default: throw new Exception($"{type}是不受支持的节点类型"); } } }