Python pycparser.c_ast.Constant() Examples

The following are 18 code examples of pycparser.c_ast.Constant(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module pycparser.c_ast , or try the search function .
Example #1
Source File: test_c_ast.py    From SwiftKitten with MIT License 6 votes vote down vote up
def test_scalar_children(self):
        b1 = c_ast.BinaryOp(
            op='+',
            left=c_ast.Constant(type='int', value='6'),
            right=c_ast.ID(name='joe'))

        cv = self.ConstantVisitor()
        cv.visit(b1)

        self.assertEqual(cv.values, ['6'])

        b2 = c_ast.BinaryOp(
            op='*',
            left=c_ast.Constant(type='int', value='111'),
            right=b1)

        b3 = c_ast.BinaryOp(
            op='^',
            left=b2,
            right=b1)

        cv = self.ConstantVisitor()
        cv.visit(b3)

        self.assertEqual(cv.values, ['111', '6', '6']) 
Example #2
Source File: test_c_ast.py    From SwiftKitten with MIT License 6 votes vote down vote up
def tests_list_children(self):
        c1 = c_ast.Constant(type='float', value='5.6')
        c2 = c_ast.Constant(type='char', value='t')

        b1 = c_ast.BinaryOp(
            op='+',
            left=c1,
            right=c2)

        b2 = c_ast.BinaryOp(
            op='-',
            left=b1,
            right=c2)

        comp = c_ast.Compound(
            block_items=[b1, b2, c1, c2])

        cv = self.ConstantVisitor()
        cv.visit(comp)

        self.assertEqual(cv.values,
            ['5.6', 't', '5.6', 't', 't', '5.6', 't']) 
Example #3
Source File: c_types.py    From mips_to_c with GNU General Public License v3.0 6 votes vote down vote up
def parse_constant_int(expr: "ca.Expression") -> int:
    if isinstance(expr, ca.Constant):
        try:
            return int(expr.value.rstrip("lLuU"), 0)
        except ValueError:
            raise DecompFailure(f"Failed to parse {to_c(expr)} as an int literal")
    if isinstance(expr, ca.BinaryOp):
        lhs = parse_constant_int(expr.left)
        rhs = parse_constant_int(expr.right)
        if expr.op == "+":
            return lhs + rhs
        if expr.op == "-":
            return lhs - rhs
        if expr.op == "*":
            return lhs * rhs
        if expr.op == "<<":
            return lhs << rhs
        if expr.op == ">>":
            return lhs >> rhs
    raise DecompFailure(
        f"Failed to evaluate expression {to_c(expr)} at compile time; only simple arithmetic is supported for now"
    ) 
Example #4
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 6 votes vote down vote up
def conv_ast_to_sym(self, math_ast):
        """
        Convert mathematical expressions to a sympy representation.

        May only contain paranthesis, addition, subtraction and multiplication from AST.
        """
        if type(math_ast) is c_ast.ID:
            return symbol_pos_int(math_ast.name)
        elif type(math_ast) is c_ast.Constant:
            return sympy.Integer(math_ast.value)
        else:  # elif type(dim) is c_ast.BinaryOp:
            op = {
                '*': operator.mul,
                '+': operator.add,
                '-': operator.sub
            }

            return op[math_ast.op](
                self.conv_ast_to_sym(math_ast.left),
                self.conv_ast_to_sym(math_ast.right)) 
Example #5
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 6 votes vote down vote up
def _p_sources(self, stmt):
        sources = []
        assert type(stmt) in \
            [c_ast.ArrayRef, c_ast.Constant, c_ast.ID, c_ast.BinaryOp, c_ast.UnaryOp], \
            'only references to arrays, constants and variables as well as binary operations ' + \
            'are supported'
        assert type(stmt) is not c_ast.UnaryOp or stmt.op in ['-', '--', '++', 'p++', 'p--'], \
            'unary operations are only allowed with -, -- and ++'

        if type(stmt) in [c_ast.ArrayRef, c_ast.ID]:
            # Document data source
            bname = self._get_basename(stmt)
            self.sources.setdefault(bname, set())
            self.sources[bname].add(self._get_offsets(stmt))
        elif type(stmt) is c_ast.BinaryOp:
            # Traverse tree
            self._p_sources(stmt.left)
            self._p_sources(stmt.right)

            self._flops[stmt.op] = self._flops.get(stmt.op, 0)+1
        elif type(stmt) is c_ast.UnaryOp:
            self._p_sources(stmt.expr)
            self._flops[stmt.op] = self._flops.get(stmt.op[-1], 0)+1

        return sources 
Example #6
Source File: test_c_ast.py    From SwiftKitten with MIT License 5 votes vote down vote up
def test_BinaryOp(self):
        b1 = c_ast.BinaryOp(
            op='+',
            left=c_ast.Constant(type='int', value='6'),
            right=c_ast.ID(name='joe'))

        self.failUnless(isinstance(b1.left, c_ast.Constant))
        self.assertEqual(b1.left.type, 'int')
        self.assertEqual(b1.left.value, '6')

        self.failUnless(isinstance(b1.right, c_ast.ID))
        self.assertEqual(b1.right.name, 'joe') 
Example #7
Source File: test_c_ast.py    From SwiftKitten with MIT License 5 votes vote down vote up
def test_weakref_works_on_nodes(self):
        c1 = c_ast.Constant(type='float', value='3.14')
        wr = weakref.ref(c1)
        cref = wr()
        self.assertEqual(cref.type, 'float')
        self.assertEqual(weakref.getweakrefcount(c1), 1) 
Example #8
Source File: extract_ptrace_constants.py    From ptracer with Apache License 2.0 5 votes vote down vote up
def render_const(value):
    if isinstance(value, c_ast.Constant):
        return value.value
    elif isinstance(value, c_ast.BinaryOp):
        return '{} {} {}'.format(
            render_const(value.left), value.op, render_const(value.right))
    else:
        die('unexpected constant value: {!r}'.format(value)) 
Example #9
Source File: extract_ptrace_constants.py    From ptracer with Apache License 2.0 5 votes vote down vote up
def fold_const_expr(expr, typedefs):
    if isinstance(expr, c_ast.BinaryOp):
        left = fold_const_expr(expr.left, typedefs)
        right = fold_const_expr(expr.right, typedefs)
        oper = _binopmap.get(expr.op)
        if oper is None:
            die('cannot fold binop with {!r}'.format(expr.op))

        result = oper(left, right)

    elif isinstance(expr, c_ast.UnaryOp):
        operand = fold_const_expr(expr.expr, typedefs)
        oper = _unopmap.get(expr.op)

        if oper is None:
            die('cannot fold unop with {!r}'.format(expr.op))

        result = oper(operand)

    elif isinstance(expr, c_ast.Constant):
        lit_type = _literalmap.get(expr.type)
        if lit_type is None:
            die('unexpected constant type: {!r}'.format(expr.type))
        result = lit_type(expr.value)

    elif isinstance(expr, c_ast.Typename):
        # sizeof operand
        result = get_final_ctypes_type(expr.type, typedefs)
        _, _, typ = result.rpartition('.')
        result = getattr(ctypes, typ)

    else:
        die('cannot fold {!r} expr'.format(expr))

    return result 
Example #10
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 5 votes vote down vote up
def _build_scalar_initializations(self):
        """Build and return scalar variable initialization."""
        random.seed(2342)  # we want reproducible random numbers
        scalar_inits = []
        for d in self.get_scalar_declarations():
            if d.type.type.names[0] in ['double', 'float']:
                init_const = c_ast.Constant('float', str(random.uniform(1.0, 0.1)))
            elif d.type.type.names[0] in ['int', 'long', 'long long',
                                          'unsigned int', 'unsigned long', 'unsigned long long']:
                    init_const = c_ast.Constant('int', 2)

            scalar_inits.append(c_ast.Assignment(
                '=', c_ast.ID(d.name), init_const))

        return scalar_inits 
Example #11
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 5 votes vote down vote up
def _build_const_declartions(self, with_init=True):
        """
        Generate constants declarations

        :return: list of declarations
        """
        decls = []

        # Use type as provided by user in loop indices
        index_type = self.get_index_type()

        i = 2  # subscript for cli input, 1 is reserved for repeat
        for k in self.constants:
            # const long long N = strtoul(argv[2])
            # with increasing N and 1
            # TODO change subscript of argv depending on constant count
            type_decl = c_ast.TypeDecl(k.name, ['const'], c_ast.IdentifierType(index_type))
            init = None
            if with_init:
                init = c_ast.FuncCall(
                    c_ast.ID('atoi'),
                    c_ast.ExprList([c_ast.ArrayRef(c_ast.ID('argv'),
                                                   c_ast.Constant('int', str(i)))]))
            i += 1
            decls.append(c_ast.Decl(
                k.name, ['const'], [], [],
                type_decl, init, None))

        return decls 
Example #12
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 5 votes vote down vote up
def transform_array_decl_to_malloc(decl, with_init=True):
    """
    Transform ast of "type var_name[N]" to "type* var_name = aligned_malloc(sizeof(type)*N, 32)"

    In-place operation.

    :param with_init: if False, ommit malloc
    """
    if type(decl.type) is not c_ast.ArrayDecl:
        # Not an array declaration, can be ignored
        return

    type_ = c_ast.PtrDecl([], decl.type.type)
    if with_init:
        decl.init = c_ast.FuncCall(
            c_ast.ID('aligned_malloc'),
            c_ast.ExprList([
                c_ast.BinaryOp(
                    '*',
                    c_ast.UnaryOp(
                        'sizeof',
                        c_ast.Typename(None, [], c_ast.TypeDecl(
                            None, [], decl.type.type.type))),
                    decl.type.dim),
                c_ast.Constant('int', '32')]))
    decl.type = type_ 
Example #13
Source File: kernel.py    From kerncraft with GNU Affero General Public License v3.0 5 votes vote down vote up
def _get_offsets(self, aref, dim=0):
        """
        Return a tuple of offsets of an ArrayRef object in all dimensions.

        The index order is right to left (c-code order).
        e.g. c[i+1][j-2] -> (j-2, i+1)

        If aref is actually a c_ast.ID, None will be returned.
        """
        if isinstance(aref, c_ast.ID):
            return None

        # Check for restrictions
        assert type(aref.name) in [c_ast.ArrayRef, c_ast.ID], \
            "array references must only be used with variables or other array references"
        assert type(aref.subscript) in [c_ast.ID, c_ast.Constant, c_ast.BinaryOp], \
            'array subscript must only contain variables or binary operations'

        # Convert subscript to sympy and append
        idxs = [self.conv_ast_to_sym(aref.subscript)]

        # Check for more indices (multi-dimensional access)
        if type(aref.name) is c_ast.ArrayRef:
            idxs += self._get_offsets(aref.name, dim=dim+1)

        # Reverse to preserver order (the subscripts in the AST are traversed backwards)
        if dim == 0:
            idxs.reverse()

        return tuple(idxs) 
Example #14
Source File: cparse.py    From CanCat with BSD 2-Clause "Simplified" License 4 votes vote down vote up
def __init__(self, psize=4, bigend=False):

        self.psize = psize
        self.pclass = vs_prim.v_ptr32

        self.cls_parsers = {
            c_ast.Decl:             self.c_getVsDecl,
            c_ast.Struct:           self.c_getVsStruct,
            c_ast.FileAST:          self.c_getFileAst,
            c_ast.PtrDecl:          self.c_getPointer,
            #c_ast.FuncDecl:         self.c_getFuncDecl,
            c_ast.Constant:         self.c_getConstant,
            c_ast.TypeDecl:         self.c_getVsType,
            c_ast.ArrayDecl:        self.c_getVsArray,
            c_ast.IdentifierType:   self.c_getIdentType,
        }

        self.vs_ctypes = {
            ('char',):                  vs_prim.v_int8,
            ('unsigned','char'):        vs_prim.v_uint8,

            ('short',):                 vs_prim.v_int16,
            ('short','int'):            vs_prim.v_int16,

            ('unsigned', 'short',):     vs_prim.v_uint16,
            ('unsigned', 'short','int'):vs_prim.v_uint16,

            ('int',):                   vs_prim.v_int32,
            ('unsigned','int',):        vs_prim.v_uint32,

            ('long',):                  vs_prim.v_int32,
            ('long','int'):             vs_prim.v_int32,

            ('unsigned','long',):       vs_prim.v_uint32,
            ('unsigned','long','int'):  vs_prim.v_uint32,
        }

        if psize == 8:
            self.pclass = vs_prim.v_ptr64
            self.vs_ctypes.update({
                ('long',):                  vs_prim.v_int64,
                ('long','int'):             vs_prim.v_int64,

                ('unsigned','long',):       vs_prim.v_uint64,
                ('unsigned','long','int'):  vs_prim.v_uint64,
            }) 
Example #15
Source File: cparse.py    From nightmare with GNU General Public License v2.0 4 votes vote down vote up
def __init__(self, psize=4, bigend=False):

        self.psize = psize
        self.pclass = vs_prim.v_ptr32

        self.cls_parsers = {
            c_ast.Decl:             self.c_getVsDecl,
            c_ast.Struct:           self.c_getVsStruct,
            c_ast.FileAST:          self.c_getFileAst,
            c_ast.PtrDecl:          self.c_getPointer,
            #c_ast.FuncDecl:         self.c_getFuncDecl,
            c_ast.Constant:         self.c_getConstant,
            c_ast.TypeDecl:         self.c_getVsType,
            c_ast.ArrayDecl:        self.c_getVsArray,
            c_ast.IdentifierType:   self.c_getIdentType,
        }

        self.vs_ctypes = {
            ('char',):                  vs_prim.v_int8,
            ('unsigned','char'):        vs_prim.v_uint8,

            ('short',):                 vs_prim.v_int16,
            ('short','int'):            vs_prim.v_int16,

            ('unsigned', 'short',):     vs_prim.v_uint16,
            ('unsigned', 'short','int'):vs_prim.v_uint16,

            ('int',):                   vs_prim.v_int32,
            ('unsigned','int',):        vs_prim.v_uint32,

            ('long',):                  vs_prim.v_int32,
            ('long','int'):             vs_prim.v_int32,

            ('unsigned','long',):       vs_prim.v_uint32,
            ('unsigned','long','int'):  vs_prim.v_uint32,
        }

        if psize == 8:
            self.pclass = vs_prim.v_ptr64
            self.vs_ctypes.update({
                ('long',):                  vs_prim.v_int64,
                ('long','int'):             vs_prim.v_int64,

                ('unsigned','long',):       vs_prim.v_uint64,
                ('unsigned','long','int'):  vs_prim.v_uint64,
            }) 
Example #16
Source File: ctypesmngr.py    From miasm with GNU General Public License v2.0 4 votes vote down vote up
def ast_eval_int(self, ast):
        """Eval a C ast object integer

        @ast: parsed pycparser.c_ast object
        """

        if isinstance(ast, c_ast.BinaryOp):
            left = self.ast_eval_int(ast.left)
            right = self.ast_eval_int(ast.right)
            is_pure_int = (isinstance(left, int) and
                           isinstance(right, int))

            if is_pure_int:
                if ast.op == '*':
                    result = left * right
                elif ast.op == '/':
                    assert left % right == 0
                    result = left // right
                elif ast.op == '+':
                    result = left + right
                elif ast.op == '-':
                    result = left - right
                elif ast.op == '<<':
                    result = left << right
                elif ast.op == '>>':
                    result = left >> right
                else:
                    raise NotImplementedError("Not implemented!")
            else:
                result = CTypeOp(ast.op, left, right)

        elif isinstance(ast, c_ast.UnaryOp):
            if ast.op == 'sizeof' and isinstance(ast.expr, c_ast.Typename):
                subobj = self.ast_to_typeid(ast.expr)
                result = CTypeSizeof(subobj)
            else:
                raise NotImplementedError("Not implemented!")

        elif isinstance(ast, c_ast.Constant):
            result = int(ast.value, 0)
        elif isinstance(ast, c_ast.Cast):
            # TODO: Can trunc integers?
            result = self.ast_eval_int(ast.expr)
        else:
            raise NotImplementedError("Not implemented!")
        return result 
Example #17
Source File: objc.py    From miasm with GNU General Public License v2.0 4 votes vote down vote up
def ast_get_c_access_expr(ast, expr_types, lvl=0):
    """Transform C ast object into a C Miasm expression

    @ast: parsed pycparser.c_ast object
    @expr_types: a dictionary linking ID names to their types
    @lvl: actual recursion level

    Example:

    IN:
    StructRef: ->
      ID: ptr_Test
      ID: a

    OUT:
    ExprOp('->', ExprId('ptr_Test', 64), ExprId('a', 64))
    """

    if isinstance(ast, c_ast.Constant):
        obj = ExprInt(int(ast.value), 64)
    elif isinstance(ast, c_ast.StructRef):
        name, field = ast.name, ast.field.name
        name = ast_get_c_access_expr(name, expr_types)
        if ast.type == "->":
            s_name = name
            s_field = ExprId(field, 64)
            obj = ExprOp('->', s_name, s_field)
        elif ast.type == ".":
            s_name = name
            s_field = ExprId(field, 64)
            obj = ExprOp("field", s_name, s_field)
        else:
            raise RuntimeError("Unknown struct access")
    elif isinstance(ast, c_ast.UnaryOp) and ast.op == "&":
        tmp = ast_get_c_access_expr(ast.expr, expr_types, lvl + 1)
        obj = ExprOp("addr", tmp)
    elif isinstance(ast, c_ast.ArrayRef):
        tmp = ast_get_c_access_expr(ast.name, expr_types, lvl + 1)
        index = ast_get_c_access_expr(ast.subscript, expr_types, lvl + 1)
        obj = ExprOp("[]", tmp, index)
    elif isinstance(ast, c_ast.ID):
        assert ast.name in expr_types
        obj = ExprId(ast.name, 64)
    elif isinstance(ast, c_ast.UnaryOp) and ast.op == "*":
        tmp = ast_get_c_access_expr(ast.expr, expr_types, lvl + 1)
        obj = ExprOp("deref", tmp)
    else:
        raise NotImplementedError("Unknown type")
    return obj 
Example #18
Source File: extract_ptrace_constants.py    From ptracer with Apache License 2.0 4 votes vote down vote up
def render_type(typedecl):
    res = []

    if isinstance(typedecl, (c_ast.TypeDecl, c_ast.Typename)):
        res.extend(typedecl.quals)
        res.extend(render_type(typedecl.type))

    elif isinstance(typedecl, c_ast.PtrDecl):
        res.extend(typedecl.quals)
        res.extend(render_type(typedecl.type))
        res.append('*')

    elif isinstance(typedecl, c_ast.IdentifierType):
        res.extend(typedecl.names)

    elif isinstance(typedecl, c_ast.Struct):
        res.extend(['struct', typedecl.name])

    elif isinstance(typedecl, c_ast.Union):
        res.extend(['union', typedecl.name])

    elif isinstance(typedecl, (c_ast.FuncDecl, ext_c_parser.FuncDeclExt)):
        ret = render_type(typedecl.type)
        args = []
        for param in typedecl.args.params:
            args.append(' '.join(render_type(param)))
        ret.append('({})'.format(', '.join(args)))

        res.extend(ret)

    elif isinstance(typedecl, c_ast.ArrayDecl):
        res.extend(render_type(typedecl.type))
        if typedecl.dim is None:
            res.append('[]')
        elif isinstance(typedecl.dim, c_ast.Constant):
            res.append('[{}]'.format(typedecl.dim.value))
        else:
            die('non-constant dimension in array declaration')

    else:
        die('unexpected {!r}'.format(typedecl))

    return res