Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright 2012 The Native Client Authors. All rights reserved. | 3 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # be found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 # | 6 # |
| 7 | 7 |
| 8 """ | 8 """ |
| 9 A simple recursive-descent parser for the table file format. | 9 A simple recursive-descent parser for the table file format. |
| 10 | 10 |
| 11 The grammar implemented here is roughly (taking some liberties with whitespace | 11 The grammar implemented here is roughly (taking some liberties with whitespace |
| 12 and comment parsing): | 12 and comment parsing): |
| 13 | 13 |
| 14 table_file ::= ( BLANK_LINE | table_def ) end_of_file ; | 14 table_file ::= ( BLANK_LINE | table_def ) end_of_file ; |
| 15 table_def ::= "--" IDENT CITATION NL | 15 table_def ::= "--" IDENT CITATION NL |
| 16 table_header | 16 table_header |
| 17 ( table_row )+ ; | 17 ( table_row )+ ; |
| 18 table_header ::= ( IDENT "(" BITRANGE ")" )+ ; | 18 table_header ::= ( IDENT "(" BITRANGE ")" )+ ; |
| 19 table_row ::= ( PATTERN )+ ACTION ; | 19 table_row ::= ( PATTERN )+ ACTION ; |
| 20 | 20 |
| 21 IDENT = /[a-z0-9_]+/ | 21 IDENT = /[a-z0-9_]+/ |
| 22 CITATION = "(" /[^)]+/ ")" | 22 CITATION = "(" /[^)]+/ ")" |
| 23 BITRANGE = /[0-9]+/ (":" /[0-9]+/)? | 23 BITRANGE = /[0-9]+/ (":" /[0-9]+/)? |
| 24 PATTERN = /[10x_]+/ | 24 PATTERN = /[10x_]+/ |
| 25 ACTION = ( "=" IDENT | "->" IDENT ) ( "(" IDENT ")" )? | 25 ACTION = ( "=" IDENT | "->" IDENT ) ( "(" IDENT ")" )? IDENT* |
| 26 NL = a newline | 26 NL = a newline |
| 27 BLANK_LINE = what you might expect it to be | 27 BLANK_LINE = what you might expect it to be |
| 28 | |
| 29 If ACTION has more than one IDENT, the interpretation is as follows: | |
| 30 IDENT[0] = action (plus optional architecture) to apply. | |
| 31 IDENT[1] = Arm rule action corresponds to. | |
| 32 IDENT[2] = Bit pattern of rule. | |
| 33 IDENT[3] = Name defining additional constraints for match. | |
| 28 """ | 34 """ |
| 29 | 35 |
| 30 import re | 36 import re |
| 31 import dgen_core | 37 import dgen_core |
| 32 | 38 |
| 33 # These globals track the parser state. | 39 # These globals track the parser state. |
| 34 _in = None | 40 _in = None |
| 35 _line_no = None | 41 _line_no = None |
| 36 _tables = None | 42 _tables = None |
| 37 _line = None | 43 _line = None |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 | 92 |
| 87 hi_bit = int(m.group(2)) | 93 hi_bit = int(m.group(2)) |
| 88 if m.group(4): | 94 if m.group(4): |
| 89 lo_bit = int(m.group(4)) | 95 lo_bit = int(m.group(4)) |
| 90 else: | 96 else: |
| 91 lo_bit = hi_bit | 97 lo_bit = hi_bit |
| 92 table.add_column(m.group(1), hi_bit, lo_bit) | 98 table.add_column(m.group(1), hi_bit, lo_bit) |
| 93 next_line() | 99 next_line() |
| 94 | 100 |
| 95 | 101 |
| 96 def table_row(table): | 102 def table_row(table): |
|
robertm
2012/04/11 01:28:43
can you add a docstring and maybe a sample line or
Karl
2012/04/16 23:18:10
Did this in general. This file has gone through ma
| |
| 97 global _last_row | 103 global _last_row |
| 98 | 104 |
| 99 row = _line.split() | 105 row = _line.split() |
| 100 for i in range(0, len(row)): | 106 for i in range(0, len(row)): |
| 101 if row[i] == '"': row[i] = _last_row[i] | 107 if row[i] == '"': row[i] = _last_row[i] |
| 102 _last_row = row | 108 _last_row = row |
| 103 | 109 |
| 104 action = row[-1] | 110 # Pull out action and set of following symbols, and |
| 105 patterns = row[:-1] | 111 # remerge them into a single string operation (separated |
| 106 table.add_row(patterns, action) | 112 # by a single space). |
| 113 action_index = 0 | |
| 114 action_type = None | |
| 115 for w in row: | |
| 116 if w.startswith('='): | |
| 117 action_type = '=' | |
| 118 break; | |
| 119 elif w.startswith('->'): | |
| 120 action_type = '->' | |
| 121 break; | |
| 122 else: | |
| 123 action_index += 1 | |
| 124 | |
| 125 # verify we have a properly defined input. | |
| 126 if action_index == len(row): unexpected() | |
| 127 | |
| 128 action = row[action_index:] | |
| 129 patterns = row[:action_index] | |
| 130 | |
| 131 # verify we don't have too many fields for an action. | |
| 132 if len(action) > 4: unexpected() | |
| 133 if action_type == '->' and len(action) != 1: unexpected() | |
| 134 | |
| 135 # Recompose the action into a single token and add. | |
| 136 table.add_row(patterns, ' '.join(action)) | |
| 107 next_line() | 137 next_line() |
| 108 | 138 |
| 109 | 139 |
| 110 def end_of_file(): | 140 def end_of_file(): |
| 111 return _line is None | 141 return _line is None |
| 112 | 142 |
| 113 | 143 |
| 114 def next_line(): | 144 def next_line(): |
| 115 "Reads the next non-comment line" | 145 """Reads the next non-comment line""" |
| 116 global _line_no, _line | 146 global _line_no, _line |
| 117 | 147 |
| 118 _line_no += 1 | 148 _line_no += 1 |
| 119 _line = _in.readline() | 149 _line = _in.readline() |
| 120 while True: | 150 while True: |
| 121 if _line: | 151 if _line: |
| 122 if _line[0] == '#': | 152 if _line.startswith("#"): |
| 123 # skip comment line and continue search. | 153 # skip comment line and continue search. |
| 124 _line_no += 1 | 154 _line_no += 1 |
| 125 _line = _in.readline() | 155 _line = _in.readline() |
| 126 continue | 156 continue |
| 127 _line = re.sub(r'#.*', '', _line).strip() | 157 _line = re.sub(r'#.*', '', _line).strip() |
|
robertm
2012/04/11 01:28:43
does this line sill make sense, since you are alre
Karl
2012/04/16 23:18:10
Since the parser is now free-form, it is no longer
| |
| 158 if _line.endswith('\\'): | |
| 159 # continuation. continue on next line. | |
| 160 _line_no += 1 | |
| 161 _line = _line[:-1] + ' ' + _in.readline() | |
| 162 continue | |
| 128 else: | 163 else: |
| 129 _line = None | 164 _line = None |
| 130 # if reached, found line. | 165 # if reached, found line. |
| 131 return | 166 return |
| 132 | 167 |
| 168 | |
| 133 def unexpected(): | 169 def unexpected(): |
| 134 raise Exception('Line %d: Unexpected line in input: %s' % (_line_no, _line)) | 170 raise Exception('Line %d: Unexpected line in input: %s' % (_line_no, _line)) |
| OLD | NEW |