public ASTNode Parse(Token sourceToken, ParseContext context) { if (!context.Check(TokenType.Semicolon)) { return(new ReturnNode(sourceToken, context.ParseExpression())); } else { return(new ReturnNode(sourceToken, null)); } }
protected bool ParseDateTime(string s, DateTimePart part) { ParseContext context = new ParseContext(s); bool bDatePart = ( part & DateTimePart.Date ) != 0; bool bTimePart = ( part & DateTimePart.Time ) != 0; int year = 0, month = 0, day = 0; int hour = 0, minute = 0; double second = 0; eTZ = ETZ.Missing; offsetTZ = 0; if ( bDatePart ) { // parse date bool bNegative = context.CheckAndAdvance( '-' ); if ( (part & DateTimePart.Year ) != 0 ) { int digits = 0; int temp = 0; while ( context.ReadDigitAndAdvance( ref temp, 1, 9 ) ) { year = year * 10 + temp; digits += 1; temp = 0; if (digits >= 8) // overflow return false; } if ( digits < 4 ) // invalid. return false; if ( digits > 4 && year < 10000 ) return false; if (bNegative) year = -year; } if ( (part & ( DateTimePart.Month | DateTimePart.Day )) != 0 ) { if ( !context.CheckAndAdvance( '-' ) ) return false; if ( ( part & DateTimePart.Month ) != 0 ) { if ( !context.ReadDigitAndAdvance( ref month, 10, 1 ) ) return false; if ( !context.ReadDigitAndAdvance( ref month, 1, month < 10 ? 9 : 2 ) ) return false; if ( month == 0 ) return false; } if ( ( part & DateTimePart.Day ) != 0 ) { if ( !context.CheckAndAdvance( '-') ) return false; int maxFirstDigit = month != 2 ? 3 : 2; // complicate things by making them complicated. if ( !context.ReadDigitAndAdvance( ref day, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref day, 1, 9 ) ) return false; if ( day == 0 || day > 31 ) return false; if ( ( part & DateTimePart.Month ) != 0 ) { bool b1 = month <= 7; bool b2 = ( month & 1 ) == 0; // month 1, 3, 5, 7, 8, 10, 12 if ( b1 == b2 && day > 30 ) return false; // february. if ( month == 2 && day > 29 ) return false; // leap years. if ( month == 2 && ( part & DateTimePart.Year ) != 0 && ( year % 4 != 0 || year % 100 == 0 ) && year % 400 != 0 && day > 28 ) return false; } } } if ( bTimePart ) { // a 'T' must follow if ( !context.CheckAndAdvance( 'T') ) return false; } } if ( bTimePart ) { // check format here // hour from 0 to 2 if ( !context.ReadDigitAndAdvance( ref hour, 10, 2 ) ) return false; if ( !context.ReadDigitAndAdvance( ref hour, 1, hour < 20 ? 9 : 4 ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; int maxFirstDigit = hour == 24 ? 0 : 5; int maxSecondDigit = hour == 24 ? 0 : 9; if ( !context.ReadDigitAndAdvance( ref minute, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref minute, 1, maxSecondDigit ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; int secondInt = 0; if ( !context.ReadDigitAndAdvance( ref secondInt, 10, maxFirstDigit ) ) return false; if ( !context.ReadDigitAndAdvance( ref secondInt, 1, maxSecondDigit ) ) return false; second = secondInt; if ( context.CheckAndAdvance( '.' ) ) { // fraction. do whatever seems fit. int val = 0; int digits = 0; while ( context.ReadDigitAndAdvance( ref val, 1, 9) ) { val *= 10; digits += 1; if ( digits >= 8 ) // precision loss - ignore break; } if ( digits == 0 ) return false; second += val * Math.Pow( 10.0, -digits - 1 ); // skip any further digits. while ( context.ReadDigitAndAdvance( ref val, 0, 9) ) ; } } // timezone if ( context.CheckAndAdvance('Z') ) { // timezone specified, it is UTC. eTZ = ETZ.UTC; offsetTZ = 0; } else if ( context.Check('+') || context.Check('-' ) ) { // timezone offset, in hour:minute format bool bNegative = context.Check('-'); context.Advance(); // do not check the hour part, for those who are obscure. int temp = 0; if ( !context.ReadDigitAndAdvance( ref temp, 600, 9 ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 60, 9 ) ) return false; if ( !context.CheckAndAdvance( ':' ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 10, 5 ) ) return false; if ( !context.ReadDigitAndAdvance( ref temp, 1, 9 ) ) return false; eTZ = ETZ.Offset; offsetTZ = bNegative ? -temp : temp; } if ( context.IsValid() ) return false; // C# specific if (year <= 0) year = 1; if (month == 0) month = 1; bool badjust = false; if (hour == 24) { hour = 0; badjust = true; } if (day == 0) day = 1; try { myValue = new System.DateTime(year, month, day, hour, minute, (int)second, (int)(second * 1000) % 1000); if (badjust) myValue.AddDays(1); } catch { return false; } return true; }
bool ParseDateTime(string s, DateTimePart part) { ParseContext context = new ParseContext(s); bool bDatePart = (part & DateTimePart.Date) != 0; bool bTimePart = (part & DateTimePart.Time) != 0; int year = 0, month = 0, day = 0; int hour = 0, minute = 0; double second = 0; timezone = NoTimezone; if (bDatePart) { // parse date bool bNegative = context.CheckAndAdvance('-'); if ((part & DateTimePart.Year) != 0) { int digits = 0; int temp = 0; while (context.ReadDigitAndAdvance(ref temp, 1, 9)) { year = year * 10 + temp; digits += 1; temp = 0; if (digits >= 8) // overflow { return(false); } } if (digits < 4) // invalid. { return(false); } if (digits > 4 && year < 10000) { return(false); } if (bNegative) { year = -year; } } if ((part & (DateTimePart.Month | DateTimePart.Day)) != 0) { if (!context.CheckAndAdvance('-')) { return(false); } if ((part & DateTimePart.Month) != 0) { if (!context.ReadDigitAndAdvance(ref month, 10, 1)) { return(false); } if (!context.ReadDigitAndAdvance(ref month, 1, month < 10 ? 9 : 2)) { return(false); } if (month == 0) { return(false); } } if ((part & DateTimePart.Day) != 0) { if (!context.CheckAndAdvance('-')) { return(false); } int maxFirstDigit = month != 2 ? 3 : 2; // complicate things by making them complicated. if (!context.ReadDigitAndAdvance(ref day, 10, maxFirstDigit)) { return(false); } if (!context.ReadDigitAndAdvance(ref day, 1, 9)) { return(false); } if (day == 0 || day > 31) { return(false); } if ((part & DateTimePart.Month) != 0) { bool b1 = month <= 7; bool b2 = (month & 1) == 0; // month 1, 3, 5, 7, 8, 10, 12 if (b1 == b2 && day > 30) { return(false); } // february. if (month == 2 && day > 29) { return(false); } // leap years. if (month == 2 && (part & DateTimePart.Year) != 0 && (year % 4 != 0 || year % 100 == 0) && year % 400 != 0 && day > 28) { return(false); } } } } if (bTimePart) { // a 'T' must follow if (!context.CheckAndAdvance('T')) { return(false); } } } if (bTimePart) { // check format here // hour from 0 to 2 if (!context.ReadDigitAndAdvance(ref hour, 10, 2)) { return(false); } if (!context.ReadDigitAndAdvance(ref hour, 1, hour < 20 ? 9 : 4)) { return(false); } if (!context.CheckAndAdvance(':')) { return(false); } int maxFirstDigit = hour == 24 ? 0 : 5; int maxSecondDigit = hour == 24 ? 0 : 9; if (!context.ReadDigitAndAdvance(ref minute, 10, maxFirstDigit)) { return(false); } if (!context.ReadDigitAndAdvance(ref minute, 1, maxSecondDigit)) { return(false); } if (!context.CheckAndAdvance(':')) { return(false); } int secondInt = 0; if (!context.ReadDigitAndAdvance(ref secondInt, 10, maxFirstDigit)) { return(false); } if (!context.ReadDigitAndAdvance(ref secondInt, 1, maxSecondDigit)) { return(false); } second = secondInt; if (context.CheckAndAdvance('.')) { // fraction. do whatever seems fit. int val = 0; int digits = 0; while (context.ReadDigitAndAdvance(ref val, 1, 9)) { val *= 10; digits += 1; if (digits >= 8) // precision loss - ignore { break; } } if (digits == 0) { return(false); } second += val * System.Math.Pow(10.0, -digits - 1); // skip any further digits. while (context.ReadDigitAndAdvance(ref val, 0, 9)) { ; } } } // timezone if (context.CheckAndAdvance('Z')) { // timezone specified, it is UTC. timezone = 0; } else if (context.Check('+') || context.Check('-')) { // timezone offset, in hour:minute format bool bNegative = context.Check('-'); context.Advance(); // do not check the hour part, for those who are obscure. int temp = 0; if (!context.ReadDigitAndAdvance(ref temp, 600, 9)) { return(false); } if (!context.ReadDigitAndAdvance(ref temp, 60, 9)) { return(false); } if (!context.CheckAndAdvance(':')) { return(false); } if (!context.ReadDigitAndAdvance(ref temp, 10, 5)) { return(false); } if (!context.ReadDigitAndAdvance(ref temp, 1, 9)) { return(false); } timezone = (short)(bNegative ? -temp : temp); } if (context.IsValid()) { return(false); } // C# specific if (year <= 0) { year = 1; } if (month == 0) { month = 1; } bool badjust = false; if (hour == 24) { hour = 0; badjust = true; } if (day == 0) { day = 1; } if ((part & DateTimePart.Year) == 0 && month == 2 && day == 29) { year = 4; } try { myValue = new System.DateTime(year, month, day, hour, minute, (int)second, (int)(second * 1000) % 1000); if (badjust) { myValue.AddDays(1); } } catch { return(false); } return(true); }