| 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 11 matching lines...) Expand all Loading... |
| 45 bit_expr10 ::= int | id | bit_check | bit_set | '(' bit_expr ')' | call | 45 bit_expr10 ::= int | id | bit_check | bit_set | '(' bit_expr ')' | call |
| 46 bit_set ::= '{' (bit_expr (',' bit_expr)*)? '}' | 46 bit_set ::= '{' (bit_expr (',' bit_expr)*)? '}' |
| 47 bitpattern ::= word | negated_word | 47 bitpattern ::= word | negated_word |
| 48 call ::= word '(' (bit_expr (',' bit_expr)*)? ')' | 48 call ::= word '(' (bit_expr (',' bit_expr)*)? ')' |
| 49 citation ::= '(' word+ ')' | 49 citation ::= '(' word+ ')' |
| 50 column ::= id '(' int (':' int)? ')' | 50 column ::= id '(' int (':' int)? ')' |
| 51 classdef ::= 'class' word ':' word | 51 classdef ::= 'class' word ':' word |
| 52 decoder ::= id ('=>' id)? | 52 decoder ::= id ('=>' id)? |
| 53 decoder_action ::= '=" (decoder (fields? action_option* | | 53 decoder_action ::= '=" (decoder (fields? action_option* | |
| 54 action_options_deprecated arch?) | 54 action_options_deprecated arch?) |
| 55 | '*' int action_option*) | 55 | '*' (int | id) action_option*) |
| 56 decoder_method ::= '->' id | 56 decoder_method ::= '->' id |
| 57 default_row ::= 'else' ':' action | 57 default_row ::= 'else' ':' action |
| 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 | id) 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. |
| 79 rule_restrict = Name defining additional constraints (parse and safety) | 80 rule_restrict = Name defining additional constraints (parse and safety) |
| 80 for match. | 81 for match. |
| 81 """ | 82 """ |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 """Parses 'action_options*'.""" | 505 """Parses 'action_options*'.""" |
| 505 while True: | 506 while True: |
| 506 if self._is_action_option(): | 507 if self._is_action_option(): |
| 507 self._action_option(context) | 508 self._action_option(context) |
| 508 else: | 509 else: |
| 509 return | 510 return |
| 510 | 511 |
| 511 def _decoder_action(self, starred_actions): | 512 def _decoder_action(self, starred_actions): |
| 512 """decoder_action ::= '=" (decoder (fields? action_option* | | 513 """decoder_action ::= '=" (decoder (fields? action_option* | |
| 513 action_options_deprecated arch?) | 514 action_options_deprecated arch?) |
| 514 | '*' int action_option*) | 515 | '*' (int | id) action_option*) |
| 515 """ | 516 """ |
| 516 self._read_token('=') | 517 self._read_token('=') |
| 517 if self._next_token().kind == '*': | 518 if self._next_token().kind == '*': |
| 518 return self._decoder_action_extend(starred_actions) | 519 return self._decoder_action_extend(starred_actions) |
| 519 | 520 |
| 520 (baseline, actual) = self._decoder() | 521 (baseline, actual) = self._decoder() |
| 521 action = dgen_core.DecoderAction(baseline, actual) | 522 action = dgen_core.DecoderAction(baseline, actual) |
| 522 context = action.st | 523 context = action.st |
| 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 | id) action_option* |
| 543 | 544 |
| 544 Helper function to _decoder_action.""" | 545 Helper function to _decoder_action.""" |
| 545 self._read_token('*') | 546 self._read_token('*') |
| 546 index = self._int() | 547 if self._is_int(): |
| 548 index = self._int() |
| 549 else: |
| 550 index = self._id() |
| 547 indexed_action = starred_actions.get(index) | 551 indexed_action = starred_actions.get(index) |
| 548 if not indexed_action: | 552 if not indexed_action: |
| 549 self._unexpected("Can't find decoder action *%s" % index) | 553 self._unexpected("Can't find decoder action *%s" % index) |
| 550 | 554 |
| 551 # Create an initial copy, and define starred action as | 555 # Create an initial copy, and define starred action as |
| 552 # inheriting definition. | 556 # inheriting definition. |
| 553 action = dgen_core.DecoderAction(indexed_action.baseline, | 557 action = dgen_core.DecoderAction(indexed_action.baseline, |
| 554 indexed_action.actual) | 558 indexed_action.actual) |
| 555 action.st.inherits(indexed_action.st) | 559 action.st.inherits(indexed_action.st) |
| 556 | 560 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 Passed in sequence of patterns and action from last row, | 708 Passed in sequence of patterns and action from last row, |
| 705 and returns list of patterns and action from this row. | 709 and returns list of patterns and action from this row. |
| 706 """ | 710 """ |
| 707 self._read_token('|') | 711 self._read_token('|') |
| 708 if self._next_token().kind == 'else': | 712 if self._next_token().kind == 'else': |
| 709 return self._default_row(table, starred_actions, last_action) | 713 return self._default_row(table, starred_actions, last_action) |
| 710 else: | 714 else: |
| 711 return self._pat_row(table, starred_actions, last_patterns, last_action) | 715 return self._pat_row(table, starred_actions, last_patterns, last_action) |
| 712 | 716 |
| 713 def _rule_restrict(self, context): | 717 def _rule_restrict(self, context): |
| 718 """ rule_restrict ::= ('&' bit_expr)* ('&' 'other' ':' id)? """ |
| 719 |
| 720 restrictions = context.find('constraints') |
| 721 if not restrictions: |
| 722 context.define('constraints', dgen_core.RuleRestrictions()) |
| 723 while self._next_token().kind == '&': |
| 724 self._read_token('&') |
| 725 if self._next_token().kind == 'other': |
| 726 self._read_token('other') |
| 727 self._read_token(':') |
| 728 restrictions.safety = self._id() |
| 729 return |
| 730 else: |
| 731 restrictions.add(self._bit_expr(context)) |
| 732 |
| 733 def _rule_restrict_deprecated(self, context): |
| 714 """ rule_restrict ::= ('&' bitpattern)* ('&' 'other' ':' id)? """ | 734 """ rule_restrict ::= ('&' bitpattern)* ('&' 'other' ':' id)? """ |
| 715 | 735 |
| 716 restrictions = context.find('constraints') | 736 restrictions = context.find('constraints') |
| 717 if not restrictions: | 737 if not restrictions: |
| 718 context.define('constraints', dgen_core.RuleRestrictions()) | 738 context.define('constraints', dgen_core.RuleRestrictions()) |
| 719 while self._next_token().kind == '&': | 739 while self._next_token().kind == '&': |
| 720 self._read_token('&') | 740 self._read_token('&') |
| 721 if self._next_token().kind == 'other': | 741 if self._next_token().kind == 'other': |
| 722 self._read_token('other') | 742 self._read_token('other') |
| 723 self._read_token(':') | 743 self._read_token(':') |
| 724 restrictions.safety = self._id() | 744 restrictions.safety = self._id() |
| 725 return | 745 return |
| 726 else: | 746 else: |
| 727 restrictions.add(self._bitpattern32()) | 747 restrictions.add( |
| 748 dgen_core.BitPattern.parse(self._bitpattern32(), |
| 749 dgen_core.BitField('constraint', 31, 0))) |
| 728 | 750 |
| 729 def _safety_check(self, context): | 751 def _safety_check(self, context): |
| 730 """safety_check ::= id | bit_expr ('=>' id)? | 752 """safety_check ::= id | bit_expr ('=>' id)? |
| 731 | 753 |
| 732 Parses safety check and returns it. | 754 Parses safety check and returns it. |
| 733 """ | 755 """ |
| 734 if self._is_name_semicolon(): | 756 if self._is_name_semicolon(): |
| 735 # This is a special case where we are picking up a instruction | 757 # This is a special case where we are picking up a instruction |
| 736 # tester suffix. | 758 # tester suffix. |
| 737 check = self._id() | 759 check = self._id() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 749 starred_actions = self._table_actions() | 771 starred_actions = self._table_actions() |
| 750 self._header(table) | 772 self._header(table) |
| 751 (pattern, action) = self._row(table, starred_actions) | 773 (pattern, action) = self._row(table, starred_actions) |
| 752 while not self._next_token().kind == '+': | 774 while not self._next_token().kind == '+': |
| 753 (pattern, action) = self._row(table, starred_actions, pattern, action) | 775 (pattern, action) = self._row(table, starred_actions, pattern, action) |
| 754 if not decoder.add(table): | 776 if not decoder.add(table): |
| 755 self._unexpected('Multiple tables with name %s' % table.name) | 777 self._unexpected('Multiple tables with name %s' % table.name) |
| 756 self._footer() | 778 self._footer() |
| 757 | 779 |
| 758 def _table_actions(self): | 780 def _table_actions(self): |
| 759 """table_actions ::= ( ('*' int decoder fields? action_options*)+ | 781 """table_actions ::= ( ('*' (int | id) decoder fields? action_options*)+ |
| 760 footer)?""" | 782 footer)?""" |
| 761 starred_actions = {} | 783 starred_actions = {} |
| 762 if self._next_token().kind != '*': return starred_actions | 784 if self._next_token().kind != '*': return starred_actions |
| 763 while self._next_token().kind == '*': | 785 while self._next_token().kind == '*': |
| 764 self._read_token('*') | 786 self._read_token('*') |
| 765 index = self._int() | 787 if self._is_int(): |
| 788 index = self._int() |
| 789 else: |
| 790 index = self._id() |
| 766 | 791 |
| 767 (baseline, actual) = self._decoder() | 792 (baseline, actual) = self._decoder() |
| 768 action = dgen_core.DecoderAction(baseline, actual) | 793 action = dgen_core.DecoderAction(baseline, actual) |
| 769 context = action.st | 794 context = action.st |
| 770 if self._next_token().kind == '{': | 795 if self._next_token().kind == '{': |
| 771 fields = self._fields(context) | 796 fields = self._fields(context) |
| 772 if not context.define('fields', fields, False): | 797 if not context.define('fields', fields, False): |
| 773 raise Exception('multiple field definitions.') | 798 raise Exception('multiple field definitions.') |
| 774 self._decoder_action_options(context) | 799 self._decoder_action_options(context) |
| 775 elif self._is_action_option(): | 800 elif self._is_action_option(): |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 return re.sub(r'#.*', '', line).strip() | 1025 return re.sub(r'#.*', '', line).strip() |
| 1001 else: | 1026 else: |
| 1002 self._reached_eof = True | 1027 self._reached_eof = True |
| 1003 return '' | 1028 return '' |
| 1004 | 1029 |
| 1005 #-------- Error reporting ------ | 1030 #-------- Error reporting ------ |
| 1006 | 1031 |
| 1007 def _unexpected(self, context='Unexpected line in input'): | 1032 def _unexpected(self, context='Unexpected line in input'): |
| 1008 """"Reports that we didn't find the expected context. """ | 1033 """"Reports that we didn't find the expected context. """ |
| 1009 raise Exception('Line %d: %s' % (self._line_no, context)) | 1034 raise Exception('Line %d: %s' % (self._line_no, context)) |
| OLD | NEW |