示例#1
0
        internal VarDecl ParseForDecl(bool implied)
        {
            Token n = null;

            if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La()))
            {
                n = ConsumeAndGet();
            }
            Require(n, ErrorCode.Expected, "identifier");

            Expr init = null;

            if (Require(TokenType.ASSIGN_OP))
            {
                init = ParseExpression();
            }

            TypeExpr type = null;

            if (!implied && Expect(TokenType.AS))
            {
                type = Require(ParseType(), ErrorCode.Expected, "type");
            }

            return(implied ? new ImpliedVarDecl(n, init)
                : new VarDecl(n, null, type, init));
        }
示例#2
0
 internal IdExpr ParseId()
 {
     if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La()))
     {
         return(new IdExpr(ConsumeAndGet()));
     }
     return(null);
 }
示例#3
0
 Token RequireId()
 {
     if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La()))
     {
         return(ConsumeAndGet());
     }
     throw Error(Lt(), ErrorCode.Expected, "identifier");
 }
示例#4
0
        internal Token ParseIdName()
        {
            Token n = null;

            if (La() == TokenType.ID || TokenAttr.IsSoftKeyword(La()))
            {
                n = ConsumeAndGet();
            }
            return(n);
        }
示例#5
0
        internal NameExpr ParseQualifiedName()
        {
            NameExpr n = ParseName();

            while (La() == TokenType.DOT && (La(2) == TokenType.ID || TokenAttr.IsSoftKeyword(La(2))))
            {
                Consume();
                n = new QualifiedNameExpr(n, ParseName());
            }
            return(n);
        }
示例#6
0
        internal TypeExpr ParseType()
        {
            var t = La();

            switch (t)
            {
            case TokenType.ID:
                return(ParseTypeSuffix(ParseQualifiedName()));

            case TokenType.ARRAY:
            case TokenType.BINARY:
            case TokenType.CODEBLOCK:
            case TokenType.CURRENCY:
            case TokenType.DATE:
            case TokenType.FLOAT:
            case TokenType.PSZ:
            case TokenType.SYMBOL:
            case TokenType.USUAL:
                return(ParseTypeSuffix(new NativeTypeExpr(ConsumeAndGet())));

            case TokenType.BYTE:
            case TokenType.CHAR:
            case TokenType.DATETIME:
            case TokenType.DECIMAL:
            case TokenType.DWORD:
            case TokenType.DYNAMIC:
            case TokenType.INT:
            case TokenType.INT64:
            case TokenType.LOGIC:
            case TokenType.LONGINT:
            case TokenType.OBJECT:
            case TokenType.PTR:
            case TokenType.REAL4:
            case TokenType.REAL8:
            case TokenType.SHORTINT:
            case TokenType.STRING:
            case TokenType.UINT64:
            case TokenType.VOID:
            case TokenType.WORD:
                return(ParseTypeSuffix(new NativeTypeExpr(ConsumeAndGet())));

            default:
                if (TokenAttr.IsSoftKeyword(La()))
                {
                    return(ParseTypeSuffix(ParseQualifiedName()));
                }
                return(null);
            }
        }
示例#7
0
 internal Token ParseVarIdName()
 {
     if (La() == TokenType.ID)
     {
         return(ConsumeAndGet());
     }
     else if (La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3))))
     {
         Consume(2);
         return(ConsumeAndGet());
     }
     else if (TokenAttr.IsSoftKeyword(La()))
     {
         return(ConsumeAndGet());
     }
     return(null);
 }
示例#8
0
 internal Expr ParseFieldAlias()
 {
     if (La(2) == TokenType.ALIAS)
     {
         if (La(3) == TokenType.LPAREN || La(3) == TokenType.AMP || La(4) == TokenType.LPAREN)
         {
             return(null);
         }
         if (Expect(TokenType.FIELD))
         {
             Require(Expect(TokenType.ALIAS), ErrorCode.Expected, "->");
         }
         var alias = Require(ParseId(), ErrorCode.Expected, "name");
         if (La() == TokenType.ALIAS)
         {
             Token o     = ConsumeAndGet();
             var   field = Require(ParseId(), ErrorCode.Expected, "name");
             return((_options.AllowMemvarAlias && alias.Token.type == TokenType.M)
                 ? new MemvarExpr(new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o) as Expr
                 : new AliasExpr(new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o));
         }
         else
         {
             return(new AliasExpr(null, new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), alias.Token));
         }
     }
     if (_options.AllowMemvarAlias && La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3))))
     {
         Consume();
         var o = ConsumeAndGet();
         var v = Require(ParseId(), ErrorCode.Expected, "name");
         return(new MemvarExpr(new LiteralExpr(v.Token, TokenType.SYMBOL_CONST), o));
     }
     return(null);
 }
