My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones  
Changes to /src/lepl/rxpy/alphabet/bytes.py
263822c3252c vs. 1fb01bf01581 Compare: vs.  Format:
Revision 1fb01bf01581
Go to: 
Project members, sign in to write a code review
/src/lepl/rxpy/alphabet/bytes.py   263822c3252c /src/lepl/rxpy/alphabet/bytes.py   1fb01bf01581
1 #LICENCE 1 #LICENCE
2 2
3 ''' 3 '''
4 Logic related to ASCII input. 4 Logic related to ASCII input.
5 ''' 5 '''
6 6
7 from array import array 7 from array import array
8 from string import digits, ascii_letters 8 from string import digits, ascii_letters
9 9
10 from lepl.rxpy.alphabet.base import BaseAlphabet 10 from lepl.rxpy.alphabet.base import BaseAlphabet
11 from lepl.rxpy.parser.support import ParserState 11 from lepl.rxpy.parser.support import ParserState
12 from lepl.rxpy.support import RxpyError 12 from lepl.rxpy.support import RxpyError
13 from lepl.support.lib import fmt 13 from lepl.support.lib import fmt
14 14
15 15
16 ASCII_WORD = set(ascii_letters + digits + '_') 16 ASCII_WORD = set(ascii_letters + digits + '_')
17 17
18 18
19 class Bytes(BaseAlphabet): 19 class Bytes(BaseAlphabet):
20 ''' 20 '''
21 Define character sets etc for byte-strings. 21 Define character sets etc for byte-strings.
22 22
23 See base class for full documentation. 23 See base class for full documentation.
24 ''' 24 '''
25 25
26 def __init__(self): 26 def __init__(self):
27 super(Bytes, self).__init__(0, 127, b'\\') 27 super(Bytes, self).__init__(0, 127, b'\\')
28 28
29 def code_to_letter(self, code): 29 def code_to_letter(self, code):
30 if code < 0 or code > 255: 30 if code < 0 or code > 255:
31 raise ValueError(fmt('Byte out of range: {}', code)) 31 raise ValueError(fmt('Byte out of range: {}', code))
32 return bytes([code]) 32 return bytes([code])
33 33
34 def letter_to_code(self, char): 34 def letter_to_code(self, char):
35 if len(char) != 1 or char[0] < 0 or char[0] > 255: 35 if len(char) != 1 or char[0] < 0 or char[0] > 255:
36 raise ValueError(fmt('Byte out of range: {}', char)) 36 raise ValueError(fmt('Byte out of range: {}', char))
37 return char[0] 37 return char[0]
38 38
39 def validate_expression(self, expression, flags): 39 def validate_expression(self, expression, flags):
40 if not isinstance(expression, bytes): 40 if not isinstance(expression, bytes):
41 raise TypeError('Expression for bytes alphabet must be of type bytes') 41 raise TypeError('Expression for bytes alphabet must be of type bytes')
42 if flags & ParserState.UNICODE: 42 if flags & ParserState.UNICODE:
43 raise ValueError('Cannot use UNICODE with bytes') 43 raise ValueError('Cannot use UNICODE with bytes')
44 44
45 def validate_input(self, input, flags): 45 def validate_input(self, input, flags):
46 if not isinstance(input, bytes) and not isinstance(input, array): 46 if not isinstance(input, bytes) and not isinstance(input, array):
47 raise TypeError('Input for bytes alphabet must be bytes or array') 47 raise TypeError('Input for bytes alphabet must be bytes or array')
48 48
49 def expression_to_letter(self, char): 49 def expression_to_letter(self, char):
50 return bytes([char]) 50 return bytes([char])
51 51
52 def expression_to_str(self, char): 52 def expression_to_str(self, char):
53 return chr(char) if char is not None else None 53 return chr(char) if char is not None else None
54 54
55 def letter_to_str(self, letter): 55 def letter_to_str(self, letter):
56 return chr(letter[0]) 56 return chr(letter[0])
57 57
58 def join(self, *strings): 58 def join(self, *strings):
59 ''' 59 '''
60 Construct a word in the alphabet, given a list of words and/or 60 Construct a word in the alphabet, given a list of words and/or
61 characters. 61 characters.
62 ''' 62 '''
63 return b''.join(strings) 63 return b''.join(strings)
64 64
65 def digit(self, char, flags): 65 def digit(self, char, flags):
66 '''Test whether the character is a digit or not.''' 66 '''Test whether the character is a digit or not.'''
67 if flags & ParserState.UNICODE: 67 if flags & ParserState.UNICODE:
68 raise ValueError('Cannot use UNICODE flag with bytes') 68 raise ValueError('Cannot use UNICODE flag with bytes')
69 return char and char in b'0123456789' 69 return char and char in b'0123456789'
70 70
71 def space(self, char, flags): 71 def space(self, char, flags):
72 '''Test whether the character is a whitespace or not.''' 72 '''Test whether the character is a whitespace or not.'''
73 if flags & ParserState.UNICODE: 73 if flags & ParserState.UNICODE:
74 raise ValueError('Cannot use UNICODE flag with bytes') 74 raise ValueError('Cannot use UNICODE flag with bytes')
75 return char and char in b' \t\n\r\f\v' 75 return char and char in b' \t\n\r\f\v'
76 76
77 def word(self, char, flags): 77 def word(self, char, flags):
78 '''Test whether the character is a word character or not.''' 78 '''Test whether the character is a word character or not.'''
79 if flags & ParserState.UNICODE: 79 if flags & ParserState.UNICODE:
80 raise ValueError('Cannot use UNICODE flag with bytes') 80 raise ValueError('Cannot use UNICODE flag with bytes')
81 return char and chr(char) in ASCII_WORD 81 return char and chr(char[0]) in ASCII_WORD
82 82
83 def expression_to_charset(self, char, flags): 83 def expression_to_charset(self, char, flags):
84 from lepl.rxpy.parser.support import ParserState 84 from lepl.rxpy.parser.support import ParserState
85 if flags & ParserState.UNICODE: 85 if flags & ParserState.UNICODE:
86 raise ValueError('Cannot use UNICODE flag with bytes') 86 raise ValueError('Cannot use UNICODE flag with bytes')
87 # restrict case conversion to 7bit values 87 # restrict case conversion to 7bit values
88 if flags & ParserState.IGNORE_CASE and char < 128: 88 if flags & ParserState.IGNORE_CASE and char < 128:
89 lo = chr(char).lower().encode('ascii') 89 lo = chr(char).lower().encode('ascii')
90 hi = chr(char).upper() 90 hi = chr(char).upper()
91 if lo != hi: 91 if lo != hi:
92 return True, (lo, hi) 92 return True, (lo, hi)
93 return False, self.expression_to_letter(char) 93 return False, self.expression_to_letter(char)
94 94
95 def unescape(self, code): 95 def unescape(self, code):
96 '''For compatibility with python.''' 96 '''For compatibility with python.'''
97 if code < 512: 97 if code < 512:
98 return self.code_to_letter(code % 256) 98 return self.code_to_letter(code % 256)
99 else: 99 else:
100 raise RxpyError('Unexpected character code for ASCII: ' + str(code)) 100 raise RxpyError('Unexpected character code for ASCII: ' + str(code))
Powered by Google Project Hosting