Version 1.0
Copyright © 2022 Lowell D. Thomas
Python APG
 … an ABNF Parser Generator
utilities.py
Go to the documentation of this file.
1 ''' @file apg_py/lib/utilities.py
2 @brief A few APG utility functions'''
3 import sys
4 import os
5 from pprint import pprint
6 
7 
8 def string_to_tuple(string):
9  '''Converts a string to a tuple of the
10  Unicode values of the string characters.
11  The APG parser requires a tuple of integers as input.
12  However, many problems are defined in terms of ASCII
13  or Unicode strings. This utility is a handy assist to get
14  a string into the proper format for parser input.
15  @param string The string to convert.
16  @return A tuple of the Unicode code points
17  for each of the strings's characters.
18  '''
19  lst = []
20  for c in string:
21  lst.append(ord(c))
22  return tuple(lst)
23 
24 
25 def tuple_to_string(input):
26  '''Converts a tuple of Unicode values to the equivalent string.
27  @param input The tuple of Unicode values to convert.
28  @return The converted string.
29  '''
30  string = ''
31  for u in input:
32  string += chr(u)
33  return string
34 
35 
36 def tuple_to_ascii(input, map=None):
37  '''Converts a tuple of Unicode values to an ASCII string.
38  Non-ASCII characters are displayed by hexadecimal value.
39  Used mainly for error reporting in the syntax phase.
40  @param input The tuple of Unicode values to convert.
41  @param map If map = [] a list of character display mappings is generated.
42  map[index] = [offset, length] where<br>
43  - index is the zero-based index of the character to map
44  - offset is the offset from the beginning of the ASCII display
45  to the first display gliph for the indexed character
46  - length is the number of ASCII characters used to display
47  the indexed character
48  @return The converted string.
49  '''
50  def hex(char):
51  if(char <= 0xff):
52  s = '\\x%02X' % char
53  elif(char <= 0xffff):
54  s = '\\x%04X' % char
55  elif(char <= 0xffffffff):
56  s = '\\x%08X' % char
57  else:
58  s = '\\x%X' % char
59  return s
60 
61  ascii = ''
62  has_map = False
63  if(map is not None):
64  has_map = True
65  offset = 0
66  length = 0
67  for u in input:
68  if(u == 9):
69  ascii += '\\t'
70  elif(u == 10):
71  ascii += '\\n'
72  elif(u == 13):
73  ascii += '\\r'
74  elif(u < 32 or u > 127):
75  ascii += hex(u)
76  else:
77  ascii += chr(u)
78  if(has_map):
79  length = len(ascii) - offset
80  map.append(length)
81  offset += length
82  return ascii
83 
84 
85 def tuple_to_ascii_underline(map, index):
86  '''Uses the (optional) map generated by @ref tuple_to_ascii()
87  to generate a mapping of the display characters to the actual
88  tuple (integer) characters.
89  Used mainly for error reporting in the syntax phase.
90  @param map A list of [offset, length] lists, one for each tuple
91  character that indicates the offset into the ASCII display.
92  and the length of the display of that specific character.
93  @param index The index of the underlying tuple character to accent.
94  @returns A string to underline the original with caret(s) to mark
95  the accented character.
96  '''
97  underline = ''
98  count = 0
99  has_caret = False
100  for length in map:
101  if(count is index):
102  underline += '^' * length
103  has_caret = True
104  else:
105  underline += '-' * length
106  count += 1
107  if(has_caret is False):
108  underline += '^'
109  return underline
110 
111 
112 def pprint_to_string(obj, temp):
113  '''Pretty prints an object to a temporary file,
114  then reads the string back and returns it.
115  @param obj The object to pretty print.
116  @param temp The file name to use to save the printed string.
117  It is deleted after use.
118  @returns The pretty printed string or the exception on file error.
119  - result['string'] is the displayed object on success
120  - result['error'] is the exception raised on failure.
121  '''
122  stdout_save = sys.stdout
123  result = {'string': '', 'error': None}
124  try:
125  fn = open(temp, 'w')
126  sys.stdout = fn
127  pprint(obj, sort_dicts=False)
128  sys.stdout = stdout_save
129  fn.close()
130  fn = open(temp, 'r')
131  result['string'] = fn.read()
132  fn.close()
133  os.remove(temp)
134  except Exception as e:
135  result['error'] = e
136  if(sys.stdout is not stdout_save):
137  # should not happen
138  # but just in case make sure we restore sys.sdtout
139  sys.stdout = stdout_save
140  return result
def tuple_to_string(input)
Converts a tuple of Unicode values to the equivalent string.
Definition: utilities.py:25
def tuple_to_ascii(input, map=None)
Converts a tuple of Unicode values to an ASCII string.
Definition: utilities.py:36
def pprint_to_string(obj, temp)
Pretty prints an object to a temporary file, then reads the string back and returns it.
Definition: utilities.py:112
def tuple_to_ascii_underline(map, index)
Uses the (optional) map generated by tuple_to_ascii() to generate a mapping of the display characters...
Definition: utilities.py:85
def string_to_tuple(string)
Converts a string to a tuple of the Unicode values of the string characters.
Definition: utilities.py:8
Python APG, Version 1.0, is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.