예제 #1
0
 def createAction(self, statementGroup):
     '''Tries to create an action based on p_statementGroup. If the statement
        is not correct, r_ is -1. Else, r_ is the index of the element within
        the buffer that is the object of the action.'''
     res = -1
     try:
         # Check the whole statement group
         if not statementGroup or (len(statementGroup) > 2):
             raise ParsingError(BAD_STATEMENT_GROUP % str(statementGroup))
         # Check the statement
         statement = statementGroup[0]
         aRes = self.actionRex.match(statement)
         if not aRes:
             raise ParsingError(BAD_STATEMENT % statement)
         statementName, podElem, minus, actionType, subExpr = aRes.groups()
         if not (podElem in PodElement.POD_ELEMS):
             raise ParsingError(BAD_ELEMENT % podElem)
         if minus and (not podElem in PodElement.MINUS_ELEMS):
             raise ParsingError(BAD_MINUS %
                                (podElem, PodElement.MINUS_ELEMS))
         indexPodElem = self.getIndex(podElem)
         if indexPodElem == -1:
             raise ParsingError(
                 ELEMENT_NOT_FOUND % (podElem, str([
                     e.__class__.__name__.lower() \
                     for e in self.elements.values()])))
         podElem = self.elements[indexPodElem]
         # Check the 'from' clause
         fromClause = None
         source = 'buffer'
         if len(statementGroup) > 1:
             fromClause = statementGroup[1]
             source = 'from'
             if not fromClause.startswith('from '):
                 raise ParsingError(BAD_FROM_CLAUSE % fromClause)
             fromClause = fromClause[5:]
         # Create the action
         if actionType == 'if':
             self.action = IfAction(statementName, self, subExpr, podElem,
                                    minus, source, fromClause)
             self.env.ifActions.append(self.action)
             if self.action.name:
                 # We must register this action as a named action
                 if self.env.namedIfActions.has_key(self.action.name):
                     raise ParsingError(DUPLICATE_NAMED_IF)
                 self.env.namedIfActions[self.action.name] = self.action
         elif actionType == 'else':
             if not self.env.ifActions:
                 raise ParsingError(ELSE_WITHOUT_IF)
             # Does the "else" action reference a named "if" action?
             ifReference = subExpr.strip()
             if ifReference:
                 if not self.env.namedIfActions.has_key(ifReference):
                     raise ParsingError(ELSE_WITHOUT_NAMED_IF % ifReference)
                 linkedIfAction = self.env.namedIfActions[ifReference]
                 # This "else" action "consumes" the "if" action: this way,
                 # it is not possible to define two "else" actions related to
                 # the same "if".
                 del self.env.namedIfActions[ifReference]
                 self.env.ifActions.remove(linkedIfAction)
             else:
                 linkedIfAction = self.env.ifActions.pop()
             self.action = ElseAction(statementName, self, None, podElem,
                                      minus, source, fromClause,
                                      linkedIfAction)
         elif actionType == 'for':
             forRes = MemoryBuffer.forRex.match(subExpr.strip())
             if not forRes:
                 raise ParsingError(BAD_FOR_EXPRESSION % subExpr)
             iter, subExpr = forRes.groups()
             self.action = ForAction(statementName, self, subExpr, podElem,
                                     minus, iter, source, fromClause)
         elif actionType == 'with':
             variables = self._getVariables(subExpr)
             self.action = VariablesAction(statementName, self, podElem,
                                           minus, variables, source,
                                           fromClause)
         else:  # null action
             if not fromClause:
                 raise ParsingError(NULL_ACTION_ERROR)
             self.action = NullAction(statementName, self, None, podElem,
                                      None, source, fromClause)
         res = indexPodElem
     except ParsingError, ppe:
         PodError.dump(self, ppe, removeFirstLine=True)