commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r7882 - trunk/gnue-common/src/formatting/masks


From: jamest
Subject: [gnue] r7882 - trunk/gnue-common/src/formatting/masks
Date: Fri, 26 Aug 2005 22:50:59 -0500 (CDT)

Author: jamest
Date: 2005-08-26 22:50:57 -0500 (Fri, 26 Aug 2005)
New Revision: 7882

Modified:
   trunk/gnue-common/src/formatting/masks/InputMask.py
   trunk/gnue-common/src/formatting/masks/MaskParser.py
Log:
docstrings and cleanup


Modified: trunk/gnue-common/src/formatting/masks/InputMask.py
===================================================================
--- trunk/gnue-common/src/formatting/masks/InputMask.py 2005-08-25 16:38:04 UTC 
(rev 7881)
+++ trunk/gnue-common/src/formatting/masks/InputMask.py 2005-08-27 03:50:57 UTC 
(rev 7882)
@@ -23,7 +23,8 @@
 #
 # DESCRIPTION:
 """
-Input masks for GNUe Forms, et al
+Input masks for GNUe Forms, et al 
+
 Based on lex/yacc parsing (via Plex)
 """
 # NOTES:
@@ -151,6 +152,11 @@
               first_state = mstate
 
       except Errors.PlexError, msg:
+        import sys
+        mesg = u_("input error:\n%(exType)s\n%(exMessage)s") \
+            % {'exType'   : sys.exc_info ()[0],
+               'exMessage': sys.exc_info ()[1]}
+        print mesg
         raise InvalidInputCharacter, msg
 
 
@@ -309,10 +315,28 @@
   # ===========================================================================
 
   def __init__(self, mask, numeric=False, date=False):
+    """
+    InputMask constructor
+    
+    InputMasks can be of 3 differnt types (text, numeric, and date).  The type 
of
+    input mask is determined by the boolean values of the numeric and date 
+    arguments to the constructor.  The default mask type is text but if either 
+    of the two booleans are set then the mask type switchs to that.
+    
+    When building an input mask 2 token lists are built.  The initial token 
list
+    is created from the mask text passed into the constructor.  This token list
+    
+    @param mask: The input mask the initialized instance of the class should
+                 support
+    @param numeric: Is this input mask numeric input only?
+    @param date: Is this input mask date input only?
+    """
     # -------------------------------------------------------------------------
     # Generate a list of parser tokens that define the input mask
     # -------------------------------------------------------------------------
+    #
     parser = MaskParser.InputMaskParser(StringIO(mask),'inline', numeric, date)
+    
     self.pp = pprint.PrettyPrinter(indent=4)
     self.isnumeric = numeric
     self.isdate = date
@@ -321,10 +345,10 @@
     # List of all tokens. Note that all {#}
     # expansions have already happened.
     ptokens = parser.tokens
-    print "1st token list"
-    for item in ptokens:
-      print item.token,
-    print
+#     print "1st token list"
+#     for item in ptokens:
+#       print item.token,
+#     print
     # If non-zero, position of the right-to-left token
     rtl_pos = self.rtl_pos = parser.rtl_pos
 
@@ -342,6 +366,8 @@
     # -------------------------------------------------------------------------
     # Convert the parser token list into an input mask token list
     # -------------------------------------------------------------------------
+    #
+    # 
     i = 0
     while i < len(ptokens):
       ptoken=ptokens[i]      

Modified: trunk/gnue-common/src/formatting/masks/MaskParser.py
===================================================================
--- trunk/gnue-common/src/formatting/masks/MaskParser.py        2005-08-25 
16:38:04 UTC (rev 7881)
+++ trunk/gnue-common/src/formatting/masks/MaskParser.py        2005-08-27 
03:50:57 UTC (rev 7882)
@@ -33,12 +33,14 @@
 import string
 from Errors import *
 
+# TODO: Why is this here?
 digit = Any(string.digits)
 
 class BaseToken:
   """
-  Basic parser class. Not used directly,
-  but inherited by the other defined tokens
+  Basic parser token class. 
+  
+  Not used directly,  but inherited by the other defined tokens
   Literal, Token, etc.
   """
   numeric=False
@@ -48,6 +50,9 @@
   token=False
 
   def __init__(self, t1, t2=None, *args):
