| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright (c) 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 be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # 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 ::= classdef* table+ eof ; | 14 table_file ::= classdef* table+ eof ; |
| 15 | 15 |
| 16 action ::= decoder_action | decoder_method | '"' | 16 action ::= decoder_action | decoder_method | '"' |
| 17 action_arch ::= 'arch' ':=' word | 17 action_arch ::= 'arch' ':=' word |
| 18 action_option ::= (action_rule | | 18 action_option ::= (action_rule | |
| 19 action_pattern | | 19 action_pattern | |
| 20 action_safety | | 20 action_safety | |
| 21 action_arch | | 21 action_arch | |
| 22 action_other) ';' | 22 action_other) ';' |
| 23 action_options_deprecated ::= (id (word (rule_restrict id?)?)?)? | 23 action_options_deprecated ::= (id (word (rule_restrict_deprecated id?)?)?)? |
| 24 action_other ::= word ':=' bit_expr | 24 action_other ::= word ':=' bit_expr |
| 25 action_pattern ::= 'pattern' ':=' word rule_restrict? | 25 action_pattern ::= 'pattern' ':=' word rule_restrict? |
| 26 action_safety ::= 'safety' ':=' safety_check ('&' safety_check)* | 26 action_safety ::= 'safety' ':=' safety_check ('&' safety_check)* |
| 27 action_rule ::= 'rule' ':=' id | 27 action_rule ::= 'rule' ':=' id |
| 28 arch ::= '(' word+ ')' | 28 arch ::= '(' word+ ')' |
| 29 bit_check ::= column '=' bitpattern | 29 bit_check ::= column '=' bitpattern |
| 30 bit_expr ::= bit_expr1 ('if' bit_expr 'else' bit_expr)? # conditional | 30 bit_expr ::= bit_expr1 ('if' bit_expr 'else' bit_expr)? # conditional |
| 31 bit_expr1 ::= bit_expr2 (('&' bit_expr2)* | ('|' bit_expr2)*)? | 31 bit_expr1 ::= bit_expr2 (('&' bit_expr2)* | ('|' bit_expr2)*)? |
| 32 bit_expr2 ::= bit_expr3 | 'not' bit_expr2 | 32 bit_expr2 ::= bit_expr3 | 'not' bit_expr2 |
| 33 bit_expr3 ::= bit_expr4 ('in' 'bitset'? bit_set)? | 33 bit_expr3 ::= bit_expr4 ('in' 'bitset'? bit_set)? |
| (...skipping 24 matching lines...) Expand all Loading... |
| 58 fields ::= '{' column (',' column)* '}' | 58 fields ::= '{' column (',' column)* '}' |
| 59 footer ::= '+' '-' '-' | 59 footer ::= '+' '-' '-' |
| 60 header ::= "|" column+ | 60 header ::= "|" column+ |
| 61 int ::= word (where word is a sequence of digits) | 61 int ::= word (where word is a sequence of digits) |
| 62 id ::= word (where word is sequence of letters, digits and _) | 62 id ::= word (where word is sequence of letters, digits and _) |
| 63 negated_word ::= '~' word | 63 negated_word ::= '~' word |
| 64 parenthesized_exp ::= '(' (word | punctuation)+ ')' | 64 parenthesized_exp ::= '(' (word | punctuation)+ ')' |
| 65 pat_row ::= pattern+ action | 65 pat_row ::= pattern+ action |
| 66 pattern ::= bitpattern | '-' | '"' | 66 pattern ::= bitpattern | '-' | '"' |
| 67 row ::= '|' (pat_row | default_row) | 67 row ::= '|' (pat_row | default_row) |
| 68 rule_restrict ::= ('&' bitpattern)* ('&' 'other' ':' id)? | 68 rule_restrict ::= ('&' bit_expr)* ('&' 'other' ':' id)? |
| 69 rule_restrict_deprecated ::= ('&' bitpattern)* ('&' 'other' ':' id)? |
| 69 safety_check ::= id | bit_expr1 ('=>' id)? # note: single id only at end. | 70 safety_check ::= id | bit_expr1 ('=>' id)? # note: single id only at end. |
| 70 table ::= table_desc table_actions header row+ footer | 71 table ::= table_desc table_actions header row+ footer |
| 71 table_actions ::= ( ('*' int decoder fields? action_options*)+ footer)? | 72 table_actions ::= ( ('*' int decoder fields? action_options*)+ footer)? |
| 72 table_desc ::= '+' '-' '-' id citation? | 73 table_desc ::= '+' '-' '-' id citation? |
| 73 | 74 |
| 74 Note that action_options_deprecated is deprecated, and one should generate | 75 Note that action_options_deprecated is deprecated, and one should generate |
| 75 a sequence of action_option's. For action_options_depcrected, the interpretation | 76 a sequence of action_option's. For action_options_depcrected, the interpretation |
| 76 is as follows: | 77 is as follows: |
| 77 id[1] = Arm rule action corresponds to. | 78 id[1] = Arm rule action corresponds to. |
| 78 word = Bit pattern of rule. | 79 word = Bit pattern of rule. |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 if self._next_token().kind == '{': | 524 if self._next_token().kind == '{': |
| 524 fields = self._fields(context) | 525 fields = self._fields(context) |
| 525 if not context.define('fields', fields, False): | 526 if not context.define('fields', fields, False): |
| 526 raise Exception('multiple field definitions.') | 527 raise Exception('multiple field definitions.') |
| 527 self._decoder_action_options(context) | 528 self._decoder_action_options(context) |
| 528 elif self._is_action_option(): | 529 elif self._is_action_option(): |
| 529 self._decoder_action_options(context) | 530 self._decoder_action_options(context) |
| 530 else: | 531 else: |
| 531 context.define('rule', self._read_id_or_none(True)) | 532 context.define('rule', self._read_id_or_none(True)) |
| 532 context.define('pattern', self._read_id_or_none(False)) | 533 context.define('pattern', self._read_id_or_none(False)) |
| 533 self._rule_restrict(context) | 534 self._rule_restrict_deprecated(context) |
| 534 other_restrictions = self._read_id_or_none(True) | 535 other_restrictions = self._read_id_or_none(True) |
| 535 if other_restrictions: | 536 if other_restrictions: |
| 536 context.define('safety', [other_restrictions]) | 537 context.define('safety', [other_restrictions]) |
| 537 if self._next_token().kind == '(': | 538 if self._next_token().kind == '(': |
| 538 context.define('arch', self._arch()) | 539 context.define('arch', self._arch()) |
| 539 return action | 540 return action |
| 540 | 541 |
| 541 def _decoder_action_extend(self, starred_actions): | 542 def _decoder_action_extend(self, starred_actions): |
| 542 """'*' int action_option* | 543 """'*' int action_option* |
| 543 | 544 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 Passed in sequence of patterns and action from last row, | 705 Passed in sequence of patterns and action from last row, |
| 705 and returns list of patterns and action from this row. | 706 and returns list of patterns and action from this row. |
| 706 """ | 707 """ |
| 707 self._read_token('|') | 708 self._read_token('|') |
| 708 if self._next_token().kind == 'else': | 709 if self._next_token().kind == 'else': |
| 709 return self._default_row(table, starred_actions, last_action) | 710 return self._default_row(table, starred_actions, last_action) |
| 710 else: | 711 else: |
| 711 return self._pat_row(table, starred_actions, last_patterns, last_action) | 712 return self._pat_row(table, starred_actions, last_patterns, last_action) |
| 712 | 713 |
| 713 def _rule_restrict(self, context): | 714 def _rule_restrict(self, context): |
| 715 """ rule_restrict ::= ('&' bit_expr)* ('&' 'other' ':' id)? """ |
| 716 |
| 717 restrictions = context.find('constraints') |
| 718 if not restrictions: |
| 719 context.define('constraints', dgen_core.RuleRestrictions()) |
| 720 while self._next_token().kind == '&': |
| 721 self._read_token('&') |
| 722 if self._next_token().kind == 'other': |
| 723 self._read_token('other') |
| 724 self._read_token(':') |
| 725 restrictions.safety = self._id() |
| 726 return |
| 727 else: |
| 728 restrictions.add(self._bit_expr(context)) |
| 729 |
| 730 def _rule_restrict_deprecated(self, context): |
| 714 """ rule_restrict ::= ('&' bitpattern)* ('&' 'other' ':' id)? """ | 731 """ rule_restrict ::= ('&' bitpattern)* ('&' 'other' ':' id)? """ |
| 715 | 732 |
| 716 restrictions = context.find('constraints') | 733 restrictions = context.find('constraints') |
| 717 if not restrictions: | 734 if not restrictions: |
| 718 context.define('constraints', dgen_core.RuleRestrictions()) | 735 context.define('constraints', dgen_core.RuleRestrictions()) |
| 719 while self._next_token().kind == '&': | 736 while self._next_token().kind == '&': |
| 720 self._read_token('&') | 737 self._read_token('&') |
| 721 if self._next_token().kind == 'other': | 738 if self._next_token().kind == 'other': |
| 722 self._read_token('other') | 739 self._read_token('other') |
| 723 self._read_token(':') | 740 self._read_token(':') |
| 724 restrictions.safety = self._id() | 741 restrictions.safety = self._id() |
| 725 return | 742 return |
| 726 else: | 743 else: |
| 727 restrictions.add(self._bitpattern32()) | 744 restrictions.add( |
| 745 dgen_core.BitPattern.parse(self._bitpattern32(), |
| 746 dgen_core.BitField('constraint', 31, 0))) |
| 728 | 747 |
| 729 def _safety_check(self, context): | 748 def _safety_check(self, context): |
| 730 """safety_check ::= id | bit_expr ('=>' id)? | 749 """safety_check ::= id | bit_expr ('=>' id)? |
| 731 | 750 |
| 732 Parses safety check and returns it. | 751 Parses safety check and returns it. |
| 733 """ | 752 """ |
| 734 if self._is_name_semicolon(): | 753 if self._is_name_semicolon(): |
| 735 # This is a special case where we are picking up a instruction | 754 # This is a special case where we are picking up a instruction |
| 736 # tester suffix. | 755 # tester suffix. |
| 737 check = self._id() | 756 check = self._id() |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 return re.sub(r'#.*', '', line).strip() | 1019 return re.sub(r'#.*', '', line).strip() |
| 1001 else: | 1020 else: |
| 1002 self._reached_eof = True | 1021 self._reached_eof = True |
| 1003 return '' | 1022 return '' |
| 1004 | 1023 |
| 1005 #-------- Error reporting ------ | 1024 #-------- Error reporting ------ |
| 1006 | 1025 |
| 1007 def _unexpected(self, context='Unexpected line in input'): | 1026 def _unexpected(self, context='Unexpected line in input'): |
| 1008 """"Reports that we didn't find the expected context. """ | 1027 """"Reports that we didn't find the expected context. """ |
| 1009 raise Exception('Line %d: %s' % (self._line_no, context)) | 1028 raise Exception('Line %d: %s' % (self._line_no, context)) |
| OLD | NEW |