Пример #1
0
        public ExprOp ParseAssingExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseLambdaExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                while (true)
                {
                    ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.ASSIGN)
                    {
                        ExprOp prev = node;
                        node      = new ExprOp(OpKindEnum.O_DEFINE);
                        node.Left = prev;
                        ExprOp scope = new ExprOp(OpKindEnum.SCOPE);
                        scope.Left = ParseLambdaExpr(inStream, tFlags);
                        node.Right = scope;
                    }
                    else
                    {
                        PushToken(tok);
                        break;
                    }
                }
            }

            return(node);
        }
Пример #2
0
        public ExprOp ParseValueTerm(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp    node = null;
            ExprToken tok  = NextToken(inStream, tFlags);

            switch (tok.Kind)
            {
            case ExprTokenKind.VALUE:
                node         = new ExprOp(OpKindEnum.VALUE);
                node.AsValue = tok.Value;
                break;

            case ExprTokenKind.IDENT:
                string ident = tok.Value.AsString;

                node         = new ExprOp(OpKindEnum.IDENT);
                node.AsIdent = ident;
                break;

            case ExprTokenKind.LPAREN:
                node = ParseValueExpr(inStream, (tFlags | AmountParseFlagsEnum.PARSE_PARTIAL) & ~AmountParseFlagsEnum.PARSE_SINGLE);
                tok  = NextToken(inStream, tFlags, ExprTokenKind.RPAREN);
                break;

            default:
                PushToken(tok);
                break;
            }

            return(node);
        }
Пример #3
0
        public ExprOp ParseOrExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseAndExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                while (true)
                {
                    ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.KW_OR)
                    {
                        ExprOp prev = node;
                        node       = new ExprOp(OpKindEnum.O_OR);
                        node.Left  = prev;
                        node.Right = ParseAndExpr(inStream, tFlags);
                        if (node.Right == null)
                        {
                            throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                        }
                    }
                    else
                    {
                        PushToken(tok);
                        break;
                    }
                }
            }

            return(node);
        }
Пример #4
0
        public ExprOp ParseCallExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseValueTerm(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                while (true)
                {
                    ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.LPAREN)
                    {
                        ExprOp prev = node;
                        node      = new ExprOp(OpKindEnum.O_CALL);
                        node.Left = prev;
                        PushToken(tok);  // let the parser see the '(' again
                        node.Right = ParseValueExpr(inStream, tFlags | AmountParseFlagsEnum.PARSE_SINGLE);
                    }
                    else
                    {
                        PushToken(tok);
                        break;
                    }
                }
            }

            return(node);
        }
Пример #5
0
        public ExprOp ParseUnaryExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp    node = null;
            ExprToken tok  = NextToken(inStream, tFlags);

            switch (tok.Kind)
            {
            case ExprTokenKind.EXCLAM:
            {
                ExprOp term = ParseDotExpr(inStream, tFlags);
                if (term == null)
                {
                    throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                }

                // A very quick optimization
                if (term.Kind == OpKindEnum.VALUE)
                {
                    term.AsValue.InPlaceNot();
                    node = term;
                }
                else
                {
                    node      = new ExprOp(OpKindEnum.O_NOT);
                    node.Left = term;
                }
                break;
            }

            case ExprTokenKind.MINUS:
            {
                ExprOp term = ParseDotExpr(inStream, tFlags);
                if (term == null)
                {
                    throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                }

                // A very quick optimization
                if (term.Kind == OpKindEnum.VALUE)
                {
                    term.AsValue.InPlaceNegate();
                    node = term;
                }
                else
                {
                    node      = new ExprOp(OpKindEnum.O_NEG);
                    node.Left = term;
                }
                break;
            }

            default:
                PushToken(tok);
                node = ParseDotExpr(inStream, tFlags);
                break;
            }

            return(node);
        }
Пример #6
0
        public static string TokenToString(ExprToken token)
        {
            switch (token.Kind)
            {
            case ExprTokenKind.VALUE:
                return(String.Format("<value '{0}'>", token.Value));

            case ExprTokenKind.IDENT:
                return(String.Format("<ident '{0}'>", token.Value));

            case ExprTokenKind.MASK:
                return(String.Format("<mask '{0}'>", token.Value));

            default:
                return(KindToString(token.Kind));
            }
        }
Пример #7
0
        public ExprOp ParseCommaExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseQuerycolonExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                ExprOp next = null;
                while (true)
                {
                    ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.COMMA)
                    {
                        if (next == null)
                        {
                            ExprOp prev = node;
                            node      = new ExprOp(OpKindEnum.O_CONS);
                            node.Left = prev;
                            next      = node;
                        }

                        ExprToken ntok = NextToken(inStream, tFlags);
                        PushToken(ntok);
                        if (ntok.Kind == ExprTokenKind.RPAREN)
                        {
                            break;
                        }

                        ExprOp chain = new ExprOp(OpKindEnum.O_CONS);
                        chain.Left = ParseQuerycolonExpr(inStream, tFlags);

                        next.Right = chain;
                        next       = chain;
                    }
                    else
                    {
                        PushToken(tok);
                        break;
                    }
                }
            }

            return(node);
        }