示例#9
0
        internal Expr ParseTerm()
        {
#if DEBUG
            if (!CanParseTerm())
            {
                return(null);
            }
#endif
            var t = La();
            switch (t)
            {
            case TokenType.ID:
                return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName())));

            case TokenType.SELF:
                return(new SelfExpr(ConsumeAndGet()));

            case TokenType.SUPER:
                return(new SuperExpr(ConsumeAndGet()));

            case TokenType.CHECKED:
            {
                var o = ConsumeAndGet();
                return(new CheckedExpr(ParseParenExpr(), o));
            }

            case TokenType.UNCHECKED:
            {
                var o = ConsumeAndGet();
                return(new UncheckedExpr(ParseParenExpr(), o));
            }

            case TokenType.TYPEOF:
            {
                var o = ConsumeAndGet();
                return(new TypeOfExpr(ParseParenType(), o));
            }

            case TokenType.SIZEOF:
            {
                var o = ConsumeAndGet();
                return(new SizeOfExpr(ParseParenType(), o));
            }

            case TokenType.DEFAULT:
            {
                var o = ConsumeAndGet();
                return(new DefaultExpr(ParseParenType(), o));
            }

            case TokenType.TRUE_CONST:
            case TokenType.FALSE_CONST:
            case TokenType.CHAR_CONST:
            case TokenType.STRING_CONST:
            case TokenType.ESCAPED_STRING_CONST:
            case TokenType.INTERPOLATED_STRING_CONST:
            case TokenType.SYMBOL_CONST:
            case TokenType.HEX_CONST:
            case TokenType.BIN_CONST:
            case TokenType.REAL_CONST:
            case TokenType.INT_CONST:
            case TokenType.DATE_CONST:
            case TokenType.DATETIME_CONST:
            case TokenType.NIL:
            case TokenType.NULL:
            case TokenType.NULL_ARRAY:
            case TokenType.NULL_CODEBLOCK:
            case TokenType.NULL_DATE:
            case TokenType.NULL_OBJECT:
            case TokenType.NULL_PSZ:
            case TokenType.NULL_PTR:
            case TokenType.NULL_STRING:
            case TokenType.NULL_SYMBOL:
                return(new LiteralExpr(ConsumeAndGet()));

            case TokenType.INCOMPLETE_STRING_CONST:
                throw Error(Lt(), ErrorCode.UnterminatedString);

            case TokenType.INVALID_NUMBER:
                throw Error(Lt(), ErrorCode.InvalidNumber);

            case TokenType.ARRAY:
            case TokenType.DATE:
            case TokenType.DATETIME:
                if (TokenAttr.IsSoftKeyword(La()) && La(2) == TokenType.LPAREN)
                {
                    return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName())));
                }
                return(ParseNativeTypeOrCast(new NativeTypeExpr(ConsumeAndGet())));

            case TokenType.CODEBLOCK:
            case TokenType.FLOAT:
            case TokenType.PSZ:
            case TokenType.SYMBOL:
            case TokenType.USUAL:
            case TokenType.BYTE:
            case TokenType.CHAR:
            case TokenType.DECIMAL:
            case TokenType.DWORD:
            case TokenType.DYNAMIC:
            case TokenType.INT:
            case TokenType.INT64:
            case TokenType.LOGIC:
            case TokenType.LONGINT:
            case TokenType.OBJECT:
            case TokenType.PTR:
            case TokenType.REAL4:
            case TokenType.REAL8:
            case TokenType.SHORTINT:
            case TokenType.STRING:
            case TokenType.UINT64:
            case TokenType.VOID:
            case TokenType.WORD:
                return(ParseNativeTypeOrCast(new NativeTypeExpr(ConsumeAndGet())));

            case TokenType.LPAREN:
                return(ParseParenExpr());

            case TokenType.LCURLY:
                return(ParseLiteralArrayOrCodeblock());

            case TokenType.LT:
                return(ParseTypedLiteralArray());

            case TokenType.IF:
            case TokenType.IIF:
                return(ParseIif());

            case TokenType.FIELD:
                return(ParseFieldAlias());

            // TODO nvk: PTR LPAREN Type=datatype COMMA Expr=expression RPAREN		#voCastPtrExpression	// PTR( typeName, expr )
            // TODO nvk: Op=(VO_AND | VO_OR | VO_XOR | VO_NOT) LPAREN Exprs+=expression (COMMA Exprs+=expression)* RPAREN							#intrinsicExpression	// _Or(expr, expr, expr)
            // TODO nvk: AMP LPAREN Expr=expression RPAREN							#macro					// &( expr )
            // TODO nvk: AMP Id=identifierName										#macro					// &id
            case TokenType.ARGLIST:
                if (_options.ParseStatements)
                {
                    throw Error(Lt(), ErrorCode.NotSupported, Lt()?.value);
                }
                else
                {
                    goto default;
                }

            case TokenType.VO_AND:
            case TokenType.VO_OR:
            case TokenType.VO_XOR:
            case TokenType.VO_NOT:
                return(ParseIntrinsicFunction());

            default:
                if (TokenAttr.IsSoftKeyword(La()))
                {
                    return(ParseFieldAlias() ?? ParseNameOrCtorCallOrSpecialFunc(ParseTypeSuffix(ParseQualifiedName())));
                }
                return(null);
            }
        }
