private void ParseFeature(PsiBuilder builder) { var featureMarker = builder.Mark(); Assertion.Assert(builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD, "_builder.GetTokenType() == GherkinTokenTypes.FEATURE_KEYWORD"); int? descMarker = null; bool wasLineBreak = false; do { builder.AdvanceLexer(); var tokenType = builder.GetTokenType(); if (tokenType == GherkinTokenTypes.TEXT && descMarker == null) { if (wasLineBreak) { descMarker = builder.Mark(); } } if (GherkinTokenTypes.SCENARIOS_KEYWORDS[tokenType] || tokenType == GherkinTokenTypes.RULE_KEYWORD || tokenType == GherkinTokenTypes.BACKGROUND_KEYWORD || tokenType == GherkinTokenTypes.TAG) { if (descMarker != null) { builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null); descMarker = null; } ParseFeatureElements(builder); } wasLineBreak = IsLineBreak(builder); if (wasLineBreak) { SkipGroupedWhiteSpaces(builder); } } while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof()); if (descMarker != null) { builder.DoneBeforeWhitespaces(descMarker.Value, GherkinNodeTypes.FEATURE_HEADER, null); } builder.DoneBeforeWhitespaces(featureMarker, GherkinNodeTypes.FEATURE, null); }
private bool ParseHigh(PsiBuilder builder) { var start = builder.Mark(); if (!ParseIdent(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() == SpringTokenType.HIGH_BINOP) { AdvanceWithSpaces(builder); if (!ParseHigh(builder)) { builder.Drop(start); return(false); } builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.HIGH_BINOP, null); return(true); } builder.Drop(start); return(true); }
private bool ParseMedium(PsiBuilder builder) { var start = builder.Mark(); if (!ParseHigh(builder)) { builder.Drop(start); return(false); } while (builder.GetTokenType() == SpringTokenType.MEDIUM_BINOP) { AdvanceWithSpaces(builder); if (!ParseHigh(builder)) { builder.Drop(start); return(false); } builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.MEDIUM_BINOP, null); builder.Precede(start); } builder.Drop(start); return(true); }
private bool ParseAssign(PsiBuilder builder) { var start = builder.Mark(); if (builder.GetTokenType() != SpringTokenType.IDENT) { builder.Drop(start); builder.Error("Missing variable"); return(false); } AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.ASSIGN) { builder.Drop(start); builder.Error("Missing ':='"); return(false); } AdvanceWithSpaces(builder); if (!ParseLogic(builder)) { builder.Drop(start); return(false); } builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.ASSIGN, null); return(true); }
private void ParseComments(PsiBuilder builder) { while (builder.GetTokenType() == GherkinTokenTypes.COMMENT) { var commentMarker = builder.Mark(); var commentText = builder.GetTokenText(); builder.AdvanceLexer(); var match = LanguagePattern.Match(commentText); if (match.Success) { _lang = match.Groups["lang"].Value; builder.DoneBeforeWhitespaces(commentMarker, GherkinNodeTypes.LANGUAGE_COMMENT, _lang); } else { builder.Drop(commentMarker); } if (builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { builder.AdvanceLexer(); } } }
private static int?ParseRule(PsiBuilder builder, int?ruleMarker) { if (builder.GetTokenType() == GherkinTokenTypes.RULE_KEYWORD) { if (ruleMarker != null) { builder.DoneBeforeWhitespaces(ruleMarker.Value, GherkinNodeTypes.RULE, null); } ruleMarker = builder.Mark(); builder.AdvanceLexer(); if (builder.GetTokenType() == GherkinTokenTypes.COLON) { builder.AdvanceLexer(); } else { return(ruleMarker); } while (builder.GetTokenType() == GherkinTokenTypes.TEXT || builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { builder.AdvanceLexer(); } } return(ruleMarker); }
private bool ParseSeq(PsiBuilder builder) { var start = builder.Mark(); if (!ParseStmt(builder)) { builder.Drop(start); return(false); } if (builder.Eof() || builder.GetTokenType() == SpringTokenType.RFBRACKET) { builder.Drop(start); return(true); } if (!ParseSeq(builder)) { builder.Drop(start); return(false); } builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.SEQ, null); return(true); }
private static void ParseTags(PsiBuilder builder) { while (builder.GetTokenType() == GherkinTokenTypes.TAG) { var tagMarker = builder.Mark(); builder.AdvanceLexer(); builder.DoneBeforeWhitespaces(tagMarker, GherkinNodeTypes.TAG, null); SkipWhitespace(builder); } }
private void ParseStep(PsiBuilder builder) { var marker = builder.Mark(); var keywordText = builder.GetTokenText(); builder.AdvanceLexer(); while (builder.GetTokenType() == GherkinTokenTypes.TEXT || builder.GetTokenType() == GherkinTokenTypes.STEP_PARAMETER_BRACE || builder.GetTokenType() == GherkinTokenTypes.STEP_PARAMETER_TEXT || builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { if (IsLineBreak(builder)) { break; } if (!ParseStepParameter(builder)) { builder.AdvanceLexer(); } } SkipGroupedWhiteSpaces(builder); var nextToken = builder.GetTokenType(1); if (nextToken == GherkinTokenTypes.PIPE) { builder.AdvanceLexer(); ParseTable(builder); } else if (nextToken == GherkinTokenTypes.PYSTRING) { builder.AdvanceLexer(); ParsePystring(builder); } var stepKind = _keywordProvider.GetStepKind(_lang, keywordText); var effectiveStepKind = stepKind; if (stepKind == GherkinStepKind.And) { effectiveStepKind = _lastStepKind; } else if (stepKind == GherkinStepKind.Given || stepKind == GherkinStepKind.When || stepKind == GherkinStepKind.Then) { _lastStepKind = effectiveStepKind; } builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.STEP, (stepKind, effectiveStepKind)); }
private void ParseScenario(PsiBuilder builder) { SkipWhitespace(builder); var scenarioMarker = builder.Mark(); ParseTags(builder); // scenarios var startTokenType = builder.GetTokenType(); var outline = startTokenType == GherkinTokenTypes.SCENARIO_OUTLINE_KEYWORD; builder.AdvanceLexer(); while (!AtScenarioEnd(builder)) { SkipWhitespace(builder); ParseTags(builder); if (ParseStepParameter(builder)) { continue; } if (builder.GetTokenType() == GherkinTokenTypes.STEP_KEYWORD) { ParseStep(builder); } else if (builder.GetTokenType() == GherkinTokenTypes.EXAMPLES_KEYWORD) { ParseExamplesBlock(builder); } else { builder.AdvanceLexer(); } } builder.DoneBeforeWhitespaces(scenarioMarker, outline ? GherkinNodeTypes.SCENARIO_OUTLINE : GherkinNodeTypes.SCENARIO, null); }
private void ParseFeatureElements(PsiBuilder builder) { int?ruleMarker = null; while (builder.GetTokenType() != GherkinTokenTypes.FEATURE_KEYWORD && !builder.Eof()) { if (builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { builder.AdvanceLexer(); continue; } ruleMarker = ParseRule(builder, ruleMarker); ParseScenario(builder); } if (ruleMarker.HasValue) { builder.DoneBeforeWhitespaces(ruleMarker.Value, GherkinNodeTypes.RULE, null); } }
private static void ParseExamplesBlock(PsiBuilder builder) { var marker = builder.Mark(); builder.AdvanceLexer(); if (builder.GetTokenType() == GherkinTokenTypes.COLON) { builder.AdvanceLexer(); } while (builder.GetTokenType() == GherkinTokenTypes.TEXT || builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { builder.AdvanceLexer(); } if (builder.GetTokenType() == GherkinTokenTypes.PIPE) { ParseTable(builder); } builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.EXAMPLES_BLOCK, null); }
private bool ParseIdent(PsiBuilder builder) { var start = builder.Mark(); if (builder.GetTokenType() == SpringTokenType.READ) { AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LBRACKET) { builder.RollbackTo(start); builder.Error("Missing '('"); return(false); } AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.RBRACKET) { builder.RollbackTo(start); builder.Error("Missing ')'"); return(false); } AdvanceWithSpaces(builder); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.READ, null); return(true); } if (builder.GetTokenType() == SpringTokenType.NUMBER) { AdvanceWithSpaces(builder); builder.Done(start, SpringCompositeNodeType.NUMBER, null); return(true); } if (builder.GetTokenType() == SpringTokenType.IDENT) { AdvanceWithSpaces(builder); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.VARIABLE, null); return(true); } if (builder.GetTokenType() == SpringTokenType.STRING) { AdvanceWithSpaces(builder); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.STRING, null); return(true); } if (builder.GetTokenType() == SpringTokenType.LBRACKET) { AdvanceWithSpaces(builder); if (!ParseLogic(builder)) { builder.RollbackTo(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RBRACKET) { builder.RollbackTo(start); builder.Error("Missing ')'"); return(false); } AdvanceWithSpaces(builder); builder.Drop(start); return(true); } builder.Drop(start); builder.Error("Not ident"); return(false); }
private static void ParseTable(PsiBuilder builder) { var marker = builder.Mark(); var rowMarker = builder.Mark(); var headerNodeType = GherkinNodeTypes.TABLE_HEADER_ROW; int?cellMarker = null; var wasLineBreak = false; var possibleEmptyCell = false; while (builder.GetTokenType() == GherkinTokenTypes.PIPE || builder.GetTokenType() == GherkinTokenTypes.TABLE_CELL || builder.GetTokenType() == GherkinTokenTypes.WHITE_SPACE || builder.GetTokenType() == GherkinTokenTypes.NEW_LINE) { var tokenType = builder.GetTokenType(); if (tokenType == GherkinTokenTypes.TABLE_CELL && cellMarker == null) { cellMarker = builder.Mark(); } else if (tokenType != GherkinTokenTypes.TABLE_CELL && cellMarker != null) { builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null); cellMarker = null; possibleEmptyCell = false; } if (tokenType == GherkinTokenTypes.PIPE) { if (wasLineBreak) { possibleEmptyCell = true; builder.DoneBeforeWhitespaces(rowMarker, headerNodeType, null); headerNodeType = GherkinNodeTypes.TABLE_ROW; rowMarker = builder.Mark(); } else { if (possibleEmptyCell) { cellMarker = builder.Mark(); builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null); cellMarker = null; } possibleEmptyCell = true; } } wasLineBreak = IsLineBreak(builder); if (wasLineBreak) { SkipGroupedWhiteSpaces(builder); } builder.AdvanceLexer(); } if (cellMarker.HasValue) { builder.DoneBeforeWhitespaces(cellMarker.Value, GherkinNodeTypes.TABLE_CELL, null); } builder.DoneBeforeWhitespaces(rowMarker, headerNodeType, null); builder.DoneBeforeWhitespaces(marker, GherkinNodeTypes.TABLE, null); }
public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e) { _builder.ResetCurrentLexeme(offendingSymbol.TokenIndex, offendingSymbol.TokenIndex); _builder.DoneBeforeWhitespaces(_builder.Mark(), SpringPsiBuilderErrorElement.NODE_TYPE, new ErrorMsgWithLengthAndType(msg, offendingSymbol.Text.Length)); }
private bool ParseStmt(PsiBuilder builder) { var start = builder.Mark(); if (builder.GetTokenType() == SpringTokenType.IF) { AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LBRACKET) { builder.Drop(start); builder.Error("Missing '('"); return(false); } AdvanceWithSpaces(builder); if (!ParseLogic(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RBRACKET) { builder.Drop(start); builder.Error("Missing ')'"); return(false); } AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LFBRACKET) { builder.Drop(start); builder.Error("Missing '{'"); return(false); } AdvanceWithSpaces(builder); if (!ParseSeq(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RFBRACKET) { builder.Drop(start); builder.Error("Missing '}'"); return(false); } AdvanceWithSpaces(builder); if (builder.GetTokenType() == SpringTokenType.ELSE) { AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LFBRACKET) { builder.Drop(start); builder.Error("Missing '{'"); return(false); } AdvanceWithSpaces(builder); if (!ParseSeq(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RFBRACKET) { builder.Drop(start); builder.Error("Missing '}'"); return(false); } AdvanceWithSpaces(builder); } builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.IF, null); return(true); } if (builder.GetTokenType() == SpringTokenType.FOR) { AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LBRACKET) { builder.Drop(start); builder.Error("Missing '('"); return(false); } AdvanceWithSpaces(builder); if (!ParseAssign(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.SEQ) { builder.Drop(start); builder.Error("Missing ';'"); return(false); } AdvanceWithSpaces(builder); if (!ParseLogic(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.SEQ) { builder.Drop(start); builder.Error("Missing ';'"); return(false); } AdvanceWithSpaces(builder); if (!ParseAssign(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RBRACKET) { builder.Drop(start); builder.Error("Missing ')'"); return(false); } AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LFBRACKET) { builder.Drop(start); builder.Error("Missing '{'"); return(false); } AdvanceWithSpaces(builder); if (!ParseSeq(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RFBRACKET) { builder.Drop(start); builder.Error("Missing '}'"); return(false); } AdvanceWithSpaces(builder); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.FOR, null); return(true); } if (builder.GetTokenType() == SpringTokenType.WRITE) { AdvanceWithSpaces(builder); if (builder.GetTokenType() != SpringTokenType.LBRACKET) { builder.RollbackTo(start); builder.Error("Missing '('"); return(false); } AdvanceWithSpaces(builder); if (!ParseLogic(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.RBRACKET) { builder.RollbackTo(start); builder.Error("Missing ')'"); return(false); } AdvanceWithSpaces(builder); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.WRITE, null); if (builder.GetTokenType() != SpringTokenType.SEQ) { builder.Error("Missing ';'"); return(false); } AdvanceWithSpaces(builder); return(true); } if (!ParseAssign(builder)) { builder.Drop(start); return(false); } if (builder.GetTokenType() != SpringTokenType.SEQ) { builder.Drop(start); builder.Error("Missing ';'"); return(false); } AdvanceWithSpaces(builder); builder.Drop(start); return(true); }
private bool ParseVariable() { if (builder.GetTokenType() != SpringTokenType.IDENTIFIER) { return(false); } var start = builder.Mark(); AdvanceLexerSkipNonsemantical(); if (builder.GetTokenType() == SpringTokenType.SQUARE_LBRACE) { var subsListMark = builder.Mark(); AdvanceLexerSkipNonsemantical(); if (!ParseNonemptyList(tt => tt == SpringTokenType.COMMA, ParseArithExpr, "An arithmetic expression expected")) { builder.Error("An arithmetic expression expected"); } if (builder.GetTokenType() != SpringTokenType.SQUARE_RBRACE) { builder.Error("A closing bracket expected"); } else { AdvanceLexerSkipNonsemantical(); } builder.DoneBeforeWhitespaces(subsListMark, SpringCompositeNodeType.SUBSCRIPT_LIST, null); builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.SUBSCRIPTED_VAR, null); } else { builder.DoneBeforeWhitespaces(start, SpringCompositeNodeType.VAR, null); } return(true); }