public override bool Parse(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; if (tokens.CurrentToken.IsVariableKind()) { var v = new Variable(); v.Parse(context, this); // Variables don't set parent since during complex // exression parsing parent is determined by the // expression parser based on precedence and grouping. v.Parent = this; this.Variable = v; if (tokens.CurrentToken.IsKeywordText(context.TextProvider, "in")) { this.InOperator = new TokenNode(); this.InOperator.Parse(context, this); this.Expression = new Expression(inGroup: true); if (this.Expression.Parse(context, this)) { return base.Parse(context, parent); } } else { context.AddError(new MissingItemParseError(ParseErrorType.InKeywordExpected, tokens.CurrentToken)); } } else { context.AddError(new MissingItemParseError(ParseErrorType.IndentifierExpected, tokens.PreviousToken)); } return false; }
public override bool Parse(ParseContext context, IAstNode parent) { // First parse base which should pick up keyword, braces, inner // expression and either full or simple (single statement) scope if (!base.Parse(context, parent)) { return false; } // At this point we should be either at 'else' token or // at the next statement. In the latter case we are done. TokenStream<RToken> tokens = context.Tokens; if (tokens.CurrentToken.IsKeywordText(context.TextProvider, "else")) { bool allowLineBreak = AllowLineBreakBeforeElse(context); if (!allowLineBreak) { // Verify that there is no line break before the 'else' if (context.Tokens.IsLineBreakAfter(context.TextProvider, tokens.Position - 1)) { context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, tokens.CurrentToken)); return true; } } this.Else = new KeywordScopeStatement(allowsSimpleScope: true); return this.Else.Parse(context, this); } // Not at 'else' so we are done here return true; }
public override bool Parse(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; Debug.Assert(tokens.CurrentToken.TokenType == RTokenType.Keyword); this.Keyword = RParser.ParseKeyword(context, this); this.Text = context.TextProvider.GetText(this.Keyword); if (tokens.CurrentToken.TokenType == RTokenType.OpenBrace) { this.OpenBrace = RParser.ParseToken(context, this); this.Arguments = new ArgumentList(RTokenType.CloseBrace); this.Arguments.Parse(context, this); if (tokens.CurrentToken.TokenType == RTokenType.CloseBrace) { this.CloseBrace = RParser.ParseToken(context, this); this.Scope = RParser.ParseScope(context, this, allowsSimpleScope: true, terminatingKeyword: null); if (this.Scope != null) { return base.Parse(context, parent); } else { context.AddError(new ParseError(ParseErrorType.FunctionBodyExpected, ErrorLocation.Token, tokens.PreviousToken)); } } else { context.AddError(new ParseError(ParseErrorType.CloseBraceExpected, ErrorLocation.Token, tokens.CurrentToken)); } } else { context.AddError(new ParseError(ParseErrorType.OpenBraceExpected, ErrorLocation.Token, tokens.CurrentToken)); } return false; }
protected override CommaSeparatedItem CreateItem(IAstNode parent, ParseContext context) { RToken currentToken = context.Tokens.CurrentToken; RToken nextToken = context.Tokens.NextToken; switch (currentToken.TokenType) { case RTokenType.Ellipsis: return new EllipsisArgument(); case RTokenType.Comma: return new MissingArgument(); case RTokenType.Identifier: case RTokenType.String: case RTokenType.Logical: case RTokenType.Complex: case RTokenType.NaN: case RTokenType.Null: case RTokenType.Number: case RTokenType.Infinity: if (nextToken.TokenType == RTokenType.Operator && context.TextProvider.GetText(nextToken) == "=") { return new NamedArgument(); } break; case RTokenType.CloseBrace: return null; // no arguments supplied } return new ExpressionArgument(); }
/// <summary> /// Abstract factory creating statements depending on current /// token and the following token sequence /// </summary> /// <returns></returns> public static IStatement Create(ParseContext context, IAstNode parent, string terminatingKeyword) { TokenStream<RToken> tokens = context.Tokens; RToken currentToken = tokens.CurrentToken; IStatement statement = null; switch (currentToken.TokenType) { case RTokenType.Keyword: // If statement starts with a keyword, it is not an assignment // hence we should always try keyword based statements first. // Some of the statements may be R-values like typeof() but // in case of the statement appearing on its own return value // will be simply ignored. IDE may choose to show a warning. if (currentToken.SubType == RTokenSubType.BuiltinFunction && tokens.NextToken.TokenType != RTokenType.OpenBrace) { // 'return <- x + y' is allowed statement = new ExpressionStatement(terminatingKeyword); } else { statement = KeywordStatement.CreateStatement(context, parent); } break; case RTokenType.Semicolon: statement = new EmptyStatement(); break; default: // Possible L-value in a left-hand assignment, // a function call or R-value in a right hand assignment. statement = new ExpressionStatement(terminatingKeyword); break; } return statement; }
public override bool Parse(ParseContext context, IAstNode parent) { if (ParseExpression(context) && this.Children.Count > 0) { return base.Parse(context, parent); } return false; }
public override bool Parse(ParseContext context, IAstNode parent) { // Remove comments from the token stream this.Comments = new CommentsCollection(context.Comments); GlobalScope globalScope = new GlobalScope(); return globalScope.Parse(context, this); }
public override bool Parse(ParseContext context, IAstNode parent) { if (context.Tokens.CurrentToken.TokenType == RTokenType.Comma) { this.Comma = RParser.ParseToken(context, this); } return base.Parse(context, parent); }
public override bool Parse(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Identifier || context.Tokens.CurrentToken.TokenType == RTokenType.String); this.Identifier = RParser.ParseToken(context, this); this.EqualsSign = RParser.ParseToken(context, this); if (context.Tokens.CurrentToken.TokenType != RTokenType.Comma && context.Tokens.CurrentToken.TokenType != RTokenType.CloseBrace) { Expression exp = new Expression(inGroup: true); if (exp.Parse(context, this)) { this.DefaultValue = exp; } } else { this.DefaultValue = new NullExpression(); if (context.Tokens.IsEndOfStream()) { context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, context.Tokens.CurrentToken)); } else { context.AddError(new ParseError(ParseErrorType.ExpressionExpected, ErrorLocation.Token, EqualsSign)); } } return base.Parse(context, parent); }
private bool AllowLineBreakBeforeElse(ParseContext context) { if (context.Scopes.Count > 1) { return true; } // The problem here is that in recursive descent parser // node parent hasn't been assigned yet since it is assigned // when construct is fully parsed. So we will check if this // 'if' is part of an ExpressionStatement (which is in the // global scope. // // Variants: // a. If is not an 'inline if' and rather is a statement by itself. // b. If is 'inline if' but is a part of an expression // that is inside expression statement and has no braces. // if (!(this is InlineIf)) { // 'if' statement return false; } // Now we need to check if the expression being parsed. // is in a Group i.e. enclosed in ( ). Debug.Assert(context.Expressions.Count > 0); Expression expression = context.Expressions.Count > 0 ? context.Expressions.Peek() : null; if (expression != null && expression.IsInGroup) { return true; } // Remaining case: x <- a + if(y < 0) 1 return false; }
public override bool Parse(ParseContext context, IAstNode parent) { if (context.Tokens.CurrentToken.TokenType == RTokenType.OpenBrace) { context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, context.Tokens.CurrentToken)); } return false; }
public static TokenNode ParseToken(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; TokenNode node = new TokenNode(); node.Parse(context, parent); return node; }
public override bool Parse(ParseContext context, IAstNode parent) { foreach (RToken t in Tokens) { TokenNode n = new TokenNode(t); n.Parent = this; } return base.Parse(context, parent); }
public override bool Parse(ParseContext context, IAstNode parent) { this.ArgumentValue = new Expression(inGroup: true); if (this.ArgumentValue.Parse(context, this)) { return base.Parse(context, parent); } return false; }
public override bool Parse(ParseContext context, IAstNode parent) { RToken currentToken = context.Tokens.CurrentToken; this.Token = currentToken; context.Tokens.MoveToNextToken(); return base.Parse(context, parent); }
public override bool Parse(ParseContext context, IAstNode parent) { if (ParseKeyword(context, this)) { if (ParseSemicolon(context, this)) { return base.Parse(context, parent); } } return false; }
private int GetCurrentOperatorPrecedence(ParseContext context, OperatorType operatorType, out bool isUnary) { isUnary = false; if (IsUnaryOperator(context.Tokens, operatorType, -1)) { operatorType = OperatorType.Unary; isUnary = true; } return OperatorPrecedence.GetPrecedence(operatorType); }
public static TokenNode ParseCloseBraceSequence(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; if (tokens.CurrentToken.TokenType == RTokenType.CloseBrace) { return RParser.ParseToken(context, parent); } context.AddError(new MissingItemParseError(ParseErrorType.CloseBraceExpected, tokens.PreviousToken)); return null; }
public static TokenNode ParseKeyword(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; Debug.Assert(tokens.CurrentToken.TokenType == RTokenType.Keyword); TokenNode keyword = new TokenNode(); keyword.Parse(context, parent); return keyword; }
public override bool Parse(ParseContext context, IAstNode parent) { _statement = Statement.Create(context, this, _terminatingKeyword); if (_statement != null) { if (_statement.Parse(context, this)) { return base.Parse(context, parent); } } return false; }
public override bool Parse(ParseContext context, IAstNode parent) { RToken currentToken = context.Tokens.CurrentToken; Debug.Assert(currentToken.IsVariableKind()); // Not calling base since expression parser will decide // what parent node the variable belongs to. this.Token = currentToken; context.Tokens.MoveToNextToken(); return true; }
public override bool Parse(ParseContext context, IAstNode parent) { if (base.Parse(context, parent)) { IScope scope = RParser.ParseScope(context, this, allowsSimpleScope: true, terminatingKeyword: _terminatingKeyword); if (scope != null) { this.Scope = scope; return true; } } return false; }
public override bool Parse(ParseContext context, IAstNode parent) { if (ParseKeyword(context, parent)) { IScope scope = RParser.ParseScope(context, this, _allowsSimpleScope, terminatingKeyword: null); if (scope != null) { this.Scope = scope; } this.Parent = parent; return true; } return false; }
/// <summary> /// Parse text from a text provider within a given range /// </summary> /// <param name="textProvider">Text provider</param> /// <param name="range">Range to parse</param> public static AstRoot Parse(ITextProvider textProvider, ITextRange range) { var tokenizer = new RTokenizer(separateComments: true); IReadOnlyTextRangeCollection<RToken> tokens = tokenizer.Tokenize(textProvider, range.Start, range.Length); TokenStream<RToken> tokenStream = new TokenStream<RToken>(tokens, new RToken(RTokenType.EndOfStream, TextRange.EmptyRange)); ParseContext context = new ParseContext(textProvider, range, tokenStream, tokenizer.CommentTokens); context.AstRoot.Parse(context, context.AstRoot); context.AstRoot.Errors = new TextRangeCollection<IParseError>(context.Errors); return context.AstRoot; }
public static TokenNode ParseOpenBraceSequence(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; if (tokens.CurrentToken.TokenType == RTokenType.OpenBrace) { TokenNode openBrace = new TokenNode(); openBrace.Parse(context, parent); return openBrace; } else { context.AddError(new MissingItemParseError(ParseErrorType.OpenBraceExpected, tokens.PreviousToken)); } return null; }
public override bool Parse(ParseContext context, IAstNode parent) { Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Keyword); this.Keyword = RParser.ParseKeyword(context, this); this.Text = context.TextProvider.GetText(this.Keyword); bool result = base.Parse(context, parent); if (context.Tokens.CurrentToken.TokenType == RTokenType.Semicolon) { this.Semicolon = RParser.ParseToken(context, this); } return result; }
protected bool ParseSemicolon(ParseContext context, IAstNode parent) { if (!context.Tokens.IsEndOfStream()) { if (!context.Tokens.IsLineBreakAfter(context.TextProvider, context.Tokens.Position - 1)) { if (context.Tokens.CurrentToken.TokenType == RTokenType.Semicolon) { this.Semicolon = RParser.ParseToken(context, this); } else { context.AddError(new ParseError(ParseErrorType.UnexpectedToken, ErrorLocation.Token, context.Tokens.CurrentToken)); return false; } } } return true; }
public override bool Parse(ParseContext context, IAstNode parent) { Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Operator); _operatorType = TokenOperator.GetOperatorType(context.TextProvider.GetText(context.Tokens.CurrentToken)); this.OperatorToken = RParser.ParseToken(context, this); this.Association = OperatorAssociation.GetAssociation(_operatorType); bool isUnary; _precedence = this.GetCurrentOperatorPrecedence(context, this.OperatorType, out isUnary); if (!_isUnary) { _isUnary = isUnary; } return base.Parse(context, parent); }
public override bool Parse(ParseContext context, IAstNode parent) { Debug.Assert(context.Tokens.CurrentToken.TokenType == RTokenType.Operator); OperatorType = TokenOperator.GetOperatorType(context.TextProvider.GetText(context.Tokens.CurrentToken)); OperatorToken = RParser.ParseToken(context, this); Associativity = OperatorAssociativity.GetAssociativity(OperatorType); // If operator is preceded by an operator, it is then unary // Look back two tokens since operator parsing already consumed its token. if (IsUnary || IsUnaryOperator(context.Tokens, context.TextProvider, OperatorType, -2)) { OperatorType = Operator.GetUnaryForm(OperatorType); IsUnary = true; Associativity = Associativity.Right; } return base.Parse(context, parent); }
public override bool Parse(ParseContext context, IAstNode parent) { this.Expression = new Expression(_terminatingKeyword); if (this.Expression.Parse(context, this)) { if (this.Expression.Children.Count == 1 && this.Expression.Children[0] is Expression) { // Promote up Expression = this.Expression.Children[0] as Expression; Expression.Parent = null; _children.RemoveAt(0); Expression.Parent = this; } return base.Parse(context, parent); } return false; }