[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r8362 - trunk/gnue-common/src/formatting/masks
From: |
jamest |
Subject: |
[gnue] r8362 - trunk/gnue-common/src/formatting/masks |
Date: |
Tue, 4 Apr 2006 21:23:02 -0500 (CDT) |
Author: jamest
Date: 2006-04-04 21:23:02 -0500 (Tue, 04 Apr 2006)
New Revision: 8362
Modified:
trunk/gnue-common/src/formatting/masks/MaskParser.py
Log:
old uncommited changes to MaskParser (all formatting I think)
start of pep8-ification
Modified: trunk/gnue-common/src/formatting/masks/MaskParser.py
===================================================================
--- trunk/gnue-common/src/formatting/masks/MaskParser.py 2006-04-05
02:15:18 UTC (rev 8361)
+++ trunk/gnue-common/src/formatting/masks/MaskParser.py 2006-04-05
02:23:02 UTC (rev 8362)
@@ -19,137 +19,140 @@
# Copyright 2001-2006 Free Software Foundation
#
# FILE:
-# masks.py
+# MaskParser
#
# DESCRIPTION:
"""
-Parse mask definitions into tokens that the Mask class can use.
+A parser which takes a text based mask and generates a list of
+token class instances that represent that mask. Any repeaters
+found in the mask ({3}) are replaced with the appropriate number
+of tokens so that the mask class will not have to deal with
+them.
-Tokens are ......
+Valid tokens include:
+
"""
-# NOTES:
-#
-from gnue.common.external.plex import *
+__revision__ = "$Id$"
+
+from gnue.common.external.plex import Scanner, Lexicon, Errors, \
+ Str, Begin, State, AnyChar, Rep1, Any
import string
-from Errors import *
+from Errors import MaskDefinitionError
-# TODO: Why is this here?
-digit = Any(string.digits)
-
class BaseToken:
- """
- Basic parser token class.
-
- Not used directly, but inherited by the other defined tokens
- Literal, Token, etc.
- """
- numeric=False
- date=False
- text=False
- literal=False
- token=False
+ """
+ Basic parser token class.
- def __init__(self, t1, t2=None, *args):
+ Not used directly, but inherited by the other defined tokens
+ Literal, Token, etc.
"""
- Token construtor
- """
- if t2:
- self.token = t2
- else:
- self.token = t1
+ numeric = False
+ date = False
+ text = False
+ literal = False
+ token = False
+ def __init__(self, t1, t2=None, *args):
+ """
+ Token construtor
+ """
+ if t2:
+ self.token = t2
+ else:
+ self.token = t1
+
# -----------------------------------------------------------------------------
# Standard token classes
# -----------------------------------------------------------------------------
class Token(BaseToken):
- """
- Class typically used to create normal tokens as
- opposed to special tokens like literal.
-
- It sets the standard options so that each individual
- token class doesn't need to.
- """
- force_lower = False
- force_upper = False
- token=True
+ """
+ Class typically used to create normal tokens as
+ opposed to special tokens like literal.
+ It sets the standard options so that each individual
+ token class doesn't need to.
+ """
+ force_lower = False
+ force_upper = False
+ token = True
+
class NumberToken(Token):
- """
- Numeric token (#9-,.)
- """
- numeric = True
+ """
+ Numeric token (#9-,.)
+ """
+ numeric = True
class DateToken(Token):
- """
- Date token (MDYyHIS:/)
- """
- date=True
+ """
+ Date token (MDYyHIS:/)
+ """
+ date = True
class TextToken(Token):
- """
- Text token
-
- A test token represents 1 standard alphanumeric character.
- """
- text = True
+ """
+ Text token
+ A test token represents 1 standard alphanumeric character.
+ """
+ text = True
+
class TokenSet(Token):
- """
- Token defined by user with [] notation.
- Can behave like a NumberToken or TextToken,
- depending on contents of [].
- """
- def __init__(self, token, *args):
- # TODO: Expand the set
- # Are we all-numeric?
- self.numeric = token.isdigit()
- self.token = token
+ """
+ Token defined by user with [] notation.
+ Can behave like a NumberToken or TextToken,
+ depending on contents of [].
+ """
+ def __init__(self, token, *args):
+ # TODO: Expand the set
+ # Are we all-numeric?
+ self.numeric = token.isdigit()
+ self.token = token
- if not self.numeric:
- self.text = True
+ if not self.numeric:
+ self.text = True
# -----------------------------------------------------------------------------
# Special token classes
# -----------------------------------------------------------------------------
class Literal(BaseToken):
- """
- A literal string that the developer wants in the string.
- Note that for our purposes, the basic "literals" aren't
- really Literals(), but special cases of Token classes.
- So all literals represented by this class are denoted
- with \ or "" syntaxes.
- """
- literal=True
+ """
+ A literal string that the developer wants in the string.
+ Note that for our purposes, the basic "literals" aren't
+ really Literals(), but special cases of Token classes.
+ So all literals represented by this class are denoted
+ with \ or "" syntaxes.
+ """
+ literal = True
class RightToLeft(BaseToken):
- """
- Temporary token class used to note the
- position of ! modifiers
- """
- numeric = True
+ """
+ Temporary token class used to note the
+ position of ! modifiers
+ """
+ numeric = True
class CaseModifier:
- """
- Temporary token class used to record > and <
- markers. These cause the modified token to have
- either force_upper or force_lower set, so the
- other classes won't ever see CaseModifier
- instances.
- """
- pass
+ """
+ Temporary token class used to record > and <
+ markers. These cause the modified token to have
+ either force_upper or force_lower set, so the
+ other classes won't ever see CaseModifier
+ instances.
+ """
+ pass
class Repeater:
- """
- Temporary token class used to record {#}
- markers. These are replaced with the actual
- represented tokens before being passed out
- of MaskParser (i.e., 0{3} would be returned
- as 000, so the other classes won't ever see
- Repeater instances.
- """
- def __init__(self, count):
- self.count = count
+ """
+ Temporary token class used to record {#}
+ markers. These are replaced with the actual
+ represented tokens before being passed out
+ of MaskParser (i.e., 0{3} would be returned
+ as 000, so the other classes won't ever see
+ Repeater instances.
+ """
+ def __init__(self, count):
+ self.count = count
##
##
@@ -158,390 +161,394 @@
# Input mask parser
# =============================================================================
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
- """
-
-
- def getType(self):
"""
- Returns the apparent type of this mask.
-
- @rtype: string
- @return: The value 'text', 'numeric', or 'date'
- """
- return type
+ Custom plex scanner used to contstruct the TODO: put name here
+ from an input mask passed in during initialization.
- def getTokens(self):
+ Takes a file handle containing an input mask and creates a
+ list of Tokens which define the input mask
"""
- Returns a list of the tokens after parsing the input mask.
-
- @rtype: list
- @return: The list of tokens
- """
- return self.tokens[:]
- # ===========================================================================
- # Private stuff
- # ===========================================================================
-
- # ---------------------------------------------------------------------------
- # Lexicon action functions
- # ---------------------------------------------------------------------------
- def _check_single(self, text):
- """
- Function to add single instance tokens to the input mask.
-
- A single instance token is something that can appear only once
- in an input mask.
- """
- if text in self.__singles:
- raise Errors.UnrecognizedInput(self, 'Mask can only have one "%s" token'
%text)
- self.__singles.append(text)
- if text == '!':
- self.produce (RightToLeft(text))
- elif text in '.+,':
- self.produce(NumberToken(text))
- else:
- self.produce(TextToken(text))
- def _literal(self, text):
- """
- A text literal that should appear as is in the mask
- """
- print "literal %s" % text
- self.produce(Literal(text))
+ def getType(self):
+ """
+ Returns the apparent type of this mask.
- def _literal_2nd(self, text):
- """
- Closes the literal string
- """
- print "literal 2nd %s" % text
- return self.literal(text[1:])
+ @rtype: string
+ @return: The value 'text', 'numeric', or 'date'
+ """
+ return type
- def _escape(self, text):
- """
- An escaped character such as \$ to display a $
- """
- print "escape %s" % text
- self.begin('')
- self.produce(Literal(text))
+ def getTokens(self):
+ """
+ Returns a list of the tokens after parsing the input mask.
- 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)))
+ @rtype: list
+ @return: The list of tokens
+ """
+ return self.tokens[:]
- 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 = ""
+ #
===========================================================================
+ # Private stuff
+ #
===========================================================================
- 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
+ #
---------------------------------------------------------------------------
+ # Lexicon action functions
+ #
---------------------------------------------------------------------------
+ def _check_single(self, text):
+ """
+ Function to add single instance tokens to the input mask.
- 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:])
+ A single instance token is something that can appear only once
+ in an input mask.
+ """
+ if text in self.__singles:
+ raise Errors.UnrecognizedInput(self, 'Mask can only have one "%s"
token' %text)
+ self.__singles.append(text)
+ if text == '!':
+ self.produce (RightToLeft(text))
+ elif text in '.+,':
+ self.produce(NumberToken(text))
+ else:
+ self.produce(TextToken(text))
- 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))
+ def _literal(self, text):
+ """
+ A text literal that should appear as is in the mask
+ """
+ print "literal %s" % text
+ self.produce(Literal(text))
- # ===========================================================================
- # 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), # No matter which character is next
- # execute _escape, the function will
- # create a literal instance and set
- # the state back to default
- ]),
+ def _literal_2nd(self, text):
+ """
+ Closes the literal string
+ """
+ print "literal 2nd %s" % text
+ return self.literal(text[1:])
- # -----------------------------------------------------------------------
- # 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), # Handle \' in the string
- (Str("'"), Begin('')), # found ', set state to default
- (AnyChar, _literal) # Process as literal character
- ]),
+ def _escape(self, text):
+ """
+ An escaped character such as \$ to display a $
+ """
+ print "escape %s" % text
+ self.begin('')
+ self.produce(Literal(text))
- # -----------------------------------------------------------------------
- # 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), # Handle \" in the string
- (Str('"'), Begin('')), # found ", set state to default
- (AnyChar, _literal) # Process as literal character
- ]),
+ def _repeater(self, text):
+ """
+ Action to process an input mask repeater.
- # -----------------------------------------------------------------------
- # 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('')), # 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
- ]),
+ A repeater tells the parser to repeat the previous token a
+ specified number of times.
- # -----------------------------------------------------------------------
- # 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) #
- ]),
- ]
+ @param text: The value pulled from between the {} which
+ denotes the number of times to repeat.
+ """
+ self.produce(Repeater(int(text)))
- # ---------------------------------------------------------------------------
- # Additional lexicon definitions for input masks
- # ---------------------------------------------------------------------------
- _extra_lexicon = [
- (Any('!'), _check_single),
- ]
+ def _begin_set(self, text):
+ """
+ Action to process the start of a set of valid characters.
- def __process(self, token):
- """
- 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
+ The scanner will be placed into set state and the list
+ of valid characters will be reset.
+ """
+ self.begin('set')
+ self._set = ""
- self.tokens.append(token)
+ def _add_set(self, text):
+ """
+ Action to add a character to the set currently being constructed.
- # TODO: Should this be storing modifiers and the like? It is.
- self.__last = token
+ Only called when the scanner is in state "set".
- 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
- @param name: The name of the input mask(TODO: ?)
- @type numeric: boolean
- @param numeric: Is this a numeric input mask
- @type date: boolean
- @param date: Is this a numeric input mask
- """
- self.__singles = []
- self.tokens = []
- self.__last = None # The last token generated from the input mask
- self.__modify = []
-
-
- # -------------------------------------------------------------------------
- # Read the input mask and convert into instances of Token classes
- # -------------------------------------------------------------------------
- try:
- Scanner.__init__(self, Lexicon(self._lexicon + self._extra_lexicon),
file, name)
+ The character read will be added to the character sting
+ containing the possible valid values.
+ """
+ self._set += text
- while True:
- token, extra = self.read()
- if token is None:
- break
-
- # Process the returned token
- self.__process(token)
-
- except Errors.PlexError, msg:
- raise MaskDefinitionError, msg
+ def _add_set_2nd(self, text):
+ """
+ Action to add a special character to a set being built.
- if self.__modify:
- print "WARNING: Modifier found at end of mask."
+ 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:])
- # -------------------------------------------------------------------------
- # Build a count of the various token types created during parsing
- # -------------------------------------------------------------------------
+ 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))
+
+ #
===========================================================================
+ # Lexicon defintions
+ #
===========================================================================
#
- 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
+ #
---------------------------------------------------------------------------
+ # Base Lexicon definition
+ #
---------------------------------------------------------------------------
+ # This lexicon is the base used by all masks
+ #
- for (position, token) in enumerate(self.tokens):
- if isinstance(token,RightToLeft):
- rtl_pos = position
- if not isinstance(token, Literal):
- if token.numeric:
- num_markers += 1
- elif token.date:
- date_markers += 1
+ _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), # 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 whenever 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), # 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), # 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('')),# found }, set state to
default
+ (Rep1(Any(string.digits)), _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) #
+ ]),
+ ]
+
+ #
---------------------------------------------------------------------------
+ # Additional lexicon definitions for input masks
+ #
---------------------------------------------------------------------------
+ _extra_lexicon = [
+ (Any('!'), _check_single),
+ ]
+
+ def __process(self, token):
+ """
+ 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:
- text_markers += 1
-
- # Check for "!" in non-numeric mask
- if rtl_pos >= 0:
- self.tokens.pop(rtl_pos)
- else:
- rtl_pos = 0
+ # 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.rtl_pos = rtl_pos
+ self.tokens.append(token)
- # -------------------------------------------------------------------------
- # Check for errors and mixed marker types
- # -------------------------------------------------------------------------
- if not (num_markers or date_markers or text_markers):
- raise MaskDefinitionError, 'Mask has no character tokens'
+ # TODO: Should this be storing modifiers and the like? It is.
+ self.__last = token
- if numeric and (date_markers or text_markers):
- raise MaskDefinitionError, 'Numeric mask has non-numeric tokens'
+ def __init__(self, mask, name, numeric=False, date=False):
+ """
+ Input mask scanner constructor.
- if date and (num_markers or text_markers):
- raise MaskDefinitionError, 'Date/Time mask has non-date tokens'
+ The input mask scanner will create a list of class instances
+ that describe the input mask.
- # -------------------------------------------------------------------------
- # 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:
- self.type = 'numeric'
- else:
- self.type = 'date'
+ @type mask: input stream
+ @param mask: The text to be used as the mask
+ @type name: string
+ @param name: The name of the input mask(TODO: ?)
+ @type numeric: boolean
+ @param numeric: Is this a numeric input mask
+ @type date: boolean
+ @param date: Is this a numeric input mask
+ """
+ self.__singles = []
+ self.tokens = []
+ self.__last = None # The last token generated from the input mask
+ self.__modify = []
+
+
+ #
-------------------------------------------------------------------------
+ # Read the input mask and convert into instances of Token classes
+ #
-------------------------------------------------------------------------
+ try:
+ Scanner.__init__(self,
+ Lexicon(self._lexicon + self._extra_lexicon),
+ mask, name)
+
+ while True:
+ token, extra = self.read()
+ if token is None:
+ break
+
+ # Process the returned token
+ self.__process(token)
+
+ except Errors.PlexError, msg:
+ raise MaskDefinitionError, msg
+
+ if self.__modify:
+ print "WARNING: Modifier found at end of mask."
+
+ #
-------------------------------------------------------------------------
+ # 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
+
+ for (position, token) in enumerate(self.tokens):
+ if isinstance(token, RightToLeft):
+ rtl_pos = position
+ if not isinstance(token, Literal):
+ if token.numeric:
+ num_markers += 1
+ elif token.date:
+ date_markers += 1
+ else:
+ text_markers += 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'
+
+ if numeric and (date_markers or text_markers):
+ raise MaskDefinitionError, 'Numeric mask has non-numeric tokens'
+
+ if date and (num_markers or text_markers):
+ raise MaskDefinitionError, 'Date/Time mask has non-date tokens'
+
+ #
-------------------------------------------------------------------------
+ # 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:
+ self.type = 'numeric'
+ else:
+ self.type = 'date'
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r8362 - trunk/gnue-common/src/formatting/masks,
jamest <=