+    """
+    Token construtor
+    """
     if t2:
       self.token = t2
     else:
@@ -83,6 +88,8 @@
 class TextToken(Token):
   """
   Text token
+  
+  A test token represents 1 standard alphanumeric character.
   """
   text = True
 
@@ -95,11 +102,9 @@
   def __init__(self, token, *args):
     # TODO: Expand the set
     # Are we all-numeric?
-    self.numeric = True
+    self.numeric = token.isdigit()
     self.token = token
-    for t in token:
-      if not t in string.digits:
-        self.numeric = False
+
     if not self.numeric:
       self.text = True
 
@@ -154,9 +159,14 @@
 # =============================================================================
 class InputMaskParser(Scanner):
   """
+  Custom plex scanner used to contstruct the TODO: put name here
+  from an input mask passed in during initialization.
+  
   Takes a file handle containing an input mask and creates a 
-  list of Tokens which define the input mask.
+  list of Tokens which define the input mask
   """
+
+
   def getType(self):
     """
     Returns the apparent type of this mask.
@@ -222,93 +232,231 @@
     self.produce(Literal(text))
 
   def _repeater(self, text):  
+    """
+    Action to process an input mask repeater.
+    
+    A repeater tells the parser to repeat the previous token a
+    specified number of times.  
+    
+    @param text: The value pulled from between the {} which
+                 denotes the number of times to repeat.
+    """
     self.produce(Repeater(int(text)))
 
   def _begin_set(self, text):
+    """
+    Action to process the start of a set of valid characters.
+    
+    The scanner will be placed into set state and the list
+    of valid characters will be reset.
+    """
     self.begin('set')
     self._set = ""
 
   def _add_set(self, text):
+    """
+    Action to add a character to the set currently being constructed.
+    
+    Only called when the scanner is in state "set".  
+    
+    The character read will be added to the character sting 
+    containing the possible valid values.  
+    """
     self._set += text
 
   def _add_set_2nd(self, text):
+    """
+    Action to add a special character to a set being built.
+    
+    Used when an escaped set character \[ or \] is found
+    in the list of valid characters to be added to the set
+    """
     return self.add_set(text[1:])
 
   def _end_set(self, text):
+    """
+    Action to process the end of a set.
+    
+    Only called when the scanner is in state "set".
+    
+    The list of possible characters that were defined in the set will be used
+    to build an instance of a TokenSet class.  As part of this function the
+    scanner will set to default state.
+    """
     self.begin('')
     self.produce(TokenSet(self._set))
 
-  # Basic lexicon used by both input and output masks
+  # ===========================================================================
+  # Lexicon defintions
+  # ===========================================================================
+  #
+  # ---------------------------------------------------------------------------
+  # Base Lexicon definition
+  # ---------------------------------------------------------------------------
+  # This lexicon is the base used by all masks
+  #
   _lexicon = [
+      # -----------------------------------------------------------------------
+      # Default state definitions
+      # -----------------------------------------------------------------------
+      (Str('\\'),          Begin('escape')),   # found \, set state to escape
+                                               #
+      (Str("'"),           Begin('quoted')),   # found ', set state to quoted
+                                               #
+      (Str('"'),           Begin('quoted2')),  # found ", set state to qoute2
+                                               #
+      (Str('{'),           Begin('repeater')), # found {, set state to repeater
+                                               #
+      (Str('['),           _begin_set),        # found [, execute _begin_set
+                                               # the function will set state 
+                                               # to set when executed
+                                               #
+      (Str(' '),           Literal),           # found a space
+                                               # reutrn a literal char instance
+                                               #
+      (Any('+.,'),         _check_single),     # these characters can appear
+                                               # only once in an input mask
+                                               #
+      (Any('_?AaLlCc'),    TextToken),         # found a text character 
+                                               # return a text token instance
+                                               #
+      (Any('MDYyHISPp:/'), DateToken),         # found a date character
+                                               # return a date token instance
+                                               #
+      (Any('#0'),          NumberToken),       # found a number character
+                                               # return a number token instance
+                                               #
+      (Any('<>'),          CaseModifier),      # found a case modifier
+                                               # return case modifier instance
+      
+      # -----------------------------------------------------------------------
+      # Escape State
+      # -----------------------------------------------------------------------
+      # The escape state is entered whenever a backslash is encountered while
+      # in the default state.  It's purpose is to allow the placement of what
+      # would normally be reserved characters into the input mask
+      # 
       State('escape',  [
-          (AnyChar,        _escape),
+          (AnyChar,        _escape), # No matter which character is next 
+                                     # execute _escape, the function will
+                                     # create a literal instance and set
+                                     # the state back to default
         ]),
 
+      # -----------------------------------------------------------------------
+      # Quoted state
+      # -----------------------------------------------------------------------
+      # The quoted state is entered whenevre a single quote is encountered
+      # thile in the default state.  It's purpose is to allow quoted strings
+      # inside the input mask to sent through as their literal value
+      #
       State('quoted',  [
-          (Str("\\")+Str("'"),  _literal_2nd),
-          (Str("'"),       Begin('')),
-          (AnyChar,        _literal)
+          (Str("\\")+Str("'"), _literal_2nd), # Handle \' in the string
+          (Str("'"),           Begin('')),    # found ', set state to default
+          (AnyChar,            _literal)      # Process as literal character
         ]),
 
+      # -----------------------------------------------------------------------
+      # quote2 state
+      # -----------------------------------------------------------------------
+      # This works the exact same way as the quoted state but is used
+      # when a double quote is encountered.  ' and " get seperate states
+      # so that one type can always enclose the other
+      #
+      # Example : "Today's date: "
+      #
       State('quoted2',  [
-          (Str("\\")+Str('"'),  _literal_2nd),
-          (Str('"'),       Begin('')),
-          (AnyChar,        _literal)
+          (Str("\\")+Str('"'), _literal_2nd), # Handle \" in the string
+          (Str('"'),           Begin('')),    # found ", set state to default
+          (AnyChar,            _literal)      # Process as literal character
         ]),
 
+      # -----------------------------------------------------------------------
+      # repeater state
+      # -----------------------------------------------------------------------
+      # The repeater state is entered whenever a { is encountered
+      # while in the default state.  This state allows an input
+      # mask to include a number inside of {} to cause the previous
+      # token to repeat
+      #
+      # Example : A{5} is the same as AAAAA
+      #
       State('repeater',  [
-          (Str('}'),       Begin('')),
-          (Rep1(digit),    _repeater)
+          (Str('}'),       Begin('')), # found }, set state to default
+          (Rep1(digit),    _repeater)  # grab all digits inside the {}
+                                       # execute _repeater, the function
+                                       # will recreate a repeater instance
+                                       # containing the obtained number
         ]),
 
+      # -----------------------------------------------------------------------
+      # Set state
+      # -----------------------------------------------------------------------
+      # The set state is entered whenever a [ is encountered while in the 
+      # default state.  This provides basic regex set support where any
+      # character inside the [] is matched.
+      #
+      # Example : [ABCDEF]
+      #
       State('set',  [
-          (Str("\\")+Any('[]'),  _add_set_2nd),
-          (Str(']'),       _end_set),
-          (AnyChar,        _add_set)
+          (Str("\\")+Any('[]'),  _add_set_2nd), # 
+          (Str(']'),             _end_set),     # 
+          (AnyChar,              _add_set)      # 
         ]),
-
-      (Str('\\'),          Begin('escape')),
-      (Str("'"),           Begin('quoted')),
-      (Str('"'),           Begin('quoted2')),
-      (Str('{'),           Begin('repeater')),
-      (Str('['),           _begin_set),
-      (Str(' '),           Literal),
-      (Any('+.,'),        _check_single),
-      (Any('_?AaLlCc'),    TextToken),
-      (Any('MDYyHISPp:/'), DateToken),
-      (Any('#0'),         NumberToken),
-      (Any('<>'),          CaseModifier)
   ]
 
-  # Lexicon used by input masks
+  # ---------------------------------------------------------------------------
+  # Additional lexicon definitions for input masks
+  # ---------------------------------------------------------------------------
   _extra_lexicon = [
         (Any('!'),        _check_single),
   ]
 
   def __process(self, token):
     """
