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); }
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); }
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); }
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); }