public static bool TryParseNode(IParser parser, out DictionaryDefinitionNode defNode) { defNode = null; bool result = false; if (parser.PeekToken(TokenKind.DictionaryKeyword)) { result = true; defNode = new DictionaryDefinitionNode(); parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; defNode._location = parser.TokenLocation; if (!parser.PeekToken(TokenKind.OfKeyword)) { parser.ReportSyntaxError("Missing \"of\" keyword in dictionary 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 dictionary definition"); } } 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; FunctionTypeReference functionType; DictionaryDefinitionNode dictType; 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 (parser.LanguageVersion >= GeneroLanguageVersion.V310 && FunctionTypeReference.TryParseNode(parser, out functionType, isPublic) && functionType != null) { result = true; //defNode = new TypeReference(); //defNode.StartIndex = functionType.StartIndex; //defNode.EndIndex = functionType.EndIndex; defNode = functionType; defNode._isPublic = isPublic; //defNode.Children.Add(functionType.StartIndex, functionType); defNode.IsComplete = true; } else if (parser.LanguageVersion >= GeneroLanguageVersion.V310 && DictionaryDefinitionNode.TryParseNode(parser, out dictType) && dictType != null) { result = true; defNode = new TypeReference(); defNode.StartIndex = dictType.StartIndex; defNode.EndIndex = dictType.EndIndex; defNode._isPublic = isPublic; defNode.Children.Add(dictType.StartIndex, dictType); 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); }