diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2009-10-19 20:20:09 -0400 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2009-10-19 20:20:09 -0400 |
commit | 2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535 (patch) | |
tree | da9c93d2f87df6d2b688a455a31e69859117ba1e /google_appengine/google/appengine/cron | |
download | FramedPrototype-2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535.tar.xz FramedPrototype-2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535.zip |
Initial import.
Diffstat (limited to 'google_appengine/google/appengine/cron')
-rwxr-xr-x | google_appengine/google/appengine/cron/GrocLexer.py | 1669 | ||||
-rw-r--r-- | google_appengine/google/appengine/cron/GrocLexer.pyc | bin | 0 -> 22472 bytes | |||
-rwxr-xr-x | google_appengine/google/appengine/cron/GrocParser.py | 1008 | ||||
-rw-r--r-- | google_appengine/google/appengine/cron/GrocParser.pyc | bin | 0 -> 18129 bytes | |||
-rwxr-xr-x | google_appengine/google/appengine/cron/__init__.py | 17 | ||||
-rw-r--r-- | google_appengine/google/appengine/cron/__init__.pyc | bin | 0 -> 222 bytes | |||
-rwxr-xr-x | google_appengine/google/appengine/cron/groc.py | 74 | ||||
-rw-r--r-- | google_appengine/google/appengine/cron/groc.pyc | bin | 0 -> 2413 bytes | |||
-rwxr-xr-x | google_appengine/google/appengine/cron/groctimespecification.py | 304 | ||||
-rw-r--r-- | google_appengine/google/appengine/cron/groctimespecification.pyc | bin | 0 -> 10574 bytes |
10 files changed, 3072 insertions, 0 deletions
diff --git a/google_appengine/google/appengine/cron/GrocLexer.py b/google_appengine/google/appengine/cron/GrocLexer.py new file mode 100755 index 0000000..7224334 --- /dev/null +++ b/google_appengine/google/appengine/cron/GrocLexer.py @@ -0,0 +1,1669 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import sys +from antlr3 import * +from antlr3.compat import set, frozenset + + +HIDDEN = BaseRecognizer.HIDDEN + +THIRD=12 +SEPTEMBER=35 +FOURTH=13 +SECOND=11 +WEDNESDAY=21 +NOVEMBER=37 +SATURDAY=24 +JULY=33 +APRIL=30 +DIGITS=8 +OCTOBER=36 +MAY=31 +EVERY=6 +FEBRUARY=28 +MONDAY=19 +SUNDAY=25 +DAY=18 +JUNE=32 +OF=4 +MARCH=29 +EOF=-1 +JANUARY=27 +MONTH=26 +FRIDAY=23 +MINUTES=17 +FIFTH=14 +TIME=5 +WS=40 +QUARTER=39 +THURSDAY=22 +COMMA=9 +DECEMBER=38 +AUGUST=34 +DIGIT=7 +TUESDAY=20 +HOURS=16 +FOURTH_OR_FIFTH=15 +FIRST=10 + + +class GrocLexer(Lexer): + + grammarFileName = "Groc.g" + antlr_version = version_str_to_tuple("3.1.1") + antlr_version_str = "3.1.1" + + def __init__(self, input=None, state=None): + if state is None: + state = RecognizerSharedState() + Lexer.__init__(self, input, state) + + self.dfa25 = self.DFA25( + self, 25, + eot = self.DFA25_eot, + eof = self.DFA25_eof, + min = self.DFA25_min, + max = self.DFA25_max, + accept = self.DFA25_accept, + special = self.DFA25_special, + transition = self.DFA25_transition + ) + + + + + + + def mTIME(self, ): + + try: + _type = TIME + _channel = DEFAULT_CHANNEL + + pass + alt1 = 4 + LA1 = self.input.LA(1) + if LA1 == 48: + LA1_1 = self.input.LA(2) + + if (LA1_1 == 58) : + alt1 = 1 + elif ((48 <= LA1_1 <= 57)) : + alt1 = 2 + else: + nvae = NoViableAltException("", 1, 1, self.input) + + raise nvae + + elif LA1 == 49: + LA1_2 = self.input.LA(2) + + if (LA1_2 == 58) : + alt1 = 1 + elif ((48 <= LA1_2 <= 57)) : + alt1 = 3 + else: + nvae = NoViableAltException("", 1, 2, self.input) + + raise nvae + + elif LA1 == 50: + LA1_3 = self.input.LA(2) + + if ((48 <= LA1_3 <= 51)) : + alt1 = 4 + elif (LA1_3 == 58) : + alt1 = 1 + else: + nvae = NoViableAltException("", 1, 3, self.input) + + raise nvae + + elif LA1 == 51 or LA1 == 52 or LA1 == 53 or LA1 == 54 or LA1 == 55 or LA1 == 56 or LA1 == 57: + alt1 = 1 + else: + nvae = NoViableAltException("", 1, 0, self.input) + + raise nvae + + if alt1 == 1: + pass + self.mDIGIT() + + + elif alt1 == 2: + pass + pass + self.match(48) + self.mDIGIT() + + + + + + elif alt1 == 3: + pass + pass + self.match(49) + self.mDIGIT() + + + + + + elif alt1 == 4: + pass + pass + self.match(50) + self.matchRange(48, 51) + + + + + + + self.match(58) + pass + self.matchRange(48, 53) + self.mDIGIT() + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFIRST(self, ): + + try: + _type = FIRST + _channel = DEFAULT_CHANNEL + + pass + alt2 = 2 + LA2_0 = self.input.LA(1) + + if (LA2_0 == 49) : + alt2 = 1 + elif (LA2_0 == 102) : + alt2 = 2 + else: + nvae = NoViableAltException("", 2, 0, self.input) + + raise nvae + + if alt2 == 1: + pass + self.match("1st") + + + elif alt2 == 2: + pass + self.match("first") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mSECOND(self, ): + + try: + _type = SECOND + _channel = DEFAULT_CHANNEL + + pass + alt3 = 2 + LA3_0 = self.input.LA(1) + + if (LA3_0 == 50) : + alt3 = 1 + elif (LA3_0 == 115) : + alt3 = 2 + else: + nvae = NoViableAltException("", 3, 0, self.input) + + raise nvae + + if alt3 == 1: + pass + self.match("2nd") + + + elif alt3 == 2: + pass + self.match("second") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mTHIRD(self, ): + + try: + _type = THIRD + _channel = DEFAULT_CHANNEL + + pass + alt4 = 2 + LA4_0 = self.input.LA(1) + + if (LA4_0 == 51) : + alt4 = 1 + elif (LA4_0 == 116) : + alt4 = 2 + else: + nvae = NoViableAltException("", 4, 0, self.input) + + raise nvae + + if alt4 == 1: + pass + self.match("3rd") + + + elif alt4 == 2: + pass + self.match("third") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFOURTH(self, ): + + try: + _type = FOURTH + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("4th") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFIFTH(self, ): + + try: + _type = FIFTH + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("5th") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFOURTH_OR_FIFTH(self, ): + + try: + _type = FOURTH_OR_FIFTH + _channel = DEFAULT_CHANNEL + + pass + alt5 = 2 + LA5_0 = self.input.LA(1) + + if (LA5_0 == 102) : + LA5_1 = self.input.LA(2) + + if (LA5_1 == 111) : + alt5 = 1 + elif (LA5_1 == 105) : + alt5 = 2 + else: + nvae = NoViableAltException("", 5, 1, self.input) + + raise nvae + + else: + nvae = NoViableAltException("", 5, 0, self.input) + + raise nvae + + if alt5 == 1: + pass + pass + self.match("fourth") + _type = FOURTH; + + + + + + elif alt5 == 2: + pass + pass + self.match("fifth") + _type = FIFTH; + + + + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mDAY(self, ): + + try: + _type = DAY + _channel = DEFAULT_CHANNEL + + pass + self.match("day") + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mMONDAY(self, ): + + try: + _type = MONDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("mon") + alt6 = 2 + LA6_0 = self.input.LA(1) + + if (LA6_0 == 100) : + alt6 = 1 + if alt6 == 1: + pass + self.match("day") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mTUESDAY(self, ): + + try: + _type = TUESDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("tue") + alt7 = 2 + LA7_0 = self.input.LA(1) + + if (LA7_0 == 115) : + alt7 = 1 + if alt7 == 1: + pass + self.match("sday") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mWEDNESDAY(self, ): + + try: + _type = WEDNESDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("wed") + alt8 = 2 + LA8_0 = self.input.LA(1) + + if (LA8_0 == 110) : + alt8 = 1 + if alt8 == 1: + pass + self.match("nesday") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mTHURSDAY(self, ): + + try: + _type = THURSDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("thu") + alt9 = 2 + LA9_0 = self.input.LA(1) + + if (LA9_0 == 114) : + alt9 = 1 + if alt9 == 1: + pass + self.match("rsday") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFRIDAY(self, ): + + try: + _type = FRIDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("fri") + alt10 = 2 + LA10_0 = self.input.LA(1) + + if (LA10_0 == 100) : + alt10 = 1 + if alt10 == 1: + pass + self.match("day") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mSATURDAY(self, ): + + try: + _type = SATURDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("sat") + alt11 = 2 + LA11_0 = self.input.LA(1) + + if (LA11_0 == 117) : + alt11 = 1 + if alt11 == 1: + pass + self.match("urday") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mSUNDAY(self, ): + + try: + _type = SUNDAY + _channel = DEFAULT_CHANNEL + + pass + self.match("sun") + alt12 = 2 + LA12_0 = self.input.LA(1) + + if (LA12_0 == 100) : + alt12 = 1 + if alt12 == 1: + pass + self.match("day") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mJANUARY(self, ): + + try: + _type = JANUARY + _channel = DEFAULT_CHANNEL + + pass + self.match("jan") + alt13 = 2 + LA13_0 = self.input.LA(1) + + if (LA13_0 == 117) : + alt13 = 1 + if alt13 == 1: + pass + self.match("uary") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mFEBRUARY(self, ): + + try: + _type = FEBRUARY + _channel = DEFAULT_CHANNEL + + pass + self.match("feb") + alt14 = 2 + LA14_0 = self.input.LA(1) + + if (LA14_0 == 114) : + alt14 = 1 + if alt14 == 1: + pass + self.match("ruary") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mMARCH(self, ): + + try: + _type = MARCH + _channel = DEFAULT_CHANNEL + + pass + self.match("mar") + alt15 = 2 + LA15_0 = self.input.LA(1) + + if (LA15_0 == 99) : + alt15 = 1 + if alt15 == 1: + pass + self.match("ch") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mAPRIL(self, ): + + try: + _type = APRIL + _channel = DEFAULT_CHANNEL + + pass + self.match("apr") + alt16 = 2 + LA16_0 = self.input.LA(1) + + if (LA16_0 == 105) : + alt16 = 1 + if alt16 == 1: + pass + self.match("il") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mMAY(self, ): + + try: + _type = MAY + _channel = DEFAULT_CHANNEL + + pass + self.match("may") + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mJUNE(self, ): + + try: + _type = JUNE + _channel = DEFAULT_CHANNEL + + pass + self.match("jun") + alt17 = 2 + LA17_0 = self.input.LA(1) + + if (LA17_0 == 101) : + alt17 = 1 + if alt17 == 1: + pass + self.match(101) + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mJULY(self, ): + + try: + _type = JULY + _channel = DEFAULT_CHANNEL + + pass + self.match("jul") + alt18 = 2 + LA18_0 = self.input.LA(1) + + if (LA18_0 == 121) : + alt18 = 1 + if alt18 == 1: + pass + self.match(121) + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mAUGUST(self, ): + + try: + _type = AUGUST + _channel = DEFAULT_CHANNEL + + pass + self.match("aug") + alt19 = 2 + LA19_0 = self.input.LA(1) + + if (LA19_0 == 117) : + alt19 = 1 + if alt19 == 1: + pass + self.match("ust") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mSEPTEMBER(self, ): + + try: + _type = SEPTEMBER + _channel = DEFAULT_CHANNEL + + pass + self.match("sep") + alt20 = 2 + LA20_0 = self.input.LA(1) + + if (LA20_0 == 116) : + alt20 = 1 + if alt20 == 1: + pass + self.match("tember") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mOCTOBER(self, ): + + try: + _type = OCTOBER + _channel = DEFAULT_CHANNEL + + pass + self.match("oct") + alt21 = 2 + LA21_0 = self.input.LA(1) + + if (LA21_0 == 111) : + alt21 = 1 + if alt21 == 1: + pass + self.match("ober") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mNOVEMBER(self, ): + + try: + _type = NOVEMBER + _channel = DEFAULT_CHANNEL + + pass + self.match("nov") + alt22 = 2 + LA22_0 = self.input.LA(1) + + if (LA22_0 == 101) : + alt22 = 1 + if alt22 == 1: + pass + self.match("ember") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mDECEMBER(self, ): + + try: + _type = DECEMBER + _channel = DEFAULT_CHANNEL + + pass + self.match("dec") + alt23 = 2 + LA23_0 = self.input.LA(1) + + if (LA23_0 == 101) : + alt23 = 1 + if alt23 == 1: + pass + self.match("ember") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mMONTH(self, ): + + try: + _type = MONTH + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("month") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mQUARTER(self, ): + + try: + _type = QUARTER + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("quarter") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mEVERY(self, ): + + try: + _type = EVERY + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("every") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mHOURS(self, ): + + try: + _type = HOURS + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("hours") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mMINUTES(self, ): + + try: + _type = MINUTES + _channel = DEFAULT_CHANNEL + + pass + alt24 = 2 + LA24_0 = self.input.LA(1) + + if (LA24_0 == 109) : + LA24_1 = self.input.LA(2) + + if (LA24_1 == 105) : + LA24_2 = self.input.LA(3) + + if (LA24_2 == 110) : + LA24_3 = self.input.LA(4) + + if (LA24_3 == 115) : + alt24 = 1 + elif (LA24_3 == 117) : + alt24 = 2 + else: + nvae = NoViableAltException("", 24, 3, self.input) + + raise nvae + + else: + nvae = NoViableAltException("", 24, 2, self.input) + + raise nvae + + else: + nvae = NoViableAltException("", 24, 1, self.input) + + raise nvae + + else: + nvae = NoViableAltException("", 24, 0, self.input) + + raise nvae + + if alt24 == 1: + pass + self.match("mins") + + + elif alt24 == 2: + pass + self.match("minutes") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mCOMMA(self, ): + + try: + _type = COMMA + _channel = DEFAULT_CHANNEL + + pass + pass + self.match(44) + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mOF(self, ): + + try: + _type = OF + _channel = DEFAULT_CHANNEL + + pass + pass + self.match("of") + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mWS(self, ): + + try: + _type = WS + _channel = DEFAULT_CHANNEL + + pass + if (9 <= self.input.LA(1) <= 10) or self.input.LA(1) == 13 or self.input.LA(1) == 32: + self.input.consume() + else: + mse = MismatchedSetException(None, self.input) + self.recover(mse) + raise mse + + _channel=HIDDEN; + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mDIGIT(self, ): + + try: + _type = DIGIT + _channel = DEFAULT_CHANNEL + + pass + pass + self.matchRange(48, 57) + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mDIGITS(self, ): + + try: + _type = DIGITS + _channel = DEFAULT_CHANNEL + + pass + pass + self.mDIGIT() + self.mDIGIT() + + + + + + + self._state.type = _type + self._state.channel = _channel + + finally: + + pass + + + + + def mTokens(self): + alt25 = 37 + alt25 = self.dfa25.predict(self.input) + if alt25 == 1: + pass + self.mTIME() + + + elif alt25 == 2: + pass + self.mFIRST() + + + elif alt25 == 3: + pass + self.mSECOND() + + + elif alt25 == 4: + pass + self.mTHIRD() + + + elif alt25 == 5: + pass + self.mFOURTH() + + + elif alt25 == 6: + pass + self.mFIFTH() + + + elif alt25 == 7: + pass + self.mFOURTH_OR_FIFTH() + + + elif alt25 == 8: + pass + self.mDAY() + + + elif alt25 == 9: + pass + self.mMONDAY() + + + elif alt25 == 10: + pass + self.mTUESDAY() + + + elif alt25 == 11: + pass + self.mWEDNESDAY() + + + elif alt25 == 12: + pass + self.mTHURSDAY() + + + elif alt25 == 13: + pass + self.mFRIDAY() + + + elif alt25 == 14: + pass + self.mSATURDAY() + + + elif alt25 == 15: + pass + self.mSUNDAY() + + + elif alt25 == 16: + pass + self.mJANUARY() + + + elif alt25 == 17: + pass + self.mFEBRUARY() + + + elif alt25 == 18: + pass + self.mMARCH() + + + elif alt25 == 19: + pass + self.mAPRIL() + + + elif alt25 == 20: + pass + self.mMAY() + + + elif alt25 == 21: + pass + self.mJUNE() + + + elif alt25 == 22: + pass + self.mJULY() + + + elif alt25 == 23: + pass + self.mAUGUST() + + + elif alt25 == 24: + pass + self.mSEPTEMBER() + + + elif alt25 == 25: + pass + self.mOCTOBER() + + + elif alt25 == 26: + pass + self.mNOVEMBER() + + + elif alt25 == 27: + pass + self.mDECEMBER() + + + elif alt25 == 28: + pass + self.mMONTH() + + + elif alt25 == 29: + pass + self.mQUARTER() + + + elif alt25 == 30: + pass + self.mEVERY() + + + elif alt25 == 31: + pass + self.mHOURS() + + + elif alt25 == 32: + pass + self.mMINUTES() + + + elif alt25 == 33: + pass + self.mCOMMA() + + + elif alt25 == 34: + pass + self.mOF() + + + elif alt25 == 35: + pass + self.mWS() + + + elif alt25 == 36: + pass + self.mDIGIT() + + + elif alt25 == 37: + pass + self.mDIGITS() + + + + + + + + + DFA25_eot = DFA.unpack( + u"\1\uffff\4\30\2\uffff\1\30\1\uffff\2\30\14\uffff\1\36\3\uffff\2" + u"\36\33\uffff\1\76\6\uffff" + ) + + DFA25_eof = DFA.unpack( + u"\77\uffff" + ) + + DFA25_min = DFA.unpack( + u"\1\11\4\60\1\145\1\141\1\60\1\150\2\60\2\141\1\uffff\1\141\1\160" + u"\1\143\6\uffff\1\72\3\uffff\2\72\3\uffff\1\146\3\uffff\1\143\3" + u"\uffff\1\151\4\uffff\1\156\1\162\2\uffff\1\154\6\uffff\1\164\6" + u"\uffff" + ) + + DFA25_max = DFA.unpack( + u"\1\167\1\72\1\163\1\156\2\162\1\165\1\164\1\165\1\164\1\72\1\145" + u"\1\157\1\uffff\2\165\1\146\6\uffff\1\72\3\uffff\2\72\3\uffff\1" + u"\162\3\uffff\1\160\3\uffff\1\165\4\uffff\1\156\1\171\2\uffff\1" + u"\156\6\uffff\1\164\6\uffff" + ) + + DFA25_accept = DFA.unpack( + u"\15\uffff\1\13\3\uffff\1\32\1\35\1\36\1\37\1\41\1\43\1\uffff\1" + u"\44\1\1\1\2\2\uffff\1\3\1\45\1\4\1\uffff\1\7\1\15\1\21\1\uffff" + u"\1\16\1\17\1\5\1\uffff\1\12\1\6\1\10\1\33\2\uffff\1\40\1\20\1\uffff" + u"\1\23\1\27\1\31\1\42\1\30\1\14\1\uffff\1\22\1\24\1\25\1\26\1\34" + u"\1\11" + ) + + DFA25_special = DFA.unpack( + u"\77\uffff" + ) + + + DFA25_transition = [ + DFA.unpack(u"\2\26\2\uffff\1\26\22\uffff\1\26\13\uffff\1\25\3\uffff" + u"\1\1\1\2\1\3\1\4\1\7\1\11\4\12\47\uffff\1\17\2\uffff\1\13\1\23" + u"\1\5\1\uffff\1\24\1\uffff\1\16\2\uffff\1\14\1\21\1\20\1\uffff\1" + u"\22\1\uffff\1\6\1\10\2\uffff\1\15"), + DFA.unpack(u"\12\27\1\31"), + DFA.unpack(u"\12\33\1\31\70\uffff\1\32"), + DFA.unpack(u"\4\34\6\36\1\31\63\uffff\1\35"), + DFA.unpack(u"\12\36\1\31\67\uffff\1\37"), + DFA.unpack(u"\1\43\3\uffff\1\40\5\uffff\1\41\2\uffff\1\42"), + DFA.unpack(u"\1\45\3\uffff\1\44\17\uffff\1\46"), + DFA.unpack(u"\12\36\1\31\71\uffff\1\47"), + DFA.unpack(u"\1\50\14\uffff\1\51"), + DFA.unpack(u"\12\36\1\31\71\uffff\1\52"), + DFA.unpack(u"\12\36\1\31"), + DFA.unpack(u"\1\53\3\uffff\1\54"), + DFA.unpack(u"\1\56\7\uffff\1\57\5\uffff\1\55"), + DFA.unpack(u""), + DFA.unpack(u"\1\60\23\uffff\1\61"), + DFA.unpack(u"\1\62\4\uffff\1\63"), + DFA.unpack(u"\1\64\2\uffff\1\65"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\31"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\31"), + DFA.unpack(u"\1\31"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\41\13\uffff\1\32"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\35\14\uffff\1\66"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\37\13\uffff\1\67"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\70"), + DFA.unpack(u"\1\71\6\uffff\1\72"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\74\1\uffff\1\73"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\1\75"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"") + ] + + + DFA25 = DFA + + + + +def main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr): + from antlr3.main import LexerMain + main = LexerMain(GrocLexer) + main.stdin = stdin + main.stdout = stdout + main.stderr = stderr + main.execute(argv) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/google_appengine/google/appengine/cron/GrocLexer.pyc b/google_appengine/google/appengine/cron/GrocLexer.pyc Binary files differnew file mode 100644 index 0000000..c0bd09f --- /dev/null +++ b/google_appengine/google/appengine/cron/GrocLexer.pyc diff --git a/google_appengine/google/appengine/cron/GrocParser.py b/google_appengine/google/appengine/cron/GrocParser.py new file mode 100755 index 0000000..b86cb4e --- /dev/null +++ b/google_appengine/google/appengine/cron/GrocParser.py @@ -0,0 +1,1008 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import sys +from antlr3 import * +from antlr3.compat import set, frozenset + + + + + +allOrdinals = set([1, 2, 3, 4, 5]) +numOrdinals = len(allOrdinals) + + + + +HIDDEN = BaseRecognizer.HIDDEN + +THIRD=12 +SEPTEMBER=35 +FOURTH=13 +SECOND=11 +WEDNESDAY=21 +NOVEMBER=37 +SATURDAY=24 +JULY=33 +APRIL=30 +DIGITS=8 +OCTOBER=36 +MAY=31 +EVERY=6 +FEBRUARY=28 +MONDAY=19 +SUNDAY=25 +JUNE=32 +DAY=18 +MARCH=29 +OF=4 +EOF=-1 +JANUARY=27 +MONTH=26 +FRIDAY=23 +FIFTH=14 +MINUTES=17 +TIME=5 +WS=40 +QUARTER=39 +THURSDAY=22 +COMMA=9 +DECEMBER=38 +AUGUST=34 +DIGIT=7 +TUESDAY=20 +HOURS=16 +FIRST=10 +FOURTH_OR_FIFTH=15 + +tokenNames = [ + "<invalid>", "<EOR>", "<DOWN>", "<UP>", + "OF", "TIME", "EVERY", "DIGIT", "DIGITS", "COMMA", "FIRST", "SECOND", + "THIRD", "FOURTH", "FIFTH", "FOURTH_OR_FIFTH", "HOURS", "MINUTES", "DAY", + "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", + "SUNDAY", "MONTH", "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", + "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER", "QUARTER", + "WS" +] + + + + +class GrocParser(Parser): + grammarFileName = "Groc.g" + antlr_version = version_str_to_tuple("3.1.1") + antlr_version_str = "3.1.1" + tokenNames = tokenNames + + def __init__(self, input, state=None): + if state is None: + state = RecognizerSharedState() + + Parser.__init__(self, input, state) + + + self.dfa3 = self.DFA3( + self, 3, + eot = self.DFA3_eot, + eof = self.DFA3_eof, + min = self.DFA3_min, + max = self.DFA3_max, + accept = self.DFA3_accept, + special = self.DFA3_special, + transition = self.DFA3_transition + ) + + + + + self.ordinal_set = set() + self.weekday_set = set() + self.month_set = set() + self.time_string = ''; + self.interval_mins = 0; + self.period_string = ''; + + + + + + + + + + + valuesDict = { + SUNDAY: 0, + FIRST: 1, + MONDAY: 1, + JANUARY: 1, + TUESDAY: 2, + SECOND: 2, + FEBRUARY: 2, + WEDNESDAY: 3, + THIRD: 3, + MARCH: 3, + THURSDAY: 4, + FOURTH: 4, + APRIL: 4, + FRIDAY: 5, + FIFTH: 5, + MAY: 5, + SATURDAY: 6, + JUNE: 6, + JULY: 7, + AUGUST: 8, + SEPTEMBER: 9, + OCTOBER: 10, + NOVEMBER: 11, + DECEMBER: 12, + } + + def ValueOf(self, token_type): + return self.valuesDict.get(token_type, -1) + + + + + def timespec(self, ): + + try: + try: + pass + alt1 = 2 + LA1_0 = self.input.LA(1) + + if (LA1_0 == EVERY) : + LA1_1 = self.input.LA(2) + + if ((DIGIT <= LA1_1 <= DIGITS)) : + alt1 = 2 + elif ((DAY <= LA1_1 <= SUNDAY)) : + alt1 = 1 + else: + nvae = NoViableAltException("", 1, 1, self.input) + + raise nvae + + elif ((FIRST <= LA1_0 <= FOURTH_OR_FIFTH)) : + alt1 = 1 + else: + nvae = NoViableAltException("", 1, 0, self.input) + + raise nvae + + if alt1 == 1: + pass + self._state.following.append(self.FOLLOW_specifictime_in_timespec44) + self.specifictime() + + self._state.following.pop() + + + elif alt1 == 2: + pass + self._state.following.append(self.FOLLOW_interval_in_timespec48) + self.interval() + + self._state.following.pop() + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def specifictime(self, ): + + TIME1 = None + + try: + try: + pass + pass + alt3 = 2 + alt3 = self.dfa3.predict(self.input) + if alt3 == 1: + pass + pass + pass + self._state.following.append(self.FOLLOW_ordinals_in_specifictime69) + self.ordinals() + + self._state.following.pop() + self._state.following.append(self.FOLLOW_weekdays_in_specifictime71) + self.weekdays() + + self._state.following.pop() + + + + self.match(self.input, OF, self.FOLLOW_OF_in_specifictime74) + alt2 = 2 + LA2_0 = self.input.LA(1) + + if ((MONTH <= LA2_0 <= DECEMBER)) : + alt2 = 1 + elif ((FIRST <= LA2_0 <= THIRD) or LA2_0 == QUARTER) : + alt2 = 2 + else: + nvae = NoViableAltException("", 2, 0, self.input) + + raise nvae + + if alt2 == 1: + pass + self._state.following.append(self.FOLLOW_monthspec_in_specifictime77) + self.monthspec() + + self._state.following.pop() + + + elif alt2 == 2: + pass + self._state.following.append(self.FOLLOW_quarterspec_in_specifictime79) + self.quarterspec() + + self._state.following.pop() + + + + + + + + + elif alt3 == 2: + pass + pass + self._state.following.append(self.FOLLOW_ordinals_in_specifictime96) + self.ordinals() + + self._state.following.pop() + self._state.following.append(self.FOLLOW_weekdays_in_specifictime98) + self.weekdays() + + self._state.following.pop() + self.month_set = set(range(1,13)) + + + + + + + TIME1=self.match(self.input, TIME, self.FOLLOW_TIME_in_specifictime112) + self.time_string = TIME1.text + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def interval(self, ): + + intervalnum = None + period2 = None + + + try: + try: + pass + pass + self.match(self.input, EVERY, self.FOLLOW_EVERY_in_interval131) + intervalnum = self.input.LT(1) + if (DIGIT <= self.input.LA(1) <= DIGITS): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + + self.interval_mins = int(intervalnum.text) + + self._state.following.append(self.FOLLOW_period_in_interval157) + period2 = self.period() + + self._state.following.pop() + + if ((period2 is not None) and [self.input.toString(period2.start,period2.stop)] or [None])[0] == "hours": + self.period_string = "hours" + else: + self.period_string = "minutes" + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def ordinals(self, ): + + try: + try: + pass + alt5 = 2 + LA5_0 = self.input.LA(1) + + if (LA5_0 == EVERY) : + alt5 = 1 + elif ((FIRST <= LA5_0 <= FOURTH_OR_FIFTH)) : + alt5 = 2 + else: + nvae = NoViableAltException("", 5, 0, self.input) + + raise nvae + + if alt5 == 1: + pass + self.match(self.input, EVERY, self.FOLLOW_EVERY_in_ordinals176) + self.ordinal_set = self.ordinal_set.union(allOrdinals) + + + elif alt5 == 2: + pass + pass + self._state.following.append(self.FOLLOW_ordinal_in_ordinals192) + self.ordinal() + + self._state.following.pop() + while True: + alt4 = 2 + LA4_0 = self.input.LA(1) + + if (LA4_0 == COMMA) : + alt4 = 1 + + + if alt4 == 1: + pass + self.match(self.input, COMMA, self.FOLLOW_COMMA_in_ordinals195) + self._state.following.append(self.FOLLOW_ordinal_in_ordinals197) + self.ordinal() + + self._state.following.pop() + + + else: + break + + + + + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def ordinal(self, ): + + ord = None + + try: + try: + pass + ord = self.input.LT(1) + if (FIRST <= self.input.LA(1) <= FOURTH_OR_FIFTH): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + + self.ordinal_set.add(self.ValueOf(ord.type)); + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + class period_return(ParserRuleReturnScope): + def __init__(self): + ParserRuleReturnScope.__init__(self) + + + + + + def period(self, ): + + retval = self.period_return() + retval.start = self.input.LT(1) + + try: + try: + pass + if (HOURS <= self.input.LA(1) <= MINUTES): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + + + + retval.stop = self.input.LT(-1) + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return retval + + + + def weekdays(self, ): + + try: + try: + pass + alt7 = 2 + LA7_0 = self.input.LA(1) + + if (LA7_0 == DAY) : + alt7 = 1 + elif ((MONDAY <= LA7_0 <= SUNDAY)) : + alt7 = 2 + else: + nvae = NoViableAltException("", 7, 0, self.input) + + raise nvae + + if alt7 == 1: + pass + self.match(self.input, DAY, self.FOLLOW_DAY_in_weekdays280) + + self.weekday_set = set([self.ValueOf(SUNDAY), self.ValueOf(MONDAY), + self.ValueOf(TUESDAY), self.ValueOf(WEDNESDAY), + self.ValueOf(THURSDAY), self.ValueOf(FRIDAY), + self.ValueOf(SATURDAY), self.ValueOf(SUNDAY)]) + + + + elif alt7 == 2: + pass + pass + self._state.following.append(self.FOLLOW_weekday_in_weekdays288) + self.weekday() + + self._state.following.pop() + while True: + alt6 = 2 + LA6_0 = self.input.LA(1) + + if (LA6_0 == COMMA) : + alt6 = 1 + + + if alt6 == 1: + pass + self.match(self.input, COMMA, self.FOLLOW_COMMA_in_weekdays291) + self._state.following.append(self.FOLLOW_weekday_in_weekdays293) + self.weekday() + + self._state.following.pop() + + + else: + break + + + + + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def weekday(self, ): + + dayname = None + + try: + try: + pass + dayname = self.input.LT(1) + if (MONDAY <= self.input.LA(1) <= SUNDAY): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + + self.weekday_set.add(self.ValueOf(dayname.type)) + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def monthspec(self, ): + + try: + try: + pass + alt8 = 2 + LA8_0 = self.input.LA(1) + + if (LA8_0 == MONTH) : + alt8 = 1 + elif ((JANUARY <= LA8_0 <= DECEMBER)) : + alt8 = 2 + else: + nvae = NoViableAltException("", 8, 0, self.input) + + raise nvae + + if alt8 == 1: + pass + self.match(self.input, MONTH, self.FOLLOW_MONTH_in_monthspec373) + + self.month_set = self.month_set.union(set([ + self.ValueOf(JANUARY), self.ValueOf(FEBRUARY), self.ValueOf(MARCH), + self.ValueOf(APRIL), self.ValueOf(MAY), self.ValueOf(JUNE), + self.ValueOf(JULY), self.ValueOf(AUGUST), self.ValueOf(SEPTEMBER), + self.ValueOf(OCTOBER), self.ValueOf(NOVEMBER), + self.ValueOf(DECEMBER)])) + + + + elif alt8 == 2: + pass + self._state.following.append(self.FOLLOW_months_in_monthspec383) + self.months() + + self._state.following.pop() + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def months(self, ): + + try: + try: + pass + pass + self._state.following.append(self.FOLLOW_month_in_months400) + self.month() + + self._state.following.pop() + while True: + alt9 = 2 + LA9_0 = self.input.LA(1) + + if (LA9_0 == COMMA) : + alt9 = 1 + + + if alt9 == 1: + pass + self.match(self.input, COMMA, self.FOLLOW_COMMA_in_months403) + self._state.following.append(self.FOLLOW_month_in_months405) + self.month() + + self._state.following.pop() + + + else: + break + + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def month(self, ): + + monthname = None + + try: + try: + pass + monthname = self.input.LT(1) + if (JANUARY <= self.input.LA(1) <= DECEMBER): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + self.month_set.add(self.ValueOf(monthname.type)); + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def quarterspec(self, ): + + try: + try: + pass + alt10 = 2 + LA10_0 = self.input.LA(1) + + if (LA10_0 == QUARTER) : + alt10 = 1 + elif ((FIRST <= LA10_0 <= THIRD)) : + alt10 = 2 + else: + nvae = NoViableAltException("", 10, 0, self.input) + + raise nvae + + if alt10 == 1: + pass + self.match(self.input, QUARTER, self.FOLLOW_QUARTER_in_quarterspec497) + + self.month_set = self.month_set.union(set([ + self.ValueOf(JANUARY), self.ValueOf(APRIL), self.ValueOf(JULY), + self.ValueOf(OCTOBER)])) + + + elif alt10 == 2: + pass + pass + self._state.following.append(self.FOLLOW_quarter_ordinals_in_quarterspec509) + self.quarter_ordinals() + + self._state.following.pop() + self.match(self.input, MONTH, self.FOLLOW_MONTH_in_quarterspec511) + self.match(self.input, OF, self.FOLLOW_OF_in_quarterspec513) + self.match(self.input, QUARTER, self.FOLLOW_QUARTER_in_quarterspec515) + + + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def quarter_ordinals(self, ): + + try: + try: + pass + pass + self._state.following.append(self.FOLLOW_month_of_quarter_ordinal_in_quarter_ordinals534) + self.month_of_quarter_ordinal() + + self._state.following.pop() + while True: + alt11 = 2 + LA11_0 = self.input.LA(1) + + if (LA11_0 == COMMA) : + alt11 = 1 + + + if alt11 == 1: + pass + self.match(self.input, COMMA, self.FOLLOW_COMMA_in_quarter_ordinals537) + self._state.following.append(self.FOLLOW_month_of_quarter_ordinal_in_quarter_ordinals539) + self.month_of_quarter_ordinal() + + self._state.following.pop() + + + else: + break + + + + + + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + def month_of_quarter_ordinal(self, ): + + offset = None + + try: + try: + pass + offset = self.input.LT(1) + if (FIRST <= self.input.LA(1) <= THIRD): + self.input.consume() + self._state.errorRecovery = False + + else: + mse = MismatchedSetException(None, self.input) + raise mse + + + + jOffset = self.ValueOf(offset.type) - 1 + self.month_set = self.month_set.union(set([ + jOffset + self.ValueOf(JANUARY), jOffset + self.ValueOf(APRIL), + jOffset + self.ValueOf(JULY), jOffset + self.ValueOf(OCTOBER)])) + + + + + except RecognitionException, re: + self.reportError(re) + self.recover(self.input, re) + finally: + + pass + + return + + + + + + + DFA3_eot = DFA.unpack( + u"\13\uffff" + ) + + DFA3_eof = DFA.unpack( + u"\13\uffff" + ) + + DFA3_min = DFA.unpack( + u"\1\6\1\22\1\11\2\4\1\12\2\uffff\1\23\1\11\1\4" + ) + + DFA3_max = DFA.unpack( + u"\1\17\2\31\1\5\1\11\1\17\2\uffff\2\31\1\11" + ) + + DFA3_accept = DFA.unpack( + u"\6\uffff\1\1\1\2\3\uffff" + ) + + DFA3_special = DFA.unpack( + u"\13\uffff" + ) + + + DFA3_transition = [ + DFA.unpack(u"\1\1\3\uffff\6\2"), + DFA.unpack(u"\1\3\7\4"), + DFA.unpack(u"\1\5\10\uffff\1\3\7\4"), + DFA.unpack(u"\1\6\1\7"), + DFA.unpack(u"\1\6\1\7\3\uffff\1\10"), + DFA.unpack(u"\6\11"), + DFA.unpack(u""), + DFA.unpack(u""), + DFA.unpack(u"\7\12"), + DFA.unpack(u"\1\5\10\uffff\1\3\7\4"), + DFA.unpack(u"\1\6\1\7\3\uffff\1\10") + ] + + + DFA3 = DFA + + + FOLLOW_specifictime_in_timespec44 = frozenset([1]) + FOLLOW_interval_in_timespec48 = frozenset([1]) + FOLLOW_ordinals_in_specifictime69 = frozenset([18, 19, 20, 21, 22, 23, 24, 25]) + FOLLOW_weekdays_in_specifictime71 = frozenset([4]) + FOLLOW_OF_in_specifictime74 = frozenset([10, 11, 12, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]) + FOLLOW_monthspec_in_specifictime77 = frozenset([5]) + FOLLOW_quarterspec_in_specifictime79 = frozenset([5]) + FOLLOW_ordinals_in_specifictime96 = frozenset([18, 19, 20, 21, 22, 23, 24, 25]) + FOLLOW_weekdays_in_specifictime98 = frozenset([5]) + FOLLOW_TIME_in_specifictime112 = frozenset([1]) + FOLLOW_EVERY_in_interval131 = frozenset([7, 8]) + FOLLOW_set_in_interval141 = frozenset([16, 17]) + FOLLOW_period_in_interval157 = frozenset([1]) + FOLLOW_EVERY_in_ordinals176 = frozenset([1]) + FOLLOW_ordinal_in_ordinals192 = frozenset([1, 9]) + FOLLOW_COMMA_in_ordinals195 = frozenset([10, 11, 12, 13, 14, 15]) + FOLLOW_ordinal_in_ordinals197 = frozenset([1, 9]) + FOLLOW_set_in_ordinal218 = frozenset([1]) + FOLLOW_set_in_period257 = frozenset([1]) + FOLLOW_DAY_in_weekdays280 = frozenset([1]) + FOLLOW_weekday_in_weekdays288 = frozenset([1, 9]) + FOLLOW_COMMA_in_weekdays291 = frozenset([18, 19, 20, 21, 22, 23, 24, 25]) + FOLLOW_weekday_in_weekdays293 = frozenset([1, 9]) + FOLLOW_set_in_weekday314 = frozenset([1]) + FOLLOW_MONTH_in_monthspec373 = frozenset([1]) + FOLLOW_months_in_monthspec383 = frozenset([1]) + FOLLOW_month_in_months400 = frozenset([1, 9]) + FOLLOW_COMMA_in_months403 = frozenset([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38]) + FOLLOW_month_in_months405 = frozenset([1, 9]) + FOLLOW_set_in_month424 = frozenset([1]) + FOLLOW_QUARTER_in_quarterspec497 = frozenset([1]) + FOLLOW_quarter_ordinals_in_quarterspec509 = frozenset([26]) + FOLLOW_MONTH_in_quarterspec511 = frozenset([4]) + FOLLOW_OF_in_quarterspec513 = frozenset([39]) + FOLLOW_QUARTER_in_quarterspec515 = frozenset([1]) + FOLLOW_month_of_quarter_ordinal_in_quarter_ordinals534 = frozenset([1, 9]) + FOLLOW_COMMA_in_quarter_ordinals537 = frozenset([10, 11, 12, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]) + FOLLOW_month_of_quarter_ordinal_in_quarter_ordinals539 = frozenset([1, 9]) + FOLLOW_set_in_month_of_quarter_ordinal558 = frozenset([1]) + + + +def main(argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr): + from antlr3.main import ParserMain + main = ParserMain("GrocLexer", GrocParser) + main.stdin = stdin + main.stdout = stdout + main.stderr = stderr + main.execute(argv) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/google_appengine/google/appengine/cron/GrocParser.pyc b/google_appengine/google/appengine/cron/GrocParser.pyc Binary files differnew file mode 100644 index 0000000..094d1b9 --- /dev/null +++ b/google_appengine/google/appengine/cron/GrocParser.pyc diff --git a/google_appengine/google/appengine/cron/__init__.py b/google_appengine/google/appengine/cron/__init__.py new file mode 100755 index 0000000..d5eed70 --- /dev/null +++ b/google_appengine/google/appengine/cron/__init__.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"this file is needed to make this a package" diff --git a/google_appengine/google/appengine/cron/__init__.pyc b/google_appengine/google/appengine/cron/__init__.pyc Binary files differnew file mode 100644 index 0000000..1d7c118 --- /dev/null +++ b/google_appengine/google/appengine/cron/__init__.pyc diff --git a/google_appengine/google/appengine/cron/groc.py b/google_appengine/google/appengine/cron/groc.py new file mode 100755 index 0000000..373d56a --- /dev/null +++ b/google_appengine/google/appengine/cron/groc.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +"""A wrapper around the generated Groc parser and lexer.""" + + +import google + +import antlr3 + +import GrocLexer +import GrocParser + + +class GrocException(Exception): + """An error occurred while parsing the groc input string.""" + + +class GrocLexerWithErrors(GrocLexer.GrocLexer): + """An overridden Lexer that raises exceptions.""" + + def emitErrorMessage(self, msg): + """Raise an exception if the input fails to parse correctly. + + Overriding the default, which normally just prints a message to + stderr. + + Arguments: + msg: the error message + Raises: + GrocException: always. + """ + raise GrocException(msg) + + +class GrocParserWithErrors(GrocParser.GrocParser): + """An overridden Parser that raises exceptions.""" + + def emitErrorMessage(self, msg): + """Raise an exception if the input fails to parse correctly. + + Overriding the default, which normally just prints a message to + stderr. + + Arguments: + msg: the error message + Raises: + GrocException: always. + """ + raise GrocException(msg) + + +def CreateParser(parse_string): + """Creates a Groc Parser.""" + input_string = antlr3.ANTLRStringStream(parse_string) + lexer = GrocLexerWithErrors(input_string) + tokens = antlr3.CommonTokenStream(lexer) + parser = GrocParserWithErrors(tokens) + return parser diff --git a/google_appengine/google/appengine/cron/groc.pyc b/google_appengine/google/appengine/cron/groc.pyc Binary files differnew file mode 100644 index 0000000..a6770cf --- /dev/null +++ b/google_appengine/google/appengine/cron/groc.pyc diff --git a/google_appengine/google/appengine/cron/groctimespecification.py b/google_appengine/google/appengine/cron/groctimespecification.py new file mode 100755 index 0000000..9acb7bf --- /dev/null +++ b/google_appengine/google/appengine/cron/groctimespecification.py @@ -0,0 +1,304 @@ +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +"""Implementation of scheduling for Groc format schedules. + +A Groc schedule looks like '1st,2nd monday 9:00', or 'every 20 mins'. This +module takes a parsed schedule (produced by Antlr) and creates objects that +can produce times that match this schedule. + +A parsed schedule is one of two types - an Interval or a Specific Time. +See the class docstrings for more. + +Extensions to be considered: + + allowing a comma separated list of times to run + allowing the user to specify particular days of the month to run +""" + + +import calendar +import datetime + +try: + import pytz +except ImportError: + pytz = None + +import groc + +HOURS = 'hours' +MINUTES = 'minutes' + +try: + from pytz import NonExistentTimeError + from pytz import AmbiguousTimeError +except ImportError: + class NonExistentTimeError(Exception): + pass + class AmbiguousTimeError(Exception): + pass + + +def GrocTimeSpecification(schedule): + """Factory function. + + Turns a schedule specification into a TimeSpecification. + + Arguments: + schedule: the schedule specification, as a string + + Returns: + a TimeSpecification instance + """ + parser = groc.CreateParser(schedule) + parser.timespec() + + if parser.interval_mins: + return IntervalTimeSpecification(parser.interval_mins, + parser.period_string) + else: + return SpecificTimeSpecification(parser.ordinal_set, parser.weekday_set, + parser.month_set, + None, + parser.time_string) + + +class TimeSpecification(object): + """Base class for time specifications.""" + + def GetMatches(self, start, n): + """Returns the next n times that match the schedule, starting at time start. + + Arguments: + start: a datetime to start from. Matches will start from after this time. + n: the number of matching times to return + + Returns: + a list of n datetime objects + """ + out = [] + for _ in range(n): + start = self.GetMatch(start) + out.append(start) + return out + + def GetMatch(self, start): + """Returns the next match after time start. + + Must be implemented in subclasses. + + Arguments: + start: a datetime to start with. Matches will start from this time. + + Returns: + a datetime object + """ + raise NotImplementedError + + +class IntervalTimeSpecification(TimeSpecification): + """A time specification for a given interval. + + An Interval type spec runs at the given fixed interval. It has two + attributes: + period - the type of interval, either "hours" or "minutes" + interval - the number of units of type period. + """ + + def __init__(self, interval, period): + super(IntervalTimeSpecification, self).__init__() + self.interval = interval + self.period = period + + def GetMatch(self, t): + """Returns the next match after time 't'. + + Arguments: + t: a datetime to start from. Matches will start from after this time. + + Returns: + a datetime object + """ + if self.period == HOURS: + return t + datetime.timedelta(hours=self.interval) + else: + return t + datetime.timedelta(minutes=self.interval) + + +class SpecificTimeSpecification(TimeSpecification): + """Specific time specification. + + A Specific interval is more complex, but defines a certain time to run and + the days that it should run. It has the following attributes: + time - the time of day to run, as "HH:MM" + ordinals - first, second, third &c, as a set of integers in 1..5 + months - the months that this should run, as a set of integers in 1..12 + weekdays - the days of the week that this should run, as a set of integers, + 0=Sunday, 6=Saturday + timezone - the optional timezone as a string for this specification. + Defaults to UTC - valid entries are things like Australia/Victoria + or PST8PDT. + + A specific time schedule can be quite complex. A schedule could look like + this: + "1st,third sat,sun of jan,feb,mar 09:15" + + In this case, ordinals would be {1,3}, weekdays {0,6}, months {1,2,3} and + time would be "09:15". + """ + + timezone = None + + def __init__(self, ordinals=None, weekdays=None, months=None, monthdays=None, + timestr='00:00', timezone=None): + super(SpecificTimeSpecification, self).__init__(self) + if weekdays is not None and monthdays is not None: + raise ValueError("can't supply both monthdays and weekdays") + if ordinals is None: + self.ordinals = set(range(1, 6)) + else: + self.ordinals = set(ordinals) + + if weekdays is None: + self.weekdays = set(range(7)) + else: + self.weekdays = set(weekdays) + + if months is None: + self.months = set(range(1, 13)) + else: + self.months = set(months) + + if monthdays is None: + self.monthdays = set() + else: + self.monthdays = set(monthdays) + hourstr, minutestr = timestr.split(':') + self.time = datetime.time(int(hourstr), int(minutestr)) + if timezone: + if pytz is None: + raise ValueError("need pytz in order to specify a timezone") + self.timezone = pytz.timezone(timezone) + + def _MatchingDays(self, year, month): + """Returns matching days for the given year and month. + + For the given year and month, return the days that match this instance's + day specification, based on the ordinals and weekdays. + + Arguments: + year: the year as an integer + month: the month as an integer, in range 1-12 + + Returns: + a list of matching days, as ints in range 1-31 + """ + out_days = [] + start_day, last_day = calendar.monthrange(year, month) + start_day = (start_day + 1) % 7 + for ordinal in self.ordinals: + for weekday in self.weekdays: + day = ((weekday - start_day) % 7) + 1 + day += 7 * (ordinal - 1) + if day <= last_day: + out_days.append(day) + return sorted(out_days) + + def _NextMonthGenerator(self, start, matches): + """Creates a generator that produces results from the set 'matches'. + + Matches must be >= 'start'. If none match, the wrap counter is incremented, + and the result set is reset to the full set. Yields a 2-tuple of (match, + wrapcount). + + Arguments: + start: first set of matches will be >= this value (an int) + matches: the set of potential matches (a sequence of ints) + + Yields: + a two-tuple of (match, wrap counter). match is an int in range (1-12), + wrapcount is a int indicating how many times we've wrapped around. + """ + potential = matches = sorted(matches) + after = start - 1 + wrapcount = 0 + while True: + potential = [x for x in potential if x > after] + if not potential: + wrapcount += 1 + potential = matches + after = potential[0] + yield (after, wrapcount) + + def GetMatch(self, start): + """Returns the next time that matches the schedule after time start. + + Arguments: + start: a UTC datetime to start from. Matches will start after this time + + Returns: + a datetime object + """ + start_time = start + if self.timezone and pytz is not None: + if not start_time.tzinfo: + start_time = pytz.utc.localize(start_time) + start_time = start_time.astimezone(self.timezone) + start_time = start_time.replace(tzinfo=None) + if self.months: + months = self._NextMonthGenerator(start_time.month, self.months) + while True: + month, yearwraps = months.next() + candidate_month = start_time.replace(day=1, month=month, + year=start_time.year + yearwraps) + + if self.monthdays: + _, last_day = calendar.monthrange(candidate_month.year, + candidate_month.month) + day_matches = sorted(x for x in self.monthdays if x <= last_day) + else: + day_matches = self._MatchingDays(candidate_month.year, month) + + if ((candidate_month.year, candidate_month.month) + == (start_time.year, start_time.month)): + day_matches = [x for x in day_matches if x >= start_time.day] + while (day_matches and day_matches[0] == start_time.day + and start_time.time() >= self.time): + day_matches.pop(0) + while day_matches: + out = candidate_month.replace(day=day_matches[0], hour=self.time.hour, + + + minute=self.time.minute, second=0, + microsecond=0) + if self.timezone and pytz is not None: + try: + out = self.timezone.localize(out, is_dst=None) + except AmbiguousTimeError: + out = self.timezone.localize(out) + except NonExistentTimeError: + for _ in range(24): + out = out.replace(minute=1) + datetime.timedelta(minutes=60) + try: + out = self.timezone.localize(out) + except NonExistentTimeError: + continue + break + out = out.astimezone(pytz.utc) + return out diff --git a/google_appengine/google/appengine/cron/groctimespecification.pyc b/google_appengine/google/appengine/cron/groctimespecification.pyc Binary files differnew file mode 100644 index 0000000..f030218 --- /dev/null +++ b/google_appengine/google/appengine/cron/groctimespecification.pyc |