-    Adds the standard tokens to the list of tokens
-    generated for this input mask.  Deals with special
-    tokens.
+    Adds a token class instance to this instances list of tokens.
+    
+    As token instances are generated from the input mask they
+    are processed and then added to the scanners working list 
+    of tokens.  Special tokens such as repeater and case modifiers
+    are processed during this state.
     """
+    
     if isinstance(token,Repeater):
+      # If the incoming token is a repeater then replace 
+      # the repeater with the appropriate number of the
+      # previous token.
       for i in range(0, token.count-1):
         self.__process(self.__last)
     elif isinstance(token, CaseModifier):
+      # If then incomming token is a case modifier
+      # then add the modifier token to the list of 
+      # modifiers stored in the scanner
       self.__modify.append(token)
     else:
+      # Standard tokens
       if self.__modify and isinstance(token, TextToken):
+        # If a case modifier is stored and the incoming 
+        # token is text then force case based upon the
+        # modifier
         mod = self.__modify.pop(0)
         if mod.token == '<':
           token.force_upper = True
         elif mod.token == '>':
           token.force_lower = True
+
       self.tokens.append(token)
 
-    self.__last = token
+    # TODO: Should this be storing modifiers and the like? It is.
+    self.__last = token 
 
   def __init__(self, file, name, numeric=False, date=False):
     """