示例#10
0
        internal bool CanParseTerm()
        {
            switch (La())
            {
            case TokenType.ID:
            case TokenType.SELF:
            case TokenType.SUPER:
            case TokenType.CHECKED:
            case TokenType.UNCHECKED:
            case TokenType.TYPEOF:
            case TokenType.SIZEOF:
            case TokenType.DEFAULT:
            case TokenType.TRUE_CONST:
            case TokenType.FALSE_CONST:
            case TokenType.CHAR_CONST:
            case TokenType.STRING_CONST:
            case TokenType.ESCAPED_STRING_CONST:
            case TokenType.INTERPOLATED_STRING_CONST:
            case TokenType.SYMBOL_CONST:
            case TokenType.HEX_CONST:
            case TokenType.BIN_CONST:
            case TokenType.REAL_CONST:
            case TokenType.INT_CONST:
            case TokenType.DATE_CONST:
            case TokenType.DATETIME_CONST:
            case TokenType.NIL:
            case TokenType.NULL:
            case TokenType.NULL_ARRAY:
            case TokenType.NULL_CODEBLOCK:
            case TokenType.NULL_DATE:
            case TokenType.NULL_OBJECT:
            case TokenType.NULL_PSZ:
            case TokenType.NULL_PTR:
            case TokenType.NULL_STRING:
            case TokenType.NULL_SYMBOL:
            case TokenType.INCOMPLETE_STRING_CONST:
            case TokenType.INVALID_NUMBER:
            case TokenType.ARRAY:
            case TokenType.CODEBLOCK:
            case TokenType.DATE:
            case TokenType.FLOAT:
            case TokenType.PSZ:
            case TokenType.SYMBOL:
            case TokenType.USUAL:
            case TokenType.BYTE:
            case TokenType.CHAR:
            case TokenType.DATETIME:
            case TokenType.DECIMAL:
            case TokenType.DWORD:
            case TokenType.DYNAMIC:
            case TokenType.INT:
            case TokenType.INT64:
            case TokenType.LOGIC:
            case TokenType.LONGINT:
            case TokenType.OBJECT:
            case TokenType.PTR:
            case TokenType.REAL4:
            case TokenType.REAL8:
            case TokenType.SHORTINT:
            case TokenType.STRING:
            case TokenType.UINT64:
            case TokenType.VOID:
            case TokenType.WORD:
            case TokenType.LPAREN:
            case TokenType.LCURLY:
            case TokenType.IIF:
            case TokenType.FIELD:
            case TokenType.VO_AND:
            case TokenType.VO_OR:
            case TokenType.VO_XOR:
            case TokenType.VO_NOT:
                return(true);

            case TokenType.ARGLIST:
                return(_options.ParseStatements);

            case TokenType.LT:
            {
                var p  = Mark();
                var la = ParseTypedLiteralArray();
                Rewind(p);
                return(la != null);
            }

            default:
                return(TokenAttr.IsSoftKeyword(La()));
            }
        }
