1"""Samples showing the parsing of common programming-language constructs 2 3numbers 4 integers 5 int 6 int_unsigned 7 8 hexidecimal integers 9 hex 10 11 floats (including exponents, requring a '.' in the literal) 12 float 13 floats, with optional integer-only exponents 14 float_floatexp 15 floats, with optional integer or float exponents 16 17 imaginary_number 18 (float/int),[jJ] 19 20 number 21 hex/float/int 22 number_full 23 binary_number/imaginary_number/hex/float/int 24 25 binary_number 26 signed binary number 27 1001001b or 1001001B bit-field format, 28 optional sign 29 can be used with number as (binary_number/number) 30 31Interpreters: 32 33 IntInterpreter 34 int, int_unsigned 35 HexInterpreter 36 hex 37 FloatInterpreter 38 float 39 FloatFloatExpInterpreter 40 float_floatexp 41 BinaryInterpreter 42 binary_number 43 ImaginaryInterpreter 44 imaginary_number 45 46""" 47from simpleparse.parser import Parser 48from simpleparse import common, objectgenerator 49from simpleparse.common import chartypes 50from simpleparse.dispatchprocessor import * 51 52c = {} 53 54declaration = r""" 55# sample for parsing integer and float numbers 56# including hexidecimal numbers in 0xFFF format 57sign := [-+]+ 58 59<l_digits> := digits 60<l_hexdigits> := hexdigits 61 62decimal_fraction := '.',int_unsigned? 63 64# float which is explicitly a float, cannot be an integer 65# because it includes a decimal point 66explicit_base := sign?, ((int_unsigned, decimal_fraction) / decimal_fraction / (int_unsigned,'.')) 67 68exponent := int 69exponent_loose := explicit_base/int 70 71float := explicit_base, ([eE],exponent)? 72float_floatexp := explicit_base, ([eE],exponent_loose)? 73 74hex := sign?, '0', [xX], hexdigits 75int_unsigned := l_digits 76int := sign?, l_digits 77binary_digits := [01]+ 78binary_number := sign?, binary_digits,('b'/'B') 79 80imaginary_number := (float/int), [jJ] 81 82##number := binary_number/hex/float/int 83number := hex/float/int 84number_full := binary_number/imaginary_number/hex/float/int 85""" 86 87_p = Parser( declaration ) 88for name in ["int","hex", "int_unsigned", "number", "float", "binary_number", "float_floatexp", "imaginary_number", "number_full"]: 89 c[ name ] = objectgenerator.LibraryElement( 90 generator = _p._generator, 91 production = name, 92 ) 93 94if __name__ == "__main__": 95 test() 96 97common.share( c ) 98 99def _toInt( s, base ): 100 try: 101 return int( s, base) 102 except TypeError: 103 return int( s, base) 104def _toLong( s, base ): 105 return int( s, base) 106 107class IntInterpreter(DispatchProcessor): 108 """Interpret an integer (or unsigned integer) string as an integer""" 109 def __call__( self, info, buffer): 110 (tag, left, right, children) = info 111 try: 112 return _toInt( buffer[left:right], 10) 113 except ValueError: 114 return _toLong( buffer[left:right], 10) 115class HexInterpreter(DispatchProcessor): 116 """Interpret a hexidecimal integer string as an integer value""" 117 def __call__( self, info, buffer): 118 (tag, left, right, children) = info 119 try: 120 return _toInt( buffer[left:right], 16) 121 except ValueError: 122 return _toLong( buffer[left:right], 16) 123 124class FloatFloatExpInterpreter(DispatchProcessor): 125 """Interpret a float string as an integer value 126 Note: we're allowing float exponentiation, which 127 gives you a nice way to write 2e.5 128 """ 129 def __call__( self, info, buffer): 130 (tag, left, right, children) = info 131 tag, l, r, _ = children[0] 132 base = float( buffer[l:r] ) 133 if len(children) > 1: 134 # figure out the exponent... 135 exp = children[1] 136 exp = buffer[ exp[1]:exp[2]] 137## import pdb 138## pdb.set_trace() 139 exp = float( exp ) 140 141 base = base * (10** exp) 142 return base 143class FloatInterpreter(DispatchProcessor): 144 """Interpret a standard float value as a float""" 145 def __call__( self, info, buffer): 146 (tag, left, right, children) = info 147 return float( buffer[left:right]) 148 149import sys 150if hasattr( sys,'version_info') and sys.version_info[:2] > (2,0): 151 class BinaryInterpreter(DispatchProcessor): 152 def __call__( self, info, buffer): 153 """Interpret a bitfield set as an integer""" 154 (tag, left, right, children) = info 155 return _toInt( buffer[left:right-1], 2) 156else: 157 class BinaryInterpreter(DispatchProcessor): 158 def __call__( self, info, buffer): 159 """Interpret a bitfield set as an integer, not sure this algo 160 is correct, will see I suppose""" 161 (tag, left, right, children) = info 162 sign = 1 163 if len(children) > 2: 164 s = children[0] 165 for schar in buffer[s[1]:s[2]]: 166 if schar == '-': 167 sign = sign * -1 168 bits = buffer[children[1][1]:children[1][2]] 169 else: 170 bits = buffer[children[0][1]:children[0][2]] 171 value = 0 172 for bit in bits: 173 value = (value << 1) 174 if bit == '1': 175 value = value + 1 176 return value 177 178class ImaginaryInterpreter( DispatchProcessor ): 179 map = { 180 "float":FloatInterpreter(), 181 "int":IntInterpreter() 182 } 183 def __call__( self, info, buffer): 184 """Interpret a bitfield set as an integer, not sure this algo 185 is correct, will see I suppose""" 186 (tag, left, right, children) = info 187 base = children[0] 188 base = self.mapSet[base[0]](base, buffer) 189 return base * 1j 190 191