public static bool TryParseNode(IParser parser, out ConstantDefinitionNode defNode, bool isPublic = false) { defNode = null; bool result = false; // parse constant definition if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { defNode = new ConstantDefinitionNode(); result = true; parser.NextToken(); defNode.StartIndex = parser.Token.Span.Start; defNode._location = parser.TokenLocation; defNode._isPublic = isPublic; defNode.Identifier = parser.Token.Token.Value.ToString(); if (parser.PeekToken(TokenCategory.Identifier) || parser.PeekToken(TokenCategory.Keyword)) { parser.NextToken(); defNode.Typename = parser.Token.Token.Value.ToString(); string typeStr; // This gets things like char(50), etc. if (TypeConstraints.VerifyValidConstraint(parser, out typeStr)) { defNode.Typename = typeStr; } } if (!parser.PeekToken(TokenKind.Equals) && !(parser.PeekToken(2) is ConstantValueToken)) { parser.ReportSyntaxError("A constant must be defined with a value."); } else { parser.NextToken(); // advance to equals if (parser.PeekToken(TokenCategory.StringLiteral)) { parser.NextToken(); defNode.Literal = string.Format("\"{0}\"", parser.Token.Token.Value.ToString()); defNode.Typename = "string"; } else if (parser.PeekToken(TokenCategory.CharacterLiteral)) { parser.NextToken(); defNode.Literal = string.Format("\'{0}\'", parser.Token.Token.Value.ToString()); defNode.Typename = "string"; } else if (parser.PeekToken(TokenKind.Subtract)) { parser.NextToken(); if (parser.PeekToken(TokenCategory.NumericLiteral)) { parser.NextToken(); defNode.Literal = string.Format("-{0}", parser.Token.Token.Value.ToString()); } } else if (parser.PeekToken(TokenCategory.NumericLiteral)) { parser.NextToken(); defNode.Literal = parser.Token.Token.Value.ToString(); } else if (parser.PeekToken(TokenCategory.IncompleteMultiLineStringLiteral)) { StringBuilder sb = new StringBuilder(parser.NextToken().Value.ToString()); while (parser.PeekToken(TokenCategory.IncompleteMultiLineStringLiteral)) { parser.NextToken(); sb.Append(parser.Token.Token.Value.ToString()); } defNode.Literal = sb.ToString(); defNode.IsComplete = true; defNode.Typename = "string"; } else if (parser.PeekToken(TokenKind.MdyKeyword)) { StringBuilder sb = new StringBuilder(parser.NextToken().Value.ToString()); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); sb.Append("("); while (!parser.PeekToken(TokenKind.Comma)) { if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier)) { parser.ReportSyntaxError("Invalid token found in MDY specification."); return(result); } sb.Append(parser.NextToken().Value.ToString()); } sb.Append(", "); parser.NextToken(); while (!parser.PeekToken(TokenKind.Comma)) { if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier)) { parser.ReportSyntaxError("Invalid token found in MDY specification."); return(result); } sb.Append(parser.NextToken().Value.ToString()); } sb.Append(", "); parser.NextToken(); while (!parser.PeekToken(TokenKind.RightParenthesis)) { if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier)) { parser.ReportSyntaxError("Invalid token found in MDY specification."); return(result); } sb.Append(parser.NextToken().Value.ToString()); } sb.Append(")"); parser.NextToken(); defNode.Literal = sb.ToString(); defNode.IsComplete = true; defNode.Typename = "date"; } else { parser.ReportSyntaxError("Date constant found with an invalid MDY expression."); } } else if (parser.PeekToken(TokenKind.DatetimeKeyword)) { StringBuilder sb = new StringBuilder(parser.NextToken().Value.ToString()); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); sb.Append("("); while (!parser.PeekToken(TokenKind.RightParenthesis)) { if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier)) { parser.ReportSyntaxError("Invalid token found in MDY specification."); return(result); } sb.Append(parser.NextToken().Value.ToString()); } sb.Append(") "); parser.NextToken(); string constraintStr; if (TypeConstraints.VerifyValidConstraint(parser, out constraintStr, TokenKind.DatetimeKeyword)) { sb.Append(constraintStr); defNode.Literal = sb.ToString(); defNode.IsComplete = true; defNode.Typename = "datetime"; } else { parser.ReportSyntaxError("Datetime constant has an invalid constraint."); } } else { parser.ReportSyntaxError("Datetime constant found with an invalid expression."); } } else if (parser.PeekToken(TokenKind.IntervalKeyword)) { StringBuilder sb = new StringBuilder(parser.NextToken().Value.ToString()); if (parser.PeekToken(TokenKind.LeftParenthesis)) { parser.NextToken(); sb.Append("("); while (!parser.PeekToken(TokenKind.RightParenthesis)) { if (parser.PeekToken(TokenCategory.Keyword) || parser.PeekToken(TokenCategory.Identifier)) { parser.ReportSyntaxError("Invalid token found in MDY specification."); return(result); } sb.Append(parser.NextToken().Value.ToString()); } sb.Append(") "); parser.NextToken(); string constraintStr; if (TypeConstraints.VerifyValidConstraint(parser, out constraintStr, TokenKind.IntervalKeyword)) { sb.Append(constraintStr); defNode.Literal = sb.ToString(); defNode.IsComplete = true; defNode.Typename = "interval"; } else { parser.ReportSyntaxError("Interval constant has an invalid constraint."); } } else { parser.ReportSyntaxError("Interval constant found with an invalid expression."); } } else { // look for the constant in the system constants var tok = parser.PeekToken(); IAnalysisResult sysConst; if (Genero4glAst.SystemConstants.TryGetValue(tok.Value.ToString(), out sysConst)) { parser.NextToken(); defNode.Literal = sysConst.Name; defNode.Typename = sysConst.Typename; } } } } return(result); }
public static bool TryParseNode(IParser parser, out ConstantDefNode defNode, out bool matchedBreakSequence, List <List <TokenKind> > breakSequences = null) { defNode = null; bool result = false; matchedBreakSequence = false; AccessModifier?accMod = null; string accModToken = null; if (parser.PeekToken(TokenKind.PublicKeyword)) { accMod = AccessModifier.Public; accModToken = parser.PeekToken().Value.ToString(); } else if (parser.PeekToken(TokenKind.PrivateKeyword)) { accMod = AccessModifier.Private; accModToken = parser.PeekToken().Value.ToString(); } uint lookAheadBy = (uint)(accMod.HasValue ? 2 : 1); if (parser.PeekToken(TokenKind.ConstantKeyword, lookAheadBy)) { result = true; defNode = new ConstantDefNode(); if (accMod.HasValue) { parser.NextToken(); defNode.AccessModifier = accMod.Value; } else { defNode.AccessModifier = AccessModifier.Public; } parser.NextToken(); // move past the Constant keyword defNode.StartIndex = parser.Token.Span.Start; ConstantDefinitionNode constDef; while (true) { if (ConstantDefinitionNode.TryParseNode(parser, out constDef, defNode.AccessModifier == AccessModifier.Public) && constDef != null) { defNode.Children.Add(constDef.StartIndex, constDef); } else { break; } if (parser.PeekToken(TokenKind.Comma)) { parser.NextToken(); } if (breakSequences != null) { bool matchedBreak = false; foreach (var seq in breakSequences) { bool bsMatch = true; uint peekaheadCount = 1; foreach (var kind in seq) { if (parser.PeekToken(kind, peekaheadCount)) { peekaheadCount++; } else { bsMatch = false; break; } } if (bsMatch) { matchedBreak = true; break; } } if (matchedBreak) { matchedBreakSequence = true; break; } } } if (defNode.Children.Count > 0 && defNode.Children.All(x => x.Value.IsComplete)) { defNode.IsComplete = true; } } return(result); }