Logo Search packages:      
Sourcecode: calibre version File versions

def cssutils::prodparser::ProdParser::parse (   self,
  text,
  name,
  productions,
  store = None 
)

text (or token generator)
    to parse, will be tokenized if not a generator yet

    may be:
    - a string to be tokenized
    - a single token, a tuple
    - a tuple of (token, tokensGenerator)
    - already tokenized so a tokens generator

name
    used for logging
productions
    used to parse tokens
store  UPDATED
    If a Prod defines ``toStore`` the key defined there
    is a key in store to be set or if store[key] is a list
    the next Item is appended here.

    TODO: NEEDED? :
    Key ``raw`` is always added and holds all unprocessed
    values found

returns
    :wellformed: True or False
    :seq: a filled cssutils.util.Seq object which is NOT readonly yet
    :store: filled keys defined by Prod.toStore
    :unusedtokens: token generator containing tokens not used yet

Definition at line 362 of file prodparser.py.

00362                                                         :
        """
        text (or token generator)
            to parse, will be tokenized if not a generator yet

            may be:
            - a string to be tokenized
            - a single token, a tuple
            - a tuple of (token, tokensGenerator)
            - already tokenized so a tokens generator

        name
            used for logging
        productions
            used to parse tokens
        store  UPDATED
            If a Prod defines ``toStore`` the key defined there
            is a key in store to be set or if store[key] is a list
            the next Item is appended here.

            TODO: NEEDED? :
            Key ``raw`` is always added and holds all unprocessed
            values found

        returns
            :wellformed: True or False
            :seq: a filled cssutils.util.Seq object which is NOT readonly yet
            :store: filled keys defined by Prod.toStore
            :unusedtokens: token generator containing tokens not used yet
        """
        tokens = self._texttotokens(text)
        if not tokens:
            self._log.error(u'No content to parse.')
            # TODO: return???

        seq = cssutils.util.Seq(readonly=False)
        if not store: # store for specific values
            store = {}
        prods = [productions] # stack of productions
        wellformed = True

        # while no real token is found any S are ignored
        started = False
        prod = None
        # flag if default S handling should be done
        defaultS = True
        while True:
            try:
                token = tokens.next()
            except StopIteration:
                break
            type_, val, line, col = token

            # default productions
            if type_ == self.types.COMMENT:
                # always append COMMENT
                seq.append(cssutils.css.CSSComment(val),
                           cssutils.css.CSSComment, line, col)
            elif defaultS and type_ == self.types.S:
                # append S (but ignore starting ones)
                if started:
                    seq.append(val, type_, line, col)
                else:
                    continue
#            elif type_ == self.types.ATKEYWORD:
#                # @rule
#                r = cssutils.css.CSSUnknownRule(cssText=val)
#                seq.append(r, type(r), line, col)
            elif type_ == self.types.INVALID:
                # invalidate parse
                wellformed = False
                self._log.error(u'Invalid token: %r' % (token,))
                break
            elif type_ == 'EOF':
                # do nothing? (self.types.EOF == True!)
                pass
            else:
                started = True # check S now
                nextSor = False # reset

                try:
                    while True:
                        # find next matching production
                        try:
                            prod = prods[-1].nextProd(token)
                        except (Exhausted, NoMatch), e:
                            # try next
                            prod = None
                        if isinstance(prod, Prod):
                            # found actual Prod, not a Choice or Sequence
                            break
                        elif prod:
                            # nested Sequence, Choice
                            prods.append(prod)
                        else:
                            # nested exhausted, try in parent
                            if len(prods) > 1:
                                prods.pop()
                            else:
                                raise ParseError('No match')
                except ParseError, e:
                    wellformed = False
                    self._log.error(u'%s: %s: %r' % (name, e, token))
                    break
                else:
                    # process prod
                    if prod.toSeq:
                        type_, val = prod.toSeq(token, tokens)
                    if val is not None:
                        seq.append(val, type_, line, col)
                    if prod.toStore:
                        prod.toStore(store, seq[-1])
                    if prod.stop: # EOF?
                        # stop here and ignore following tokens
                        break
                    if prod.nextSor:
                        # following is S or other token (e.g. ",")?
                        # remove S if
                        tokens = self._SorTokens(tokens, ',/')
                        defaultS = False
                    else:
                        defaultS = True

        lastprod = prod
        while True:
            # all productions exhausted?
            try:
                prod = prods[-1].nextProd(token=None)
            except Done, e:
                # ok
                prod = None

            except Missing, e:
                prod = None
                # last was a S operator which may End a Sequence, then ok
                if hasattr(lastprod, 'mayEnd') and not lastprod.mayEnd:
                    wellformed = False
                    self._log.error(u'%s: %s' % (name, e))

            except ParseError, e:
                prod = None
                wellformed = False
                self._log.error(u'%s: %s' % (name, e))

            else:
                if prods[-1].optional:
                    prod = None
                elif prod and prod.optional:
                    # ignore optional
                    continue

            if prod and not prod.optional:
                wellformed = False
                self._log.error(u'%s: Missing token for production %r'
                                % (name, str(prod)))
                break
            elif len(prods) > 1:
                # nested exhausted, next in parent
                prods.pop()
            else:
                break

        # trim S from end
        seq.rstrip()
        return wellformed, seq, store, tokens



Generated by  Doxygen 1.6.0   Back to index