/// <summary> /// variable_access : variable /// | procedure_call /// | member_access /// /// member_access : variable_access DOT variable_access /// /// procedure_call : identifier params /// /// params : LPAREN actual_param_list RPAREN /// /// actual_param_list : actual_param_list COMMA param /// | empty /// /// param : statement /// /// variable : identifier /// </summary> private IdentifierAstNode ParseVariableAccess(IdentifierAstNode parentNode = null) { IdentifierAstNode node; var token = CurrentToken; Eat(TokenType.IDENTIFIER); EatWhiteSpace(); if (CurrentToken.Type != TokenType.LPAREN) { node = new IdentifierVariableAccessAstNode(token); } else { node = ParseProcedureCall(token); EatWhiteSpace(); } if (CurrentToken.Type == TokenType.DOT) { Eat(TokenType.DOT); EatWhiteSpace(); node = ParseVariableAccess(node); } if (parentNode != null) { parentNode.MemberIdentifier = node; } return(parentNode ?? node); }
public void Visit(IdentifierAstNode visitable) { if (!_context.HasVariable(visitable.Name)) { throw new UndefinedVariableException(visitable.Name); } _exprType = _context.GetVariableType(visitable.Name); }
/// <summary> /// each_loop : each variable in variable QM statement /// /// TODO: The lexer should return reserved keywords as tokens /// </summary> /// <returns></returns> private AstNode ParseEachLoop() { if (CurrentToken.Type != TokenType.IDENTIFIER && CurrentToken.Value != "each") { throw new Exception($"Invalid token, expected 'each' keyword at position {CurrentToken.Position}"); } var eachToken = CurrentToken; Eat(TokenType.IDENTIFIER); EatWhiteSpace(); // Extract variable name var loopVariable = new IdentifierAstNode(CurrentToken); Eat(TokenType.IDENTIFIER); EatWhiteSpace(); // 'in' keyword if (CurrentToken.Type != TokenType.IDENTIFIER && CurrentToken.Value == "in") { throw new Exception($"Invalid token, expect 'in' keyword at position {CurrentToken.Position}"); } Eat(TokenType.IDENTIFIER); EatWhiteSpace(); var enumerable = new IdentifierAstNode(CurrentToken); Eat(TokenType.IDENTIFIER); EatWhiteSpace(); Eat(TokenType.QM); EatWhiteSpace(); var loopBody = ParseStatement(); return(new EachLoopAstNode(eachToken, loopVariable, enumerable, loopBody)); }
public abstract void VisitIdentifier(IdentifierAstNode node);
public virtual object Visit(IdentifierAstNode node) { return(null); }
public void TestIdentifier(IdentifierAstNode expect, IdentifierAstNode actual, string traceMessage) { Assert.IsNotNull(actual, traceMessage); Assert.AreEqual(expect, actual, traceMessage); }
public void Visit(IdentifierAstNode visitable) { }
public override void VisitIdentifier(IdentifierAstNode node) { }