Exemplo n.º 1
0
class Cpp_If_Stmt(WORDClsBase):
    '''
    C99 6.10.1 Conditional inclusion

    if-stmt is  # if constant-expression new-line
                or ifdef identifier new-line
                or ifndef identifier new-line

    '''

    subclass_names = []
    use_names = ['Cpp_Macro_Identifier', 'Cpp_Pp_Tokens']

    _regex = re.compile(r"#\s*(ifdef|ifndef|if)\b")
    _if_pattern = pattern.Pattern('<if>', r'^\s*#\s*if\b', value='#if')
    _def_pattern = (pattern.Pattern('<ifdef>',
                                    r'^\s*#\s*ifdef\b',
                                    value='#ifdef'),
                    pattern.Pattern('<ifndef>',
                                    r'^\s*#\s*ifndef\b',
                                    value='#ifndef'))

    @staticmethod
    def match(string):
        '''Implements the matching for an if preprocessor directive
        (or its variations ifdef, ifndef). For ifdef and ifndef
        statements it matches the macro identifier using
        :py:class:`fparser.two.C99Preprocesser.Cpp_Macro_Identifier`
        otherwise it uses :py:class:`fparser.two.C99Preprocessor.Cpp_Pp_Tokens`
        to accept any non-empty string as rhs.

        :param str string: the string to match with as an if statement.

        :return: a tuple of size 2 containing the statement's keyword \
                  and the right hand side, or `None` if there is no match.
        :rtype: \
          (`str`, py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`)\
          or (`str`, py:class:`fparser.two.C99Preprocessor.Cpp_Pp_Tokens`) \
          or `NoneType`

        '''
        if not string:
            return None
        result = WORDClsBase.match(Cpp_If_Stmt._if_pattern,
                                   Cpp_Pp_Tokens,
                                   string,
                                   colons=False,
                                   require_cls=True)
        return result or WORDClsBase.match(Cpp_If_Stmt._def_pattern,
                                           Cpp_Macro_Identifier,
                                           string,
                                           colons=False,
                                           require_cls=True)

    def tostr(self):
        '''
        :return: this if-stmt as a string.
        :rtype: str
        '''
        return '{0} {1}'.format(*self.items)
Exemplo n.º 2
0
class Cpp_Endif_Stmt(StringBase):
    '''
    C99 6.10.1 Conditional inclusion

    endif-stmt is  # endif new-line

    '''

    subclass_names = []

    _pattern = pattern.Pattern('<endif>', r'^\s*#\s*endif\b', value='#endif')

    @staticmethod
    def match(string):
        '''Implements the matching for an endif preprocessor directive.

        :param str string: the string to match with as an endif statement.

        :return: a 1-tuple containing the matched string or `None` if \
                  there is no match.
        :rtype: (str,) or NoneType

        '''
        if not string:
            return None
        return StringBase.match(Cpp_Endif_Stmt._pattern, string)

    def tostr(self):
        '''
        :return: this endif-stmt as a string.
        :rtype: str
        '''
        return self.string
Exemplo n.º 3
0
class Cpp_Warning_Stmt(WORDClsBase):
    '''
    Not actually part of C99 but supported by most preprocessors and
    with syntax identical to Cpp_Error_Stmt

    warning-stmt is # warning [pp-tokens] new-line

    '''

    subclass_names = []
    use_names = ['Cpp_Pp_Tokens']

    _pattern = pattern.Pattern('<warning>',
                               r'^\s*#\s*warning\b',
                               value='#warning')

    @staticmethod
    def match(string):
        '''Implements the matching for a warning preprocessor directive.
        The optional right hand side of the directive is not matched any
        further but simply kept as a string.

        :param str string: the string to match with as a line statement.

        :return: an empty tuple or a tuple of size  1 with the right hand \
                  side as a string, or `None` if there is no match.
        :rtype: () or (`str`) or `NoneType`

        '''
        if not string:
            return None
        return WORDClsBase.match(Cpp_Warning_Stmt._pattern,
                                 Cpp_Pp_Tokens,
                                 string,
                                 colons=False,
                                 require_cls=False)

    def tostr(self):
        '''
        :return: this warning-stmt as a string.
        :rtype: str
        '''
        if self.items[1]:
            return '{0} {1}'.format(*self.items)
        return self.items[0]
Exemplo n.º 4
0
class Cpp_Undef_Stmt(WORDClsBase):
    '''Implements the matching of a preprocessor undef statement for a macro.

    undef-stmt is # undef identifier new-line

    Strictly, this is part of 6.10.3 but since it is identified by a different
    directive keyword (undef instead of define) we treat it separately.

    '''

    subclass_names = []

    use_names = ['Cpp_Macro_Identifier']

    _pattern = pattern.Pattern('<undef>', r'^\s*(#\s*undef)\b', value='#undef')

    @staticmethod
    def match(string):
        '''Implements the matching for a preprocessor undef statement
        for a macro. The macro identifier is matched using
        :py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`.

        :param str string: the string to match with as an if statement.

        :return: a tuple of size 1 containing the macro identifier, or\
                  `None` if there is no match.
        :rtype: (py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`) \
                or `NoneType`

        '''
        if not string:
            return None
        return WORDClsBase.match(Cpp_Undef_Stmt._pattern,
                                 Cpp_Macro_Identifier,
                                 string,
                                 colons=False,
                                 require_cls=True)

    def tostr(self):
        '''
        :return: this undef-stmt as a string.
        :rtype: str
        '''
        return '{0} {1}'.format(*self.items)