Пример #8
0
        public ExprOp ParseValueExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseAssingExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                ExprOp chain = null;
                while (true)
                {
                    ExprToken tok = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.SEMI)
                    {
                        ExprOp seq = new ExprOp(OpKindEnum.O_SEQ);
                        if (chain == null)
                        {
                            seq.Left = node;
                            node     = seq;
                        }
                        else
                        {
                            seq.Left    = chain.Right;
                            chain.Right = seq;
                        }
                        seq.Right = ParseAssingExpr(inStream, tFlags);
                        chain     = seq;
                    }
                    else
                    {
                        PushToken(tok);
                        break;
                    }
                }
            }

            return(node);
        }
Пример #9
0
 public void PushToken(ExprToken tok)
 {
     UseLookahead = true;
 }
Пример #10
0
        public ExprOp ParseQuerycolonExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseOrExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                ExprToken tok = NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT);

                if (tok.Kind == ExprTokenKind.QUERY)
                {
                    ExprOp prev = node;
                    node       = new ExprOp(OpKindEnum.O_QUERY);
                    node.Left  = prev;
                    node.Right = ParseOrExpr(inStream, tFlags);
                    if (node.Right == null)
                    {
                        throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                    }

                    NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT, ExprTokenKind.COLON);
                    prev = node.Right;
                    ExprOp subNode = new ExprOp(OpKindEnum.O_COLON);
                    subNode.Left  = prev;
                    subNode.Right = ParseOrExpr(inStream, tFlags);
                    if (subNode.Right == null)
                    {
                        throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                    }

                    node.Right = subNode;
                }
                else if (tok.Kind == ExprTokenKind.KW_IF)
                {
                    ExprOp ifOp = ParseOrExpr(inStream, tFlags);
                    if (ifOp == null)
                    {
                        throw new ParseError("'if' keyword not followed by argument");
                    }

                    tok = NextToken(inStream, tFlags |= AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    if (tok.Kind == ExprTokenKind.KW_ELSE)
                    {
                        ExprOp elseOp = ParseOrExpr(inStream, tFlags);
                        if (elseOp == null)
                        {
                            throw new ParseError("'else' keyword not followed by argument");
                        }

                        ExprOp subNode = new ExprOp(OpKindEnum.O_COLON);
                        subNode.Left  = node;
                        subNode.Right = elseOp;

                        node       = new ExprOp(OpKindEnum.O_QUERY);
                        node.Left  = ifOp;
                        node.Right = subNode;
                    }
                    else
                    {
                        ExprOp nullNode = new ExprOp(OpKindEnum.VALUE);
                        nullNode.AsValue = Value.Empty;

                        ExprOp subNode = new ExprOp(OpKindEnum.O_COLON);
                        subNode.Left  = node;
                        subNode.Right = nullNode;

                        node       = new ExprOp(OpKindEnum.O_QUERY);
                        node.Left  = ifOp;
                        node.Right = subNode;

                        PushToken(tok);
                    }
                }
                else
                {
                    PushToken(tok);
                }
            }
            return(node);
        }
Пример #11
0
        public ExprOp ParseLogicExpr(InputTextStream inStream, AmountParseFlagsEnum tFlags)
        {
            ExprOp node = ParseAddExpr(inStream, tFlags);

            if (node != null && !tFlags.HasFlag(AmountParseFlagsEnum.PARSE_SINGLE))
            {
                while (true)
                {
                    OpKindEnum           kind  = OpKindEnum.LAST;
                    AmountParseFlagsEnum flags = tFlags;
                    ExprToken            tok   = NextToken(inStream, tFlags | AmountParseFlagsEnum.PARSE_OP_CONTEXT);
                    bool negate = false;

                    switch (tok.Kind)
                    {
                    case ExprTokenKind.EQUAL:
                        if (tFlags.HasFlag(AmountParseFlagsEnum.PARSE_NO_ASSIGN))
                        {
                            tok.Rewind(inStream);
                        }
                        else
                        {
                            kind = OpKindEnum.O_EQ;
                        }
                        break;

                    case ExprTokenKind.NEQUAL:
                        kind   = OpKindEnum.O_EQ;
                        negate = true;
                        break;

                    case ExprTokenKind.MATCH:
                        kind = OpKindEnum.O_MATCH;
                        break;

                    case ExprTokenKind.NMATCH:
                        kind   = OpKindEnum.O_MATCH;
                        negate = true;
                        break;

                    case ExprTokenKind.LESS:
                        kind = OpKindEnum.O_LT;
                        break;

                    case ExprTokenKind.LESSEQ:
                        kind = OpKindEnum.O_LTE;
                        break;

                    case ExprTokenKind.GREATER:
                        kind = OpKindEnum.O_GT;
                        break;

                    case ExprTokenKind.GREATEREQ:
                        kind = OpKindEnum.O_GTE;
                        break;

                    default:
                        PushToken(tok);
                        goto exitLoop;
                    }

                    if (kind != OpKindEnum.LAST)
                    {
                        ExprOp prev = node;
                        node       = new ExprOp(kind);
                        node.Left  = prev;
                        node.Right = ParseAddExpr(inStream, flags);

                        if (node.Right == null)
                        {
                            throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol));
                        }

                        if (negate)
                        {
                            prev      = node;
                            node      = new ExprOp(OpKindEnum.O_NOT);
                            node.Left = prev;
                        }
                    }
                }
            }

exitLoop:
            return(node);
        }
Пример #12
0
 public ExprParser()
 {
     Lookahead = new ExprToken();
 }