public bool Parse(ExpressionCompiler compiler) { int startPos = compiler.Pos; if (!testSymbol.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = startPos; throw new ParserException(Name, startPos, "Missing operand for the test"); } TokenImpl test = compiler.Parent.PopChild(); // Parse the result if true token if (!compiler.ParseNextToken()) { // Reset the compiler position and restore the removed child compiler.Pos = startPos; compiler.Parent.AddChild(test); throw new ParserException(Name, startPos, "Missing operand for result if true"); } TokenImpl resultIfTrue = compiler.Parent.PopChild(); // Must have the 'else' token next if (!elseSymbol.Parse(compiler)) { // Reset the compiler position and restore the (first) removed child compiler.Pos = startPos; compiler.Parent.AddChild(test); throw new ParserException(Name, startPos, "Missing ':' symbol"); } // Parse the result if false token if (!compiler.ParseNextToken()) { // Reset the compiler position and restore the (first) removed child compiler.Pos = startPos; compiler.Parent.AddChild(test); throw new ParserException(Name, startPos, "Missing operand for result if false"); } TokenImpl resultIfFalse = compiler.Parent.PopChild(); TokenImpl token = new ConditionalOperatorToken(startPos, test, resultIfTrue, resultIfFalse); compiler.Parent.AddChild(token); return(true); }
public bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!symbolParser.Parse(compiler)) { return(false); } // Parse the right hand side if (!compiler.ParseNextToken()) { // Reset the compiler position compiler.Pos = symbolPos; throw new ParserException(Name, symbolPos, "Missing right-hand operand"); } TokenImpl rhs = compiler.Parent.PopChild(); TokenImpl token = CreateToken(compiler, symbolPos, rhs); if (token != null) { compiler.Parent.AddChild(token); } return(true); }
public override bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!base.Parse(compiler)) { return(false); } // The group becomes the new parent token GroupToken group = new GroupToken(symbolPos); compiler.Parent.AddChild(group); compiler.ParentTokens.Push(group); // Keep parsing until we are closed while (!group.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(group, "Unclosed group"); } } return(true); }
public bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!symbolParser.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = symbolPos; // If we are lenient to the left-hand side missing, just return false if (lhsLenient) { return(false); } else { throw new ParserException(Name, symbolPos, "Missing left-hand operand"); } } TokenImpl lhs = compiler.Parent.PopChild(); // Parse the right hand side if (!compiler.ParseNextToken()) { // Reset the compiler position and restore the removed child compiler.Pos = symbolPos; compiler.Parent.AddChild(lhs); throw new ParserException(Name, symbolPos, "Missing right-hand operand"); } TokenImpl rhs = compiler.Parent.PopChild(); TokenImpl token = CreateToken(compiler, symbolPos, lhs, rhs); if (token != null) { compiler.Parent.AddChild(token); } return(true); }
public override bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!base.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = symbolPos; // We don't throw an exception so the compiler will then check to see // if the symbol represents a group instead return(false); } TokenImpl lhs = compiler.Parent.PopChild(); FunctionToken function = null; if (lhs is HostSupport) { function = new FunctionToken(symbolPos, lhs); compiler.Parent.AddChild(function); } else if (lhs is BinaryToken) { // If the RHS of the binary token is token which supports hosting we can join to and replace it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); binaryLhs.Rhs = function; compiler.Parent.AddChild(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is token which supports hosting we can join to and replace it UnaryToken unaryLhs = (UnaryToken)lhs; TokenImpl lhsRhs = unaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); unaryLhs.Rhs = function; compiler.Parent.AddChild(unaryLhs); } } if (function == null) { // Restore the lhs and position compiler.Parent.AddChild(lhs); compiler.Pos = symbolPos; // Couldn't handle the lhs, just return false to continue to parse as a group return(false); } // The function becomes the new parent token compiler.ParentTokens.Push(function); // Keep parsing until we are closed while (!function.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(function, "Unclosed function"); } } return(true); }
public override bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!base.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = symbolPos; throw new ParserException("keyedAccess", symbolPos, "Missing left-hand operand"); } TokenImpl lhs = compiler.Parent.PopChild(); // See if we can handle the lhs KeyedAccessToken keyedAccess = null; if (lhs is HostSupport) { keyedAccess = new KeyedAccessToken(symbolPos, lhs); compiler.Parent.AddChild(keyedAccess); } else if (lhs is BinaryToken) { // If the RHS of the binary token is token which allows Hosting we can join to and replace it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it keyedAccess = new KeyedAccessToken(symbolPos, lhsRhs); binaryLhs.Rhs = keyedAccess; compiler.Parent.AddChild(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is which which allows Hosting we can join to and replace it UnaryToken unaryLhs = (UnaryToken)lhs; TokenImpl lhsRhs = unaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it keyedAccess = new KeyedAccessToken(symbolPos, lhsRhs); unaryLhs.Rhs = keyedAccess; compiler.Parent.AddChild(unaryLhs); } } // Throw an exception if we couldn't cope with the lhs. if (keyedAccess == null) { // Restore the lhs and position compiler.Parent.AddChild(lhs); compiler.Pos = symbolPos; throw new ParserException("keyedAccess", symbolPos, $"Left-hand side of a keyed access token cannot be: {lhs.Name}"); } // The keyed access becomes the new parent token compiler.ParentTokens.Push(keyedAccess); // Keep parsing until we are closed while (!keyedAccess.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(keyedAccess, "Unclosed keyed access"); } } return(true); }