Exemplo n.º 5
0
class Cpp_Macro_Identifier_List(StringBase):
    '''Implements the matching of an identifier list in a macro definition.

    identifier-list is (identifier [, identifier-list or ...])
                       or (...)
    '''

    subclass_names = []

    _pattern = pattern.Pattern(
        '<identifier-list>', r'\((\s*[A-Za-z_]\w*'
        r'(?:\s*,\s*[A-Za-z_]\w*)*'
        r'(?:\s*,\s*\.{3})?|\.{3})?\s*\)')

    @staticmethod
    def match(string):
        '''Implements the matching of a macro identifier list as part of
        a macro definition. It must consist of one or more macro
        identifier separated by comma, or "..." for a variadic argument
        list, and must be surrouned by parentheses.

        For simplicity, the matched list is kept as a single string and not
        matched as
        :py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`.

        :param str string: the string to match with the pattern rule.

        :return: a tuple of size 1 containing a string with the \
                 matched identifier list if there is a match, or None if \
                 there is not.
        :rtype: (`str`,) or `NoneType`

        '''
        if not string:
            return None
        return StringBase.match(Cpp_Macro_Identifier_List._pattern, string)

    def tostr(self):
        '''
        :return: this macro-identifier-list as a string.
        :rtype: str
        '''
        return self.string
Exemplo n.º 6
0
class Cpp_Error_Stmt(WORDClsBase):  # 6.10.5 Error directive
    '''
    C99 6.10.5 Error directive

    error-stmt is # error [pp-tokens] new-line

    '''

    subclass_names = []
    use_names = ['Cpp_Pp_Tokens']

    _pattern = pattern.Pattern('<error>', r'^\s*#\s*error\b', value='#error')

    @staticmethod
    def match(string):
        '''Implements the matching for an error preprocessor directive.
        The optional right hand side of the directive is not matched any
        further but simply kept as a string.

        :param str string: the string to match with as a line statement.

        :return: an empty tuple or a tuple of size  1 with the right hand \
                  side as a string, or `None` if there is no match.
        :rtype: () or (`str`) or `NoneType`

        '''
        if not string:
            return None
        return WORDClsBase.match(Cpp_Error_Stmt._pattern,
                                 Cpp_Pp_Tokens,
                                 string,
                                 colons=False,
                                 require_cls=False)

    def tostr(self):
        '''
        :return: this error-stmt as a string.
        :rtype: str
        '''
        if self.items[1]:
            return '{0} {1}'.format(*self.items)
        return self.items[0]
Exemplo n.º 7
0
class Cpp_Line_Stmt(WORDClsBase):  # 6.10.4 Line control
    '''
    C99 6.10.4 Line control

    line-stmt is # line digit-sequence [ "s-char-sequence" ] new-line
                        or pp-tokens new-line
    '''

    subclass_names = []
    use_names = ['Cpp_Pp_Tokens']

    _pattern = pattern.Pattern('<line>', r'^\s*#\s*line\b', value='#line')

    @staticmethod
    def match(string):
        '''Implements the matching for a line preprocessor directive.
        The right hand side of the directive is not matched any further
        but simply kept as a string.

        :param str string: the string to match with as a line statement.

        :return: a tuple of size 1 with the right hand side as a string, \
                  or `None` if there is no match.
        :rtype: (`str`) or `NoneType`

        '''
        if not string:
            return None
        return WORDClsBase.match(Cpp_Line_Stmt._pattern,
                                 Cpp_Pp_Tokens,
                                 string,
                                 colons=False,
                                 require_cls=True)

    def tostr(self):
        '''
        :return: this line-stmt as a string.
        :rtype: str
        '''
        return '{0} {1}'.format(*self.items)
Exemplo n.º 8
0
class Cpp_Elif_Stmt(WORDClsBase):
    '''
    C99 6.10.1 Conditional inclusion

    elif-stmt is  # elif constant-expression new-line

    '''

    subclass_names = []
    use_names = ['Cpp_Pp_Tokens']

    _pattern = pattern.Pattern('<elif-stmt>', r'^\s*#\s*elif\b', value='#elif')

    @staticmethod
    def match(string):
        '''Implements the matching for an elif preprocessor directive.

        :param str string: the string to match with as an elif statement.

        :return: a tuple of size 2 containing the statements keyword and \
                  right hand side, or `None` if there is no match.
        :rtype: \
            (`str`, :py:class:`fparser.two.C99_Preprocessor.Cpp_Pp_Tokens`) \
            or `NoneType`

        '''
        if not string:
            return None
        return WORDClsBase.match(Cpp_Elif_Stmt._pattern,
                                 Cpp_Pp_Tokens,
                                 string,
                                 colons=False,
                                 require_cls=True)

    def tostr(self):
        '''
        :return: this elif-stmt as a string.
        :rtype: str
        '''
        return '{0} {1}'.format(*self.items)