コード例 #1
0
ファイル: AttributeSpecifier.cs プロジェクト: rkhjjs/VSGenero
        public static bool TryParseNode(IParser parser, out AttributeSpecifier node)
        {
            node = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.AttributeKeyword) ||
                parser.PeekToken(TokenKind.AttributesKeyword))
            {
                result = true;
                node   = new AttributeSpecifier();
                parser.NextToken();
                node.StartIndex = parser.Token.Span.Start;

                if (!parser.PeekToken(TokenKind.LeftParenthesis))
                {
                    parser.ReportSyntaxError("Invalid attribute specifier found.");
                }
                else
                {
                    while (!parser.PeekToken(TokenKind.RightParenthesis))
                    {
                        node.SpecifierTokens.Add(parser.NextToken());
                        if (parser.PeekToken(TokenKind.EndOfFile))
                        {
                            parser.ReportSyntaxError("Unexpected end of attribute specifier.");
                            return(result);
                        }
                    }
                    if (parser.PeekToken(TokenKind.RightParenthesis))
                    {
                        parser.NextToken();
                    }
                    node.EndIndex   = parser.Token.Span.End;
                    node.IsComplete = true;
                }
            }

            return(result);
        }
コード例 #2
0
        public static bool TryParseNode(IParser parser, out ArrayTypeReference defNode)
        {
            defNode = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.DynamicKeyword))
            {
                result            = true;
                defNode           = new ArrayTypeReference();
                defNode.ArrayType = ArrayType.Dynamic;
                parser.NextToken();
                defNode.StartIndex = parser.Token.Span.Start;
                defNode._location  = parser.TokenLocation;

                if (!parser.PeekToken(TokenKind.ArrayKeyword))
                {
                    parser.ReportSyntaxError("Missing \"array\" keyword after \"dynamic\" array keyword.");
                }
                else
                {
                    parser.NextToken();
                }

                AttributeSpecifier attribSpec;
                if (AttributeSpecifier.TryParseNode(parser, out attribSpec))
                {
                    defNode.Attribute = attribSpec;
                }

                // [WITH DIMENSION rank] is optional
                if (parser.PeekToken(TokenKind.WithKeyword))
                {
                    parser.NextToken();
                    if (parser.PeekToken(TokenKind.DimensionKeyword))
                    {
                        parser.NextToken();
                        if (parser.PeekToken(TokenCategory.NumericLiteral))
                        {
                            var tok = parser.NextToken() as ConstantValueToken;
                            if (tok != null)
                            {
                                uint   intVal;
                                string val = tok.Value.ToString();
                                if (uint.TryParse(val, out intVal))
                                {
                                    if (intVal >= 1 && intVal <= 3)
                                    {
                                        defNode.DynamicArrayDimension = intVal;
                                    }
                                    else
                                    {
                                        parser.ReportSyntaxError("A dynamic array's dimension can be 1, 2, or 3.");
                                    }
                                }
                                else
                                {
                                    parser.ReportSyntaxError("Invalid array dimension found.");
                                }
                            }
                            else
                            {
                                parser.ReportSyntaxError("Invalid token found.");
                            }
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid dimension specifier for dynamic array.");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("\"dimension\" keyword not specified for dynamic array");
                    }
                }

                if (!parser.PeekToken(TokenKind.OfKeyword))
                {
                    parser.ReportSyntaxError("Missing \"of\" keyword in array definition.");
                }
                else
                {
                    parser.NextToken();
                }

                // now try to get the datatype
                TypeReference typeRef;
                if ((TypeReference.TryParseNode(parser, out typeRef) && typeRef != null))
                {
                    defNode.Children.Add(typeRef.StartIndex, typeRef);
                    defNode.EndIndex = typeRef.EndIndex;
                }
                else
                {
                    parser.ReportSyntaxError("Invalid type specified for dynamic array definition");
                }
            }
            else if (parser.PeekToken(TokenKind.ArrayKeyword))
            {
                result  = true;
                defNode = new ArrayTypeReference();
                parser.NextToken();
                defNode.StartIndex = parser.Token.Span.Start;
                defNode._location  = parser.TokenLocation;

                if (!parser.PeekToken(TokenKind.LeftBracket))
                {
                    parser.ReportSyntaxError("A non-dynamic array definition must have brackets.");
                }
                else
                {
                    parser.NextToken();
                }

                if (parser.PeekToken(TokenKind.RightBracket))
                {
                    // we should have a java array
                    defNode.ArrayType = ArrayType.Java;
                    parser.NextToken();

                    AttributeSpecifier attribSpec;
                    if (AttributeSpecifier.TryParseNode(parser, out attribSpec))
                    {
                        defNode.Attribute = attribSpec;
                    }

                    if (!parser.PeekToken(TokenKind.OfKeyword))
                    {
                        parser.ReportSyntaxError("Missing \"of\" keyword in array definition.");
                    }
                    else
                    {
                        parser.NextToken();
                    }

                    // now try to get the datatype
                    TypeReference typeRef;
                    if ((TypeReference.TryParseNode(parser, out typeRef) && typeRef != null))
                    {
                        defNode.Children.Add(typeRef.StartIndex, typeRef);
                        defNode.EndIndex = typeRef.EndIndex;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid type specified for java array definition");
                    }
                }
                else
                {
                    defNode.ArrayType = ArrayType.Static;
                    List <TokenKind> breakToks = new List <TokenKind> {
                        TokenKind.Comma, TokenKind.RightBracket
                    };
                    // get the first-dimension size
                    ExpressionNode dimensionExpr;
                    if (!FglExpressionNode.TryGetExpressionNode(parser, out dimensionExpr, breakToks))
                    {
                        parser.ReportSyntaxError("Array's first dimension size is invalid");
                    }
                    else
                    {
                        defNode.StaticDimOneSize = dimensionExpr;
                    }

                    if (parser.PeekToken(TokenKind.Comma))
                    {
                        parser.NextToken();

                        if (!FglExpressionNode.TryGetExpressionNode(parser, out dimensionExpr, breakToks))
                        {
                            parser.ReportSyntaxError("Array's second dimension size is invalid");
                        }
                        else
                        {
                            defNode.StaticDimTwoSize = dimensionExpr;
                        }

                        if (parser.PeekToken(TokenKind.Comma))
                        {
                            parser.NextToken();

                            if (!FglExpressionNode.TryGetExpressionNode(parser, out dimensionExpr, breakToks))
                            {
                                parser.ReportSyntaxError("Array's third dimension size is invalid");
                            }
                            else
                            {
                                defNode.StaticDimThreeSize = dimensionExpr;
                            }
                        }
                    }

                    if (!parser.PeekToken(TokenKind.RightBracket))
                    {
                        parser.ReportSyntaxError("Invalid end of static array dimension specifier.");
                    }
                    else
                    {
                        parser.NextToken();
                    }

                    AttributeSpecifier attribSpec;
                    if (AttributeSpecifier.TryParseNode(parser, out attribSpec))
                    {
                        defNode.Attribute = attribSpec;
                    }

                    if (!parser.PeekToken(TokenKind.OfKeyword))
                    {
                        parser.ReportSyntaxError("Missing \"of\" keyword in array definition.");
                    }
                    else
                    {
                        parser.NextToken();
                    }

                    // now try to get the datatype
                    TypeReference typeRef;
                    if ((TypeReference.TryParseNode(parser, out typeRef) && typeRef != null))
                    {
                        defNode.Children.Add(typeRef.StartIndex, typeRef);
                        defNode.EndIndex   = typeRef.EndIndex;
                        defNode.IsComplete = true;
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid type specified for static array definition");
                    }
                }
            }
            return(result);
        }
