private List <Token> RemainTokensToArgs(TokenReader reader) { var result = new List <Token>(); while (reader.IsRemainToken) { var current = reader.Get(); if (current.IsMatchType(TokenType.TargetSelector)) { if (reader.CheckNext(x => x.IsMatchType(TokenType.OpenSquareBracket))) { reader.Skip(x => x.IsMatchType(TokenType.CloseSquareBracket)); reader.MoveNext(); } } else if (current.IsMatchLiteral("minecraft")) { if (reader.CheckNext(x => x.IsMatchType(TokenType.Colon))) { reader.MoveNext(); if (reader.CheckNext(x => x.IsMatchType(TokenType.Literal))) { current = reader.Get(); } else { continue; } } } result.Add(current); } return(result); }
public static (List <Node> nodes, int variableCount) Parse(string source) { var Nodes = new List <Node>(); var variables = new Dictionary <string, int>(); bool inExpression = false; NodeType currentMod = NodeType.NoOperation; Stack <Node> BlockLevel = new Stack <Node>(); using (TokenReader tr = new TokenReader(source)) { do { if (string.IsNullOrWhiteSpace(tr.Current())) { continue; } if (tr.EqualTo("if")) { BlockLevel.Push(new Node(NodeType.JumpNotTrue)); inExpression = true; } else if (tr.EqualTo("while")) { BlockLevel.Push(new Node(NodeType.JumpNotTrue, Nodes.Count)); inExpression = true; } else if (tr.EqualTo("is", "smaller", "then")) { currentMod = NodeType.Smaller; tr.MoveNext(2); } else if (tr.EqualTo("is", "larger", "then")) { currentMod = NodeType.Larger; tr.MoveNext(2); } else if (tr.EqualTo("then") || tr.EqualTo("loop")) { Nodes.Add(BlockLevel.Peek()); inExpression = false; } else if (tr.EqualTo("end")) { BlockLevel.Pop().A = Nodes.Count; Nodes.Add(new Node(NodeType.NoOperation)); } else if (tr.EqualTo("next")) { var lvl = BlockLevel.Pop(); Nodes.Add(new Node(NodeType.GoTo, lvl.A)); lvl.A = Nodes.Count; Nodes.Add(new Node(NodeType.NoOperation)); } else if (tr.EqualTo("increment")) { if (tr.MoveNext() && !tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.Increment, GetVarIndex(tr.Current(), variables))); } else { throw new Exception("Expected a variable after increment"); } } else if (tr.EqualTo("decrement")) { if (tr.MoveNext() && !tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.Decrement, GetVarIndex(tr.Current(), variables))); } else { throw new Exception("Expected a variable after increment"); } } else if (tr.EqualTo("write")) { if (tr.MoveNext()) { int index = -1; decimal value = 0; if (tr.IsNumberLiteral()) { value = tr.GetValue(); } else { index = GetVarIndex(tr.Current(), variables); } if (tr.MoveNext()) { if (tr.EqualTo("to", "the", "console")) { if (index == -1) { Nodes.Add(new Node(NodeType.LoadNumLiteralWriteConsole, value)); } else { Nodes.Add(new Node(NodeType.LoadLocalWriteConsole, index)); } tr.MoveNext(2); } } else { throw new Exception("Expected what to write to, after value!"); } } else { throw new Exception("Expected a value to write"); } } else if (tr.EqualTo("is", "not", "equal", "to")) { currentMod = NodeType.NotEqual; tr.MoveNext(3); } else if (tr.EqualTo("is", "equal", "to")) { currentMod = NodeType.Equal; tr.MoveNext(2); } else if (tr.EqualTo("a", "variable", "named")) { if (tr.MoveNext(3)) { Nodes.Add(new Node(NodeType.LoadLocal, GetVarIndex(tr.Current(), variables))); if (currentMod != NodeType.NoOperation) { Nodes.Add(new Node(currentMod)); currentMod = NodeType.NoOperation; } } else { throw new Exception("Expected name after a variable named"); } } else { if (inExpression) { if (tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.LoadNumLiteral, tr.GetValue())); } else { Nodes.Add(new Node(NodeType.LoadLocal, GetVarIndex(tr.Current(), variables))); } if (currentMod != NodeType.NoOperation) { Nodes.Add(new Node(currentMod)); currentMod = NodeType.NoOperation; } } else { int index = GetVarIndex(tr.Current(), variables); if (tr.MoveNext() && tr.EqualTo("equals")) { tr.MoveNext(); if (tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.LoadNumLiteralAndStoreLocal, index, tr.GetValue())); } else { Nodes.Add(new Node(NodeType.LoadLocalAndStoreLocal, index, GetVarIndex(tr.Current(), variables))); } } else { throw new Exception("Expected something after the variable"); } } } } while (tr.MoveNext()); } return(Nodes, variables.Count); }
protected ParserNode _HandleLevel_Op(Func <ParserNode> HandleLevelNext, string[] Operators, Func <ParserNode, ParserNode, String, ParserNode> HandleOperator) { return(_HandleLevel_OpBase(HandleLevelNext, Operators, delegate(ParserNode ParserNode, String Operator) { Tokens.MoveNext(); ParserNode RightNode = HandleLevelNext(); return HandleOperator(ParserNode, RightNode, Operator); })); }
public static void Main() { var Nodes = new List <Node>(); var variables = new Dictionary <string, int>(); string source = @" a equals 10 b equals 15 decrement b decrement b decrement b decrement b decrement b if a variable named a is not equal to a variable named b then a equals b end write a to the console "; Console.WriteLine(source); bool inExpression = false; NodeType currentMod = NodeType.NoOperation; Queue <Node> BlockLevel = new Queue <Node>(); using (TokenReader tr = new TokenReader(source)) { do { if (string.IsNullOrWhiteSpace(tr.Current())) { continue; } if (tr.EqualTo("if")) { BlockLevel.Enqueue(new Node(NodeType.JumpNotTrue)); inExpression = true; } else if (tr.EqualTo("then")) { Nodes.Add(BlockLevel.Peek()); inExpression = false; } else if (tr.EqualTo("end")) { BlockLevel.Dequeue().A = Nodes.Count; Nodes.Add(new Node(NodeType.NoOperation)); } else if (tr.EqualTo("increment")) { if (tr.MoveNext() && !tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.Increment, GetVarIndex(tr.Current(), variables))); } else { throw new Exception("Expected a variable after increment"); } } else if (tr.EqualTo("decrement")) { if (tr.MoveNext() && !tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.Decrement, GetVarIndex(tr.Current(), variables))); } else { throw new Exception("Expected a variable after increment"); } } else if (tr.EqualTo("write")) { if (tr.MoveNext()) { int index = -1; decimal value = 0; if (tr.IsNumberLiteral()) { value = tr.GetValue(); } else { index = GetVarIndex(tr.Current(), variables); } if (tr.MoveNext()) { if (tr.EqualTo("to", "the", "console")) { if (index == -1) { Nodes.Add(new Node(NodeType.LoadNumLiteralWriteConsole, value)); } else { Nodes.Add(new Node(NodeType.LoadLocalWriteConsole, index)); } tr.MoveNext(2); } } else { throw new Exception("Expected what to write to, after value!"); } } else { throw new Exception("Expected a value to write"); } } else if (tr.EqualTo("is", "not", "equal", "to")) { // Nodes.Add(new Node(NodeType.NotEqual)); currentMod = NodeType.NotEqual; tr.MoveNext(3); } else if (tr.EqualTo("is", "equal", "to")) { currentMod = NodeType.Equal; //Nodes.Add(new Node(NodeType.Equal)); tr.MoveNext(2); } else if (tr.EqualTo("a", "variable", "named")) { if (tr.MoveNext(3)) { Nodes.Add(new Node(NodeType.LoadLocal, GetVarIndex(tr.Current(), variables))); if (currentMod != NodeType.NoOperation) { Nodes.Add(new Node(currentMod)); currentMod = NodeType.NoOperation; } } else { throw new Exception("Expected name after a variable named"); } } else { if (inExpression) { if (tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.LoadNumLiteral, tr.GetValue())); } else { Nodes.Add(new Node(NodeType.LoadLocal, GetVarIndex(tr.Current(), variables))); } if (currentMod != NodeType.NoOperation) { Nodes.Add(new Node(currentMod)); currentMod = NodeType.NoOperation; } } else { int index = GetVarIndex(tr.Current(), variables); if (tr.MoveNext() && tr.EqualTo("equals")) { tr.MoveNext(); if (tr.IsNumberLiteral()) { Nodes.Add(new Node(NodeType.LoadNumLiteralAndStoreLocal, index, tr.GetValue())); } else { Nodes.Add(new Node(NodeType.LoadLocalAndStoreLocal, index, GetVarIndex(tr.Current(), variables))); } } else { throw new Exception("Expected something after the variable"); } } } } while (tr.MoveNext()); ExecuteNodes(Nodes, variables.Count); } }
protected ParserNode _HandleLevel_Op(Func <ParserNode> HandleLevelNext, string[] Operators, Func <ParserNode, ParserNode, String, ParserNode> HandleOperator) { ParserNode ParserNode = HandleLevelNext(); while (Tokens.HasMore) { switch (CurrentTokenType) { case "OperatorTemplateToken": string Operator = CurrentToken.Text; bool Found = false; foreach (var CurrentOperator in Operators) { if (Operator == CurrentOperator) { Tokens.MoveNext(); ParserNode RightNode = HandleLevelNext(); ParserNode = HandleOperator(ParserNode, RightNode, Operator); Found = true; break; } } if (!Found) { return(ParserNode); } break; default: return(ParserNode); } } return(ParserNode); }
private IEnumerable <CompletionData> GetCompletionData(int index, string input) { if (!HandleInputStrings.Contains(input)) { return(null); } var block = this._bracketSearcher.SearchCurrentBlock(this.Document, index - 1); var bracket = string.Empty; var inBlock = TokenType.StringBlock; if (block != null) { bracket = this.Document.GetCharAt(block.OpenBracketOffset).ToString(); if (bracket == "{") { inBlock = TokenType.TagBlock; } else if (bracket == "[") { inBlock = TokenType.ArrayBlock; } } var tokens = this.Text.Tokenize(TokenizeType.All); var next = this.NextChar; var prev = (this.CaretOffset > 1) ? this.Document.GetCharAt(this.CaretOffset - 2) : '\0'; var before = tokens .TakeWhile(x => x.Index < index) .Where(x => !x.IsMatchType(TokenType.Blank)); var current = before.LastOrDefault(); var prevToken = before.SkipLast(1).LastOrDefault(); if (before.IsEmpty() || current.IsMatchType(TokenType.String, TokenType.Comment)) { return(null); } if ("\r\n".Contains(input) && (Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.None) { return(null); } before = before.Where(x => !x.IsMatchType(TokenType.Comment)); using (var reader = new TokenReader(before, true)) { try { #region コマンド if (inBlock == TokenType.StringBlock) { switch (input.ToLower()) { case "/": return(Minecraft.CommandCompletion); case "@": return(Minecraft.SelectorCompletion); case "_": return((inBlock == TokenType.ArrayBlock && current.IsMatchType(TokenType.Literal)) ? (current.Value.IndexOf("score_") == 0) ? (current.Value == "score_") ? this.ExtendedOptions.ScoreNames.ToCompletionData() : new[] { new CompletionData("min") } : null : null); } /* * if (!before.Any(x => x.IsMatchType(TokenType.Command))) * { * return null; * } */ var command = reader.SkipGet(x => x.IsMatchType(TokenType.Command) || x.IsMatchLiteral("detect")); if (command.IsEmpty()) { return(null); } switch (input.ToLower()) { case ":": if (!command.IsEmpty()) { if (reader.CheckAt(1, x => x.IsMatchLiteral("minecraft"))) { goto case " "; } } break; case ",": break; case "\r\n": case "\r": case "\n": case " ": if (!command.IsEmpty() && inBlock == TokenType.StringBlock) { reader.Reverse(); var args = this.RemainTokensToArgs(reader); var def = command.IsMatchLiteral("detect") ? Minecraft.Document.Root.Element("ExCommands").Elements("Command") .Where(x => x.Attribute("name").Value == command.Value).SingleOrDefault() : Minecraft.Document.Root.Element("Commands").Elements("Command") .Where(x => "/" + x.Attribute("name").Value == command.Value).SingleOrDefault(); if (def == null) { return(null); } var elements = def.Elements("Arg"); var element = null as XElement; foreach (var arg in args) { if (elements.IsEmpty()) { return(null); } if (elements.Count() > 1) { Console.WriteLine(arg.Value); if (elements.Any(x => x.Attribute("type").Value == "key" && arg.IsMatchLiteral(x.Attribute("key").Value))) { elements = elements.Where(x => arg.IsMatchLiteral(x.Attribute("key").Value)).Elements("Arg"); } else if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true"))) { elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")).Elements("Arg"); } else { return(null); } } else { elements = elements.Elements("Arg"); } } if (elements.Count() > 1) { if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true"))) { elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")); } else { return(elements.Attributes() .Where(x => x.Name == "key") .Select(x => new CompletionData(x.Value))); } } element = elements.SingleOrDefault(); if (element == null) { return(null); } var type = element.Attribute("type").Value; switch (type) { case "key": return(new[] { new CompletionData(element.Attribute("key").Value) }); case "keywords": return(element.Elements("Word") .Select(x => new { Name = x.Value.Trim(), Tip = x.Attribute("desc") != null ? x.Attribute("desc").Value : x.Element("Desc") != null ? x.Element("Desc").Value : null }) .Select(x => new CompletionData(x.Name, x.Tip))); case "target": return(this.ExtendedOptions.PlayerNames.ToCompletionData()); case "target_entity": return(new[] { new CompletionData("@e") }); case "score": return(this.ExtendedOptions.ScoreNames.ToCompletionData()); case "team": return(this.ExtendedOptions.TeamNames.ToCompletionData()); case "item": return(Minecraft.ItemCompletion); case "block": return(Minecraft.BlockCompletion); case "entity": return(Minecraft.EntityCompletion); case "effect": return(prevToken.IsMatchLiteral("minecraft") ? Minecraft.EffectCompletion : Minecraft.EffectCompletion .Concat(new[] { new CompletionData("clear", "すべてのエフェクトを消去します。") })); case "enchant": return(Minecraft.EnchantCompletion); case "boolean": return(Minecraft.BooleanCompletion); case "color": return(Minecraft.ColorCompletion); case "command": if (command.Value == "/execute" || command.Value == "detect") { return(new[] { new CompletionData("detect") } .Concat(Minecraft.CommandCompletion)); } return(Minecraft.CommandCompletion); default: return(null); } } break; } } #endregion #region [ ... ] if (inBlock == TokenType.ArrayBlock) { switch (input) { case "!": if (reader.CheckNext(x => x.IsMatchType(TokenType.Equal))) { reader.MoveNext(); goto case "="; } return(null); case "=": if (reader.IsRemainToken) { var selector = before.TakeWhile(x => x.Index < block.OpenBracketOffset).LastOrDefault(); if (!selector.IsEmpty() && selector.IsMatchType(TokenType.TargetSelector)) { reader.MoveNext(); if (reader.CheckNext(x => x.IsMatchLiteral("team"))) { return(this.ExtendedOptions.TeamNames.ToCompletionData()); } if (reader.CheckNext(x => x.IsMatchLiteral("name"))) { return(this.ExtendedOptions.PlayerNames.ToCompletionData()); } } } return(null); } } #endregion } catch { return(null); } } return(null); }