private string[] CommentTextToDomainCommentTextLines(Token comment, out bool isDecorated) { CommentTerminal commentTerminal = (CommentTerminal)comment.Terminal; CommentKind commentKind = GrammarHelper.GetCommentKind(commentTerminal, GetCommentCleaner(commentTerminal).NewLine); string startSymbol = commentTerminal.StartSymbol; string endSymbol = commentKind == CommentKind.Delimited ? commentTerminal.EndSymbols.First(_endSymbol => comment.Text.EndsWith(_endSymbol)) : string.Empty; string text = comment.Text; text = text .Remove(text.Length - endSymbol.Length, endSymbol.Length) .Remove(0, startSymbol.Length); var commentCleaner = GetCommentCleaner(commentTerminal); // NOTE: we handle "\n" and "\r" as well to deal with wrongly formatted input string[] textLines = text.Split(new[] { commentCleaner.NewLine, "\r", "\n" }, StringSplitOptions.None); textLines = commentCleaner.GetCleanedUpCommentTextLines(textLines, comment.Location.Column, commentTerminal, out isDecorated); return(textLines); }
private static GrammarBuilder CreateLightCommandGrammar(LightActionSpec lightActionSpec) { var allLightsIdentifierChoices = GrammarHelper.ConvertIdentyListToGrammarBuilder(lightActionSpec.LightIdentifiers.ToList()); var lightActions = lightActionSpec.GetAllActions(); var lightsLables = lightActionSpec.GetLightSubjectChoices(); var actionGrammarBuilders = new List <GrammarBuilder>(); foreach (var action in lightActions) { var actionChoices = action.ToChoices(); var actionGrammer1 = new GrammarBuilder(); actionGrammer1.AppendWildcard(); actionGrammer1.Append(new SemanticResultKey(LightActionSemanticKey, actionChoices)); actionGrammer1.AppendWildcard(); actionGrammer1.Append(new SemanticResultKey(LightIdentifierSemanticKey, allLightsIdentifierChoices)); actionGrammer1.AppendWildcard(); actionGrammer1.Append(new SemanticResultKey(CommandSubjectSemanticKey, lightsLables)); var actionGrammar2 = new GrammarBuilder(); actionGrammar2.AppendWildcard(); actionGrammar2.Append(new SemanticResultKey(LightActionSemanticKey, actionChoices)); actionGrammar2.AppendWildcard(); actionGrammar2.Append(new SemanticResultKey(CommandSubjectSemanticKey, lightsLables)); actionGrammar2.AppendWildcard(); actionGrammar2.Append(new SemanticResultKey(LightIdentifierSemanticKey, allLightsIdentifierChoices)); actionGrammarBuilders.Add(actionGrammer1); actionGrammarBuilders.Add(actionGrammar2); } return(new GrammarBuilder(new Choices(actionGrammarBuilders.ToArray()))); }
/// <summary> /// Create a multiparser which consists of multiple parsers, each of them can parse a specific nonterminal of the grammar. /// Nonterminals are specified by grammar.SnippetRoots, which may be extended regarding the value of <paramref name="makeParsableEveryNonTerminal"/> /// </summary> /// <param name="grammar"> /// The grammar which will drive the multiparser. /// </param> /// <param name="makeParsableEveryNonTerminal"> /// If true then gather all nonterminals from grammar (going down from root recursively), and add them to SnippetRoots if needed. /// If false then SnippetRoots will not be changed. /// </param> internal MultiParser(Grammar grammar, bool makeParsableEveryNonTerminal = makeParsableEveryNonTerminalDefault) { grammar.SetDecimalSeparatorOnNumberLiterals(); // it works with Irony.Grammar as well, not just with Sarcasm.Grammar // NOTE: grammar.SnippetRoots should be extended before creating LanguageData if (makeParsableEveryNonTerminal) { foreach (NonTerminal nonTerminal in GrammarHelper.GetDescendantBnfTermsExcludingSelf(grammar.Root).OfType <NonTerminal>()) { if (!grammar.SnippetRoots.Contains(nonTerminal)) { grammar.SnippetRoots.Add(nonTerminal); } } } this.grammar = grammar; this.language = new LanguageData(grammar); if (this.language.ErrorLevel >= GrammarErrorLevel.Conflict && grammar.ErrorHandling == ErrorHandling.ThrowException) { GrammarHelper.ThrowGrammarErrorException(this.language.ErrorLevel, string.Join("\n", this.language.Errors)); } this.mainParser = new Parser(language); foreach (NonTerminal nonTerminal in grammar.SnippetRoots) { this.rootToParser.Add(nonTerminal, new Parser(language, nonTerminal)); } }
public Task InitiateSpeechRecognition() { speechCancellationTokenSource = new CancellationTokenSource(); var initiateCommandGrammerBuilder = new GrammarBuilder(InitiateCommandsPhrase); var cancelOverrideGrammarBuilder = new GrammarBuilder(CancelProgramCommand); var lightGrammerBuilder = CreateLightCommandGrammar(LightActionSpec); var finalGrammarBuilder = GrammarHelper.CombineGrammarBuilders(initiateCommandGrammerBuilder, cancelOverrideGrammarBuilder, lightGrammerBuilder); var recognizerInfo = SpeechRecognitionEngine.InstalledRecognizers().FirstOrDefault(ri => ri.Culture.TwoLetterISOLanguageName.Equals("en")); return(Task.Run(() => RunSpeechRecognizer(finalGrammarBuilder, recognizerInfo)));; }
private Comment CommentToDomainComment(Token comment, ParseTreeNode parseTreeNodeOwner, CommentPlacement placement, int lineIndexDistanceFromOwner) { CommentTerminal commentTerminal = (CommentTerminal)comment.Terminal; bool isDecorated; return(new Comment( CommentTextToDomainCommentTextLines(comment, out isDecorated), CommentCategoryToDomainCommentCategory(comment.Category), placement, lineIndexDistanceFromOwner, GrammarHelper.GetCommentKind(commentTerminal, GetCommentCleaner(commentTerminal).NewLine), isDecorated )); }
private static string GetGrammarValue(Grammar grammar) { string gval = string.Empty; if (grammar.isBuiltin) { switch (grammar.builtin.Type) { case BuiltinGrammar.GrammarType.digits: string length = "10"; if (grammar.builtin.MaxLength > 0) { length = grammar.builtin.MaxLength.ToString(); } else if (grammar.builtin.MinLength > 0) { length = grammar.builtin.MinLength.ToString(); } gval = "[ " + length + " DIGITS]"; break; case BuiltinGrammar.GrammarType.boolean: gval = "yes(1, yes), no(2, no)"; break; } } else if (grammar.isExternalRef) { gval = grammar.source; } else { gval = GrammarHelper.GrammarRulesToString(grammar); } return(gval); }
private void AddCommentToSideOfAstValue(ParseTreeNode owner, Token comment, CommentPlacement commentPlacement, int?lineIndexDistanceFromOwnerExplicit) { // first we calculate the lineIndexDistanceFromOwner, then we find a proper node with a non-null astNode to decorate (it can be in another line) int lineIndexDistanceFromOwner = lineIndexDistanceFromOwnerExplicit ?? Math.Abs(comment.Location.Line - owner.Span.Location.Line); owner = Util.Recurse(owner, GetParent).First(_parseTreeNode => _parseTreeNode.AstNode != null); object astValue = GrammarHelper.AstNodeToValue(owner.AstNode); Comments domainComments = astValue.GetComments(); if (domainComments == null) { domainComments = new Comments(); astValue.SetComments(domainComments); } var commentList = commentPlacement == CommentPlacement.OwnerLeft ? domainComments.left : domainComments.right; commentList.Add(CommentToDomainComment(comment, owner, commentPlacement, lineIndexDistanceFromOwner)); decoratedComments.Add(comment); }
private void StoreAstValueToParseTreeNodeRecursive(ParseTreeNode currentNode, int nodeIndex, object astValueParent) { object astValue = GrammarHelper.AstNodeToValue(currentNode.AstNode); if (astValue != null && astValue.GetType().IsClass&& !astValueToParseTreeNode.ContainsKey(astValue)) { astValueToParseTreeNode.Add(astValue, currentNode); } if (astValue != null && astValue.GetDirectParent() == null) { astValue.SetDirectParent(astValueParent); } foreach (var parseTreeChild in currentNode.ChildNodes.Select((parseTreeChild, childIndex) => new { Value = parseTreeChild, Index = childIndex })) { parseTreeNodeToParent.Add(parseTreeChild.Value, currentNode); StoreAstValueToParseTreeNodeRecursive(parseTreeChild.Value, parseTreeChild.Index, astValueParent: astValue); } if (currentNode.Comments != null && currentNode.Comments.Count > 0) { bool isTextInLineAtLeftOfFirstComment = IsTextInLineAtLeftOfComment(currentNode.Comments[0]); int lineIndexForFirstComment = currentNode.Comments[0].Location.Line; foreach (Token comment in currentNode.Comments) { if (decoratedComments.Contains(comment)) { continue; // we have already decorated this comment } ParseTreeNode parentNode = GetParent(currentNode); bool isCommentInLineOfFirstComment = comment.Location.Line == lineIndexForFirstComment; bool isTextInLineAtLeftOfComment = isTextInLineAtLeftOfFirstComment && isCommentInLineOfFirstComment; if (!isTextInLineAtLeftOfComment && parentNode != null && parentNode.Comments.Contains(comment) && parentNode.Span.Location.Line == currentNode.Span.Location.Line && !(GrammarHelper.AstNodeToValue(parentNode.AstNode) is IEnumerable)) { /* * Try to go up so we decorate the comment on the largest "subparsetree", but stop before lists * */ continue; } if (isTextInLineAtLeftOfComment && currentLine != null && comment.Location.Line == currentLine.Span.Location.Line && currentLine.AstNode != null) { /* * The comment belongs to the previous node (they are in the same line). * * Now we have one of the followings: * * code_prev (*comment*) code_this * */ AddCommentToRightOfAstValue(currentLine, comment); } else if (isTextInLineAtLeftOfComment && prevLine != null && comment.Location.Line == prevLine.Span.Location.Line && prevLine.AstNode != null) { /* * The comment belongs to the previous node (they are in the same line). * * code_prev (*comment*) * code_this * */ AddCommentToRightOfAstValue(prevLine, comment); } else if (currentNode.AstNode != null) { AddCommentToLeftOfAstValue(currentNode, comment); // the comment belongs to this node } else if (nodeIndex > 0) { // could not decorate comment, because we have no ast (if nodeIndex == 0 then Irony has already copied it onto the parent) Debug.Assert(parentNode != null); if (currentLine != null) { AddCommentToRightOfAstValue(currentLine, comment); // decorate the comment onto currentLine } else { parentNode.Comments.Add(comment); // copy the comment onto the parent and handle it there } } } } if (currentLine == null || currentNode.Term is Terminal || currentNode.Span.Location.Line == currentLine.Span.Location.Line) { if (currentLine != null && currentNode.Span.Location.Line > currentLine.Span.Location.Line) { prevLine = currentLine; } currentLine = currentNode; } }