示例#11
0
 internal Expr ParseFieldAlias()
 {
     if (La(2) == TokenType.ALIAS)
     {
         if (La(3) == TokenType.LPAREN || La(3) == TokenType.AMP || La(4) == TokenType.LPAREN)
         {
             return(null);
         }
         if (Expect(TokenType.FIELD))
         {
             Require(Expect(TokenType.ALIAS), ErrorCode.Expected, "->");
         }
         var alias = Require(ParseId(), ErrorCode.Expected, "name");
         if (La() == TokenType.ALIAS)
         {
             Token o     = ConsumeAndGet();
             var   field = Require(ParseId(), ErrorCode.Expected, "name");
             // M-> and MEMVAR-> should not become an AliasExpr
             if (alias.Token.Type == TokenType.MEMVAR ||
                 alias.Token.Type == TokenType.M ||
                 alias.Token.SourceText.ToUpper() == "MEMVAR" ||
                 alias.Token.SourceText.ToUpper() == "_MEMVAR" ||
                 alias.Token.SourceText.ToUpper() == "M")
             {
                 return(new MemvarExpr(new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o));
             }
             return(new AliasExpr(new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), new LiteralExpr(field.Token, TokenType.SYMBOL_CONST), o));
         }
         else
         {
             return(new AliasExpr(null, new LiteralExpr(alias.Token, TokenType.SYMBOL_CONST), alias.Token));
         }
     }
     if (_options.AllowMemvarAlias && La() == TokenType.M && La(2) == TokenType.DOT && (La(3) == TokenType.ID || TokenAttr.IsSoftKeyword(La(3))))
     {
         Consume();
         var o = ConsumeAndGet();
         var v = Require(ParseId(), ErrorCode.Expected, "name");
         return(new MemvarExpr(new LiteralExpr(v.Token, TokenType.SYMBOL_CONST), o));
     }
     return(null);
 }
示例#12
0
        internal SwitchStmt ParseSwitchStmt()
        {
            ExpectAny(TokenType.BEGIN, TokenType.DO);
            var t = RequireAndGet(TokenType.SWITCH);
            var e = RequireExpression();

            Require(TokenType.EOS);
            var sbs = new List <SwitchBlock>();

            sbs.Add(Require(ParseSwitchBlock(), ErrorCode.Expected, "CASE"));
            while (ParseSwitchBlock() is SwitchBlock sb)
            {
                sbs.Add(sb);
            }
            Require(TokenType.END);
            Expect(TokenType.SWITCH);
            Require(TokenType.EOS);
            return(new SwitchStmt(t, e, sbs.ToArray()));

            SwitchBlock ParseSwitchBlock()
            {
                if (La() == TokenType.CASE && (
                        (La(2) == TokenType.M && La(3) == TokenType.DOT && (La(4) == TokenType.ID || TokenAttr.IsSoftKeyword(La(4))) && La(5) == TokenType.AS) ||
                        ((La(2) == TokenType.ID || TokenAttr.IsSoftKeyword(La(2))) && La(3) == TokenType.AS)
                        ))
                {
                    var st = ConsumeAndGet();
                    var n  = RequireVarIdName();
                    Require(TokenType.AS);
                    var  ty = Require(ParseType(), ErrorCode.Expected, "type");
                    Expr wh = null;
                    if (Expect(TokenType.WHEN))
                    {
                        wh = ParseExpression();
                    }
                    Require(TokenType.EOS);
                    var s = ParseStatementBlock();
                    return(new SwitchBlockType(st, n, ty, wh, s.StmtList.Length > 0 ? s : null));
                }
                else if (La() == TokenType.CASE)
                {
                    var st = ConsumeAndGet();
                    var se = RequireExpression();
                    Require(se is LiteralExpr, ErrorCode.Expected, "literal value");
                    Expr wh = null;
                    if (Expect(TokenType.WHEN))
                    {
                        wh = ParseExpression();
                    }
                    Require(TokenType.EOS);
                    var s = ParseStatementBlock();
                    return(new SwitchBlockExpr(st, se, wh, s.StmtList.Length > 0 ? s : null));
                }
                else if (La() == TokenType.OTHERWISE)
                {
                    var st = ConsumeAndGet();
                    Require(TokenType.EOS);
                    var s = ParseStatementBlock();
                    return(new SwitchBlock(st, s.StmtList.Length > 0 ? s : null));
                }
                else
                {
                    return(null);
                }
            }
        }