コード例 #3
0
        public new static bool TryParseNode(IParser parser, out RecordDefinitionNode defNode, bool isPublic = false)
        {
            defNode = null;
            bool result = false;

            if (parser.PeekToken(TokenKind.RecordKeyword))
            {
                result             = true;
                defNode            = new RecordDefinitionNode();
                defNode.StartIndex = parser.Token.Span.Start;
                defNode.Location   = parser.TokenLocation;
                defNode._isPublic  = isPublic;
                parser.NextToken();     // move past the record keyword
                if (parser.PeekToken(TokenKind.LikeKeyword))
                {
                    // get db info
                    parser.NextToken();
                    if (!parser.PeekToken(TokenCategory.Identifier) && parser.PeekToken(TokenKind.Colon, 2))
                    {
                        parser.NextToken(); // advance to the database name
                        defNode.MimicDatabaseName = parser.Token.Token.Value.ToString();
                        parser.NextToken(); // advance to the colon
                    }
                    FglNameExpression tableName;
                    if (FglNameExpression.TryParseNode(parser, out tableName))
                    {
                        defNode.MimicTableName = tableName;
                        if (!tableName.Name.EndsWith(".*"))
                        {
                            parser.ReportSyntaxError("A mimicking record must reference a table as follows: \"[tablename].*\".");
                        }
                    }
                    else
                    {
                        parser.ReportSyntaxError("Invalid database table name found in record definition.");
                    }
                }
                else
                {
                    AttributeSpecifier attribSpec;
                    if (AttributeSpecifier.TryParseNode(parser, out attribSpec))
                    {
                        defNode.Attribute = attribSpec;
                    }

                    bool          advance = true;
                    TokenWithSpan tok     = default(TokenWithSpan);
                    while (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword))
                    {
                        //if (advance)
                        //{

                        parser.NextToken();
                        tok = parser.Token;
                        //}
                        //else
                        //{
                        //    // reset
                        //    tok = parser.Token.Token;
                        //    advance = true;
                        //}

                        TypeReference tr;
                        if (TypeReference.TryParseNode(parser, out tr, true))
                        {
                            if (!defNode.MemberDictionary.ContainsKey(tok.Token.Value.ToString()))
                            {
                                defNode.MemberDictionary.Add(tok.Token.Value.ToString(), new VariableDef(tok.Token.Value.ToString(), tr, tok.Span.Start, true, defNode.Location?.FilePath));
                            }
                            else
                            {
                                parser.ReportSyntaxError(string.Format("Record field {0} defined more than once.", tok.Token.Value.ToString()), Severity.Error);
                            }
                        }

                        AttributeSpecifier.TryParseNode(parser, out attribSpec);

                        if (parser.MaybeEat(TokenKind.Comma))
                        {
                            //advance = false;
                            continue;
                        }
                        else if (parser.MaybeEat(TokenKind.EndKeyword))
                        {
                            if (!parser.MaybeEat(TokenKind.RecordKeyword))
                            {
                                parser.ReportSyntaxError("Invalid end token in record definition");
                            }
                            else
                            {
                                defNode.EndIndex   = parser.Token.Span.End;
                                defNode.IsComplete = true;
                            }
                            break;
                        }
                        else
                        {
                            parser.ReportSyntaxError("Invalid token within record definition");
                            break;
                        }
                    }
                }
            }

            return(result);
        }
