summaryrefslogtreecommitdiffstats
path: root/google_appengine/google/appengine/cron
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2009-10-19 20:20:09 -0400
committerJason A. Donenfeld <Jason@zx2c4.com>2009-10-19 20:20:09 -0400
commit2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535 (patch)
treeda9c93d2f87df6d2b688a455a31e69859117ba1e /google_appengine/google/appengine/cron
downloadFramedPrototype-2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535.tar.xz
FramedPrototype-2d6dd2c5ade3f5fad3e2257dce52a6e188fe7535.zip
Initial import.
Diffstat (limited to 'google_appengine/google/appengine/cron')
-rwxr-xr-xgoogle_appengine/google/appengine/cron/GrocLexer.py1669
-rw-r--r--google_appengine/google/appengine/cron/GrocLexer.pycbin0 -> 22472 bytes
-rwxr-xr-xgoogle_appengine/google/appengine/cron/GrocParser.py1008
-rw-r--r--google_appengine/google/appengine/cron/GrocParser.pycbin0 -> 18129 bytes
-rwxr-xr-xgoogle_appengine/google/appengine/cron/__init__.py17
-rw-r--r--google_appengine/google/appengine/cron/__init__.pycbin0 -> 222 bytes
-rwxr-xr-xgoogle_appengine/google/appengine/cron/groc.py74
-rw-r--r--google_appengine/google/appengine/cron/groc.pycbin0 -> 2413 bytes
-rwxr-xr-xgoogle_appengine/google/appengine/cron/groctimespecification.py304
-rw-r--r--google_appengine/google/appengine/cron/groctimespecification.pycbin0 -> 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
new file mode 100644
index 0000000..c0bd09f
--- /dev/null
+++ b/google_appengine/google/appengine/cron/GrocLexer.pyc
Binary files differ
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
new file mode 100644
index 0000000..094d1b9
--- /dev/null
+++ b/google_appengine/google/appengine/cron/GrocParser.pyc
Binary files differ
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
new file mode 100644
index 0000000..1d7c118
--- /dev/null
+++ b/google_appengine/google/appengine/cron/__init__.pyc
Binary files differ
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
new file mode 100644
index 0000000..a6770cf
--- /dev/null
+++ b/google_appengine/google/appengine/cron/groc.pyc
Binary files differ
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
new file mode 100644
index 0000000..f030218
--- /dev/null
+++ b/google_appengine/google/appengine/cron/groctimespecification.pyc
Binary files differ