// 返回一个做数据容器的block(可以作为数据容器,并包括tokens信息) public IBlock GetBlock(String blockName) { if (_isTemplateExist == false) { throw new Exception(lang.get("exTemplateNotExist")); } BlockToken blockToken = getBlockToken(blockName); if (blockToken == null) { throw new Exception(lang.get("exBlockExist") + ":" + blockName); } ContentBlock block = new ContentBlock(); block.Name = blockName; block._thisToken = blockToken; // 将上级变量放入下级循环可用 block._blockData = new BlockData(_blockData.getDic()); _blockData.addBlock(block); return(block); }
/// <summary> /// Defines a child conditional token for replacement. /// </summary> /// <typeparam name="TChild"></typeparam> /// <param name="replacement"></param> /// <param name="identifier"></param> /// <param name="condition"></param> /// <param name="context"></param> /// <returns></returns> public IConditionalToken <TModel, TChild> TokenizeIf <TChild>(Func <TModel, TChild> replacement, string identifier, Func <TModel, bool> condition, ITokenRoot <TChild> context) { Ensure.ArgumentNotNull(replacement, "replacement"); Ensure.ArgumentNotNullOrEmpty(identifier, "identifier"); Ensure.ArgumentNotNull(condition, "condition"); Ensure.ArgumentNotNull(context, "context"); var blockToken = new BlockToken <TModel, TChild> { Child = replacement, Resolve = p => string.Empty, Identifier = string.Intern(identifier), Condition = condition }; _currentToken = blockToken; Token.Children.Add(_currentToken); foreach (var token in context.Token.Children) { _currentToken.AddChild(token); } return(new TokenBlockBuilder <TModel, TChild>(_currentToken)); }
/// <summary> /// 返回一个做数据容器的block(可以作为数据容器,并包括tokens信息) /// </summary> /// <param name="blockName"></param> /// <returns></returns> public IBlock GetBlock(String blockName) { if (_isTemplateExist == false) { throw new TemplateException(lang.get("exTemplateNotExist") + ": " + _templatePath); } BlockToken blockToken = getBlockToken(blockName); if (blockToken == null) { throw new TemplateException( string.Format(lang.get("exBlockExist"), blockName, _templatePath, "<!-- BEGIN " + blockName + " -->") ); } ContentBlock block = new ContentBlock(); block.Name = blockName; block._thisToken = blockToken; block._templatePath = _templatePath; // 将上级变量放入下级循环可用 block._blockData = new BlockData(_blockData.getDic()); _blockData.addBlock(block); return(block); }
private IToken Tokenize(MethodDefinition method) { if (method.IsExcluded) { return(NullToken.Instance); } LineToken header = TokenizeHeader(method); IToken methodToken; if (method.IsExtern) { methodToken = new LinesToken(new LineToken[] { new LineToken("[DllImport(Native.Dll, CallingConvention = Native.Conv)]"), header }); } else { IList <IToken> bodyTokens = TokenizeBody(method); methodToken = new BlockToken(header, bodyTokens); } return(methodToken); }
public virtual Token getToken() { BlockToken token = new BlockToken(); token.setName(sbname.ToString()); token.setTokens(_tokens); return(token); }
/// <summary> /// 转为Lambda条件树 /// </summary> /// <param name="px"></param> /// <param name="block"></param> /// <returns></returns> private static Expression?ConvertToExpression(ParameterExpression px, BlockToken block) { Expression?exp = default; foreach (var item in block.Items) { if (item is ItemToken it) { var left = Expression.Property(px, it.Field); var right = Expression.Constant(ObjFilterConvertHelper.ConvertObject(left.Type, it.Value ?? string.Empty), left.Type); Expression binary = it.Compare switch { "=" => Expression.Equal(left, right), "!=" => Expression.NotEqual(left, right), "<" => Expression.LessThan(left, right), "<=" => Expression.LessThanOrEqual(left, right), ">" => Expression.GreaterThan(left, right), ">=" => Expression.GreaterThanOrEqual(left, right), _ => Expression.Call(left, left.Type.GetMethod(nameof(string.Contains), new[] { typeof(string) }) !, right), }; if (exp == default) { exp = binary; } else { exp = it.Logic switch { ConstantOptions.LogicConstant.Or => Expression.OrElse(exp, binary), ConstantOptions.LogicConstant.And => Expression.AndAlso(exp, binary), _ => Expression.AndAlso(exp, binary) }; } } else if (item is BlockToken bk) { var binary = ConvertToExpression(px, bk) ?? throw new HandelException(MessageCodeOption.Bad_002, "语法错误"); if (exp == default) { exp = binary; } else { exp = bk.Logic switch { ConstantOptions.LogicConstant.Or => Expression.OrElse(exp, binary), ConstantOptions.LogicConstant.And => Expression.AndAlso(exp, binary), _ => Expression.AndAlso(exp, binary) }; } } } return(exp); }
/// <summary> /// 语法分析(转为树结构) /// </summary> private static BlockToken NextToken(List <WorkToken> works, ref int index) { var block = new BlockToken(); string? blockLogic = default; ItemToken?currItem = default; while (index < works.Count) { var item = works[index]; var back = index < 1 ? works[0] : works[index - 1]; //上一个 var next = index == works.Count - 1 ? works[^ 1] : works[index + 1]; //下一个
public void custom_naming_strategy() { var name = new BlockToken("test"); var strategy = MockRepository.GenerateStub <IBlockNamingStrategy>(); strategy.Stub(x => x.Matches(name)).Return(true); var registry = new BlockRegistry(new[] { strategy }); registry.NamingStrategyFor(name).ShouldBeTheSameAs(strategy); }
public void default_naming_strategy() { var name = new BlockToken("test"); var strategy = MockRepository.GenerateStub <IBlockNamingStrategy>(); strategy.Stub(x => x.Matches(name)).Return(false); var registry = new BlockRegistry(new[] { strategy }); registry.NamingStrategyFor(name).ShouldBeOfType <DefaultBlockNamingStrategy>(); }
/// <summary> /// Closes the block using the provided close tag /// </summary> /// <param name="processor">The processor</param> /// <param name="token">The open tag</param> /// <param name="closeToken">the closing tag</param> /// <param name="content">the content the tags were parsed from</param> public override void EndBlock(Processor processor, BlockToken token, BlockCloseToken closeToken, StringSlice content) { var sectionEndTag = closeToken as SectionEndToken; if (token is InvertedSectionToken sectionTag && sectionEndTag != null) { if (sectionTag.SectionName.Equals(sectionEndTag.SectionName)) { sectionTag.Tags = processor.CurrentTags; sectionTag.EndPosition = sectionEndTag.EndPosition; sectionTag.IsClosed = true; } } }
/// <summary> /// Try to create a block close tag /// </summary> /// <param name="processor">The processor</param> /// <param name="slice">the slice</param> /// <param name="token">the current block tag</param> /// <returns>If the close was successful</returns> public override bool TryClose(Processor processor, ref StringSlice slice, BlockToken token) { var sectionTag = (SectionToken)token; while (slice.CurrentChar.IsWhitespace()) { slice.NextChar(); } var blockStart = slice.Start - processor.CurrentTags.StartTag.Length; slice.Start = slice.Start + 1; // Skip the slash while (slice.CurrentChar.IsWhitespace()) { slice.NextChar(); } var startIndex = slice.Start; // Take characters until closing tag while (!slice.IsEmpty && !slice.Match(processor.CurrentTags.EndTag)) { slice.NextChar(); } var sectionName = slice.ToString(startIndex, slice.Start).TrimEnd(); if (sectionTag.SectionName == sectionName) { var tagEnd = slice.Start + processor.CurrentTags.EndTag.Length; var endTag = new SectionEndToken { SectionName = sectionName, EndPosition = tagEnd, ContentEndPosition = blockStart, IsClosed = true }; processor.CurrentToken = endTag; slice.Start += processor.CurrentTags.EndTag.Length; return(true); } throw new StubbleException($"Cannot close Block '{sectionName}' at {blockStart}. There is already an unclosed Block '{sectionTag.SectionName}'"); }
/// <summary> /// Close the block with the given block close tag /// </summary> /// <param name="processor">The processor</param> /// <param name="token">The open tag</param> /// <param name="closeToken">the closing tag</param> /// <param name="content">the content the tags were parsed from</param> public override void EndBlock(Processor processor, BlockToken token, BlockCloseToken closeToken, StringSlice content) { var sectionEndTag = closeToken as SectionEndToken; if (token is SectionToken sectionTag && sectionEndTag != null) { if (sectionTag.SectionName.Equals(sectionEndTag.SectionName)) { sectionTag.Tags = processor.CurrentTags; sectionTag.EndPosition = sectionEndTag.EndPosition; sectionTag.ContentEndPosition = sectionEndTag.ContentEndPosition; sectionTag.IsClosed = true; sectionTag.SectionContent = new StringSlice(content.Text, sectionTag.ContentStartPosition, sectionTag.ContentEndPosition - 1); } } }
private IToken Tokenize(PropertyDefinition property) { if (property.Setter == null) { var expressionBody = new ExpressionBodyToken(new LineToken(new IToken[] { new WordToken($"public {property.Getter.ReturnType} {property.Name} =>"), new WordToken($"{property.Getter.Parent.Name}_{property.Getter.Name}(Native);") })); return(expressionBody); } var header = new LineToken($"public {property.Getter.ReturnType} {property.Name}"); var propertyToken = new BlockToken(header, new IToken[] { new LineToken($"get => {property.Getter.Parent.Name}_{property.Getter.Name}(Native);"), new LineToken($"set => {property.Setter.Parent.Name}_{property.Setter.Name}(Native, value);") }); return(propertyToken); }
private BlockToken TokenizeNamespace(NamespaceTreeNode node) { string name; if (node.Children.Count == 1 && node.Nodes.Count == 0) { var child = node.Children[0]; if (node.Namespace.IsGlobal) { name = child.Namespace.Name; } else { name = $"{node.Namespace.Name}.{child.Namespace.Name}"; } node = child; } else { name = node.Namespace.Name; } LineToken header = new LineToken($"namespace {name}"); var children = new List <IToken>(); foreach (ModelNodeDefinition childNode in node.Nodes) { IToken childToken = TokenizeNode(childNode); children.Add(childToken); } foreach (var childNamespace in node.Children) { IToken childNamespaceToken = TokenizeNamespace(childNamespace); children.Add(childNamespaceToken); } BlockToken @namespace = new BlockToken(header, children); return(@namespace); }
private void WriteBlock(BlockToken block) { WriteToken(block.Header); WriteIndent(); _writer.WriteLine('{'); _indent++; IToken precedingToken = null; foreach (IToken child in block.Children) { WriteToken(child, precedingToken); precedingToken = child; } _indent--; WriteIndent(); _writer.WriteLine('}'); }
/// <summary> /// Renders the block with the given context /// </summary> /// <param name="block">The block to render</param> /// <param name="context">The context to write the block with</param> /// <returns>A list of tokens in the scope</returns> public override object Render(BlockToken block, CompilerContext context) { Scopes.Push(new List <Expression>()); foreach (var tag in block.Children) { currentDepth++; if (currentDepth >= MaxDepth) { throw new StubbleException( $"You have reached the maximum recursion limit of {MaxDepth}."); } Write(tag, context); currentDepth--; } var scope = Scopes.Pop(); return(scope); }
internal Block(BlockToken item) { BlockType = item.BlockType; switch (BlockType) { case BlockTypes.TAB: ElementList = new Element(item.ElementList); break; case BlockTypes.SELECTION: break; case BlockTypes.SETTINGS: SettingList = new Attribute(item.SettingList); break; case BlockTypes.CONTENT: Value = item.Value; break; default: break; } }
/// <summary> /// Defines a child block of tokens. /// </summary> /// <typeparam name="TChild"></typeparam> /// <param name="children"></param> /// <param name="identifier"></param> /// <param name="context"></param> /// <returns></returns> public ITokenBlock <TModel, TChild> Block <TChild>(Func <TModel, IEnumerable <TChild> > children, string identifier, ITokenRoot <TChild> context) { Ensure.ArgumentNotNull(children, "children"); Ensure.ArgumentNotNullOrEmpty(identifier, "identifier"); Ensure.ArgumentNotNull(context, "context"); var blockToken = new BlockToken <TModel, TChild> { Resolve = p => string.Empty, Identifier = string.Intern(identifier), Items = model => GetEachChild(model, children) }; _currentToken = blockToken; Token.Children.Add(_currentToken); foreach (var token in context.Token.Children) { _currentToken.AddChild(token); } return(new TokenBlockBuilder <TModel, TChild>(_currentToken)); }
public IToken Tokenize(ModelNodeDefinition node) { var @enum = (EnumDefinition)node; var definition = new LineToken($"public enum {@enum.Name}"); IToken headerToken; if (@enum.IsFlags()) { headerToken = new LinesToken(new LineToken[] { new LineToken("[Flags]"), definition } ); } else { headerToken = definition; } var enumerators = new List <IToken>(); var lastEnumerator = @enum.Enumerators.Last(); foreach (EnumeratorDefinition enumerator in @enum.Enumerators) { string comma = enumerator == lastEnumerator ? "" : ","; string enumeratorLine = enumerator.Value != null ? $"{enumerator.Name} = {enumerator.Value}{comma}" : enumerator.Name + comma; enumerators.Add(new LineToken(enumeratorLine)); } BlockToken enumToken = new BlockToken(headerToken, enumerators); return(enumToken); }
internal void Reset() { _tokenStack = new List<Token>(); _stateStack = new List<int>(); _tokenStack.Add(new Token(0, null, TokenType.Bracket)); _stateStack.Add(0); _blockToken = null; IsLoopingForReduce = false; IsAccepted = false; }
internal void Push(Token token) { int wordtype; switch (token.Type) { case TokenType.Number: case TokenType.Boolean: wordtype = (int)TokenType.String; break; default: wordtype = (int)token.Type; break; } var action = _action[_stateStack[_stateStack.Count - 1]][wordtype]; if (action == null) { IsLoopingForReduce = false; throw new ParseException($"Grammar error at line {token.Line}"); } else if (action[0] == 'A') { IsAccepted = true; IsLoopingForReduce = false; switch (action[1]) { case '1'://ACC for elements var blocktype = (BlockTypes)System.Enum.Parse(typeof(BlockTypes), _tokenStack[1].Value); _blockToken = new BlockToken(blocktype, _tokenStack[_tokenStack.Count - 1] as ElementToken); break; case '2'://ACC for settings _blockToken = new BlockToken(_tokenStack[_tokenStack.Count - 1] as AttributeToken); break; case '3'://ACC for content _blockToken = new BlockToken(_tokenStack[_tokenStack.Count - 1].Value); break; } Block = new Block(_blockToken); } else if (action[0] == 'S') { var statestring = ""; for (var i = 1; i < action.Length; i++) { statestring += action[i]; } var nextstate = int.Parse(statestring); _stateStack.Add(nextstate); _tokenStack.Add(token); IsLoopingForReduce = false; } else { IsLoopingForReduce = true; var reducestring = ""; for (var i = 1; i < action.Length; i++) { reducestring += action[i]; } var reducerule = int.Parse(reducestring); switch (reducerule) { //case 1:// Block -> Type Bracket Elements Bracket // break; //case 2:// Block -> Settings // break; //case 3:// Block -> Content // break; case 4:// Elements -> Element _stateStack[_stateStack.Count - 1] = _goto[_stateStack[_stateStack.Count - 2]][2]; break; case 5:// Elements -> Elements Element var nextele = _tokenStack[_tokenStack.Count - 1] as ElementToken; var preele = _tokenStack[_tokenStack.Count - 2] as ElementToken; Debug.Assert(nextele != null, "nextele != null"); nextele.Next = preele; _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(nextele); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][2]); break; case 6:// Element -> Sharp Ename Equals Value Break var eName = _tokenStack[_tokenStack.Count - 4].Value; var eType = (ElementTypes)System.Enum.Parse(typeof(ElementTypes), eName); var setele = new ElementToken(_tokenStack[_tokenStack.Count - 5].Line, eType, _tokenStack[_tokenStack.Count - 2].Value); _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(setele); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][3]); break; case 7:// Element -> EName Bracket Atts Bracket var elementName = _tokenStack[_tokenStack.Count - 4].Value; var elementType = (ElementTypes)System.Enum.Parse(typeof(ElementTypes), elementName); var atts = _tokenStack[_tokenStack.Count - 2] as AttributeToken; Debug.Assert(atts != null, "atts != null"); var element = new ElementToken(atts.Line, elementType, atts); _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(element); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][3]); break; case 8:// Settings -> Setting _stateStack[_stateStack.Count - 1] = _goto[_stateStack[_stateStack.Count - 2]][0]; break; case 9:// Settings -> Settings Setting var nextset = _tokenStack[_tokenStack.Count - 1] as AttributeToken; var preset = _tokenStack[_tokenStack.Count - 2] as AttributeToken; Debug.Assert(nextset != null, "nextset != null"); nextset.Next = preset; _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(nextset); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][0]); break; //case 10:// Content -> USD Value Break // break; case 11:// Setting -> Sharp Att _tokenStack.RemoveAt(_tokenStack.Count - _popCount[reducerule - 1]); _stateStack.RemoveAt(_stateStack.Count - _popCount[reducerule - 1]); _stateStack[_stateStack.Count - 1] = _goto[_stateStack[_stateStack.Count - 2]][1]; break; case 12:// Atts -> Att _stateStack[_stateStack.Count - 1] = _goto[_stateStack[_stateStack.Count - 2]][4]; break; case 13:// Atts -> Atts Att var nextatt = _tokenStack[_tokenStack.Count - 1] as AttributeToken; var preatt = _tokenStack[_tokenStack.Count - 2] as AttributeToken; Debug.Assert(nextatt != null, "nextatt != null"); nextatt.Next = preatt; _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(nextatt); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][4]); break; case 14:// Att -> Name Equals Value Break AttributeValueType valueType = AttributeValueType.String; switch (_tokenStack[_tokenStack.Count - 2].Type) { case TokenType.Number: valueType = AttributeValueType.Number; break; case TokenType.Boolean: valueType = AttributeValueType.Boolean; break; } AttributeTypes attType = (AttributeTypes)System.Enum.Parse(typeof(AttributeTypes), _tokenStack[_tokenStack.Count - 4].Value); AttributeToken att = new AttributeToken ( _tokenStack[_tokenStack.Count - 2].Line, attType, _tokenStack[_tokenStack.Count - 2].Value, valueType ); _tokenStack.RemoveRange(_tokenStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _stateStack.RemoveRange(_stateStack.Count - _popCount[reducerule - 1], _popCount[reducerule - 1]); _tokenStack.Add(att); _stateStack.Add(_goto[_stateStack[_stateStack.Count - 1]][5]); break; } } }
/// <summary> /// Renders a block tag /// </summary> /// <param name="token">The block tag to render</param> /// <param name="context">The context to write the tag with</param> /// <returns>The current renderer</returns> public abstract object Render(BlockToken token, Context context);
/// <summary> /// Renders a block tag /// </summary> /// <param name="token">The block tag to render</param> /// <param name="context">The context to write the tag with</param> /// <returns>The current renderer</returns> public abstract ValueTask <object> RenderAsync(BlockToken token, Context context);
/// <summary> /// Ends a block tag /// </summary> /// <param name="processor">The processor</param> /// <param name="token">The opening tag</param> /// <param name="closeToken">The closing tag</param> /// <param name="content">The contents the tag was parsed from</param> public abstract void EndBlock(Processor processor, BlockToken token, BlockCloseToken closeToken, StringSlice content);
/// <summary> /// Tries to close a block tag /// </summary> /// <param name="processor">The processor</param> /// <param name="slice">The string slice to parse</param> /// <param name="token">The tag to try and close</param> /// <returns>If the block was closed or not</returns> public abstract bool TryClose(Processor processor, ref StringSlice slice, BlockToken token);
public override void EndBlock(Processor processor, BlockToken token, BlockCloseToken closeToken, StringSlice content) { throw new System.NotImplementedException(); }
public string NameFor(BlockToken token) { var blockName = token.Value; return(blockName.Substring(0, 1).ToLower() + blockName.Substring(1)); }
public bool Matches(BlockToken token) { return(!token.IsEmpty()); }
public override bool TryClose(Processor processor, ref StringSlice slice, BlockToken token) { throw new System.NotImplementedException(); }
public string NameFor(BlockToken blockToken) { return(null); }