コード例 #4
0
ファイル: TypeReference.cs プロジェクト: foxerfly/VSGenero
        public static bool TryParseNode(IParser parser, out TypeReference defNode, bool mimickingRecord = false, bool isPublic = false)
        {
            defNode = null;
            bool result = false;

            ArrayTypeReference   arrayType;
            RecordDefinitionNode recordDef;

            if (ArrayTypeReference.TryParseNode(parser, out arrayType) && arrayType != null)
            {
                result             = true;
                defNode            = new TypeReference();
                defNode.StartIndex = arrayType.StartIndex;
                defNode.EndIndex   = arrayType.EndIndex;
                defNode._isPublic  = isPublic;
                defNode.Children.Add(arrayType.StartIndex, arrayType);
                defNode.IsComplete = true;
            }
            else if (RecordDefinitionNode.TryParseNode(parser, out recordDef, isPublic) && recordDef != null)
            {
                result             = true;
                defNode            = new TypeReference();
                defNode.StartIndex = recordDef.StartIndex;
                defNode.EndIndex   = recordDef.EndIndex;
                defNode._isPublic  = isPublic;
                defNode.Children.Add(recordDef.StartIndex, recordDef);
                defNode.IsComplete = true;
            }
            else if (parser.PeekToken(TokenKind.LikeKeyword))
            {
                result = true;
                parser.NextToken();
                defNode            = new TypeReference();
                defNode.StartIndex = parser.Token.Span.Start;
                defNode._isPublic  = isPublic;

                // get db info
                if (!parser.PeekToken(TokenCategory.Identifier) && parser.PeekToken(TokenKind.Colon, 2))
                {
                    parser.NextToken(); // advance to the database name
                    defNode.DatabaseName = parser.Token.Token.Value.ToString();
                    parser.NextToken(); // advance to the colon
                }
                if (!parser.PeekToken(TokenCategory.Identifier))
                {
                    parser.ReportSyntaxError("Database table name expected.");
                }
                else if (!parser.PeekToken(TokenKind.Dot, 2) && !parser.PeekToken(TokenCategory.Identifier))
                {
                    parser.ReportSyntaxError("A mimicking type must reference a table as follows: \"[tablename].[recordname]\".");
                }
                else
                {
                    parser.NextToken(); // advance to the table name
                    defNode.TableName = parser.Token.Token.Value.ToString();
                    parser.NextToken(); // advance to the dot
                    if (parser.Token.Token.Kind == TokenKind.Dot)
                    {
                        if (parser.PeekToken(TokenKind.Multiply) ||
                            parser.PeekToken(TokenCategory.Identifier) ||
                            parser.PeekToken(TokenCategory.Keyword))
                        {
                            parser.NextToken(); // advance to the column name
                            defNode.ColumnName = parser.Token.Token.Value.ToString();
                            if (!mimickingRecord && defNode.ColumnName == "*")
                            {
                                parser.ReportSyntaxError("A variable cannot mimic an entire table without being a record. The variable must be defined as a mimicking record.");
                            }
                            defNode.IsComplete = true;
                            defNode.EndIndex   = parser.Token.Span.End;
                        }
                        else
                        {
                            if (mimickingRecord)
                            {
                                parser.ReportSyntaxError("A mimicking variable must use the format \"like table.*\"");
                            }
                            else
                            {
                                parser.ReportSyntaxError("A mimicking variable must use the format \"like table.column\"");
                            }
                        }
                    }
                    else
                    {
                        if (mimickingRecord)
                        {
                            parser.ReportSyntaxError("A mimicking variable must use the format \"like table.*\"");
                        }
                        else
                        {
                            parser.ReportSyntaxError("A mimicking variable must use the format \"like table.column\"");
                        }
                    }
                }
            }
            else
            {
                var tok = parser.PeekToken();
                var cat = Tokenizer.GetTokenInfo(tok).Category;
                if (cat == TokenCategory.Keyword || cat == TokenCategory.Identifier)
                {
                    StringBuilder sb = new StringBuilder();
                    result = true;
                    parser.NextToken();
                    defNode            = new TypeReference();
                    defNode.StartIndex = parser.Token.Span.Start;
                    sb.Append(parser.Token.Token.Value.ToString());

                    // determine if there are any constraints on the type keyword
                    string typeString;
                    if (TypeConstraints.VerifyValidConstraint(parser, out typeString))
                    {
                        defNode._typeNameString    = typeString;
                        defNode._isConstrainedType = true;
                    }
                    else
                    {
                        // see if we're referencing an extension type (dotted name)
                        while (parser.PeekToken(TokenKind.Dot))
                        {
                            sb.Append(parser.NextToken().Value.ToString());
                            if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier))
                            {
                                sb.Append(parser.NextToken().Value.ToString());
                            }
                            else
                            {
                                parser.ReportSyntaxError("Unexpected token in type reference.");
                            }
                        }
                        defNode._typeNameString = sb.ToString();
                    }

                    AttributeSpecifier attribSpec;
                    if (AttributeSpecifier.TryParseNode(parser, out attribSpec))
                    {
                        defNode.Attribute = attribSpec;
                    }

                    defNode.EndIndex   = parser.Token.Span.End;
                    defNode.IsComplete = true;
                }
                else if (cat == TokenCategory.EndOfStream)
                {
                    parser.ReportSyntaxError("Unexpected end of type definition");
                    result = false;
                }
            }

            return(result);
        }