+    Input mask scanner constructor.
+    
+    The input mask scanner will create a list of class instances
+    that describe the input mask.
+    
     @type file: input stream
     @param file: The text to be used as the mask
     @type name: string
@@ -320,8 +468,10 @@
     """
     self.__singles = []
     self.tokens = []
-    self.__last = None
+    self.__last = None  # The last token generated from the input mask
     self.__modify = []
+    
+    
     # -------------------------------------------------------------------------
     # Read the input mask and convert into instances of Token classes
     # -------------------------------------------------------------------------
@@ -332,6 +482,8 @@
         token, extra = self.read()
         if token is None:
           break
+        
+        # Process the returned token 
         self.__process(token)
         
     except Errors.PlexError, msg:
@@ -341,20 +493,18 @@
       print "WARNING: Modifier found at end of mask."
 
     # -------------------------------------------------------------------------
-    # Set appropriate flags
+    # Build a count of the various token types created during parsing
     # -------------------------------------------------------------------------
+    #
+    num_markers   = 0 # Number of numeric token instances found
+    date_markers  = 0 # Number of date token instances found
+    text_markers  = 0 # Number of text token instances found
+    rtl_pos = -1      # Right to left token
+                      # TODO: Unknown functionality at this time
 
-    # If any two of these are non-zero, then the
-    # mask is a text mask, not date or numeric.
-    num_markers = 0
-    date_markers = 0
-    text_markers = 0
-    rtl_pos = -1
-
-    i = 0
-    for token in self.tokens:
+    for (position, token) in enumerate(self.tokens):
       if isinstance(token,RightToLeft):
-        rtl_pos = i
+        rtl_pos = position
       if not isinstance(token, Literal):
         if token.numeric:
           num_markers += 1
@@ -362,8 +512,18 @@
           date_markers += 1
         else:
           text_markers += 1
-      i += 1
+    
+    # Check for "!" in non-numeric mask
+    if rtl_pos >= 0:
+      self.tokens.pop(rtl_pos)
+    else:
+      rtl_pos = 0
 
+    self.rtl_pos = rtl_pos
+
+    # -------------------------------------------------------------------------
+    # Check for errors and mixed marker types
+    # -------------------------------------------------------------------------
     if not (num_markers or date_markers or text_markers):
       raise MaskDefinitionError, 'Mask has no character tokens'
 
@@ -373,15 +533,12 @@
     if date and (num_markers or text_markers):
       raise MaskDefinitionError, 'Date/Time mask has non-date tokens'
 
-    # Check for "!" in non-numeric mask
-    if rtl_pos >= 0:
-      self.tokens.pop(rtl_pos)
-    else:
-      rtl_pos = 0
-
-    self.rtl_pos = rtl_pos
-    
-    # Set the type of parser
+    # -------------------------------------------------------------------------
+    # Set the type of parser based upon the marker counts
+    # -------------------------------------------------------------------------
+    # If any two of these are non-zero, then the mask is a text mask, 
+    # not date or numeric.
+    #
     if (num_markers and date_markers) or text_markers:
       self.type = 'text'
     elif num_markers:





reply via email to

[Prev in Thread] Current Thread [Next in Thread]