| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 | 3 |
| 4 /** | 4 /** |
| 5 * A simple recursive descent parser for CSS. | 5 * A simple recursive descent parser for CSS. |
| 6 */ | 6 */ |
| 7 class Parser { | 7 class Parser { |
| 8 Tokenizer tokenizer; | 8 Tokenizer tokenizer; |
| 9 | 9 |
| 10 var _fs; // If non-null filesystem to read files. | 10 var _fs; // If non-null filesystem to read files. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 void _eatSemicolon() { | 98 void _eatSemicolon() { |
| 99 _eat(TokenKind.SEMICOLON); | 99 _eat(TokenKind.SEMICOLON); |
| 100 } | 100 } |
| 101 | 101 |
| 102 void _errorExpected(String expected) { | 102 void _errorExpected(String expected) { |
| 103 var tok = _next(); | 103 var tok = _next(); |
| 104 var message; | 104 var message; |
| 105 try { | 105 try { |
| 106 message = 'expected $expected, but found $tok'; | 106 message = 'expected $expected, but found $tok'; |
| 107 } catch (var e) { | 107 } catch (final e) { |
| 108 message = 'parsing error expected $expected'; | 108 message = 'parsing error expected $expected'; |
| 109 } | 109 } |
| 110 _error(message, tok.span); | 110 _error(message, tok.span); |
| 111 } | 111 } |
| 112 | 112 |
| 113 void _error(String message, [lang.SourceSpan location=null]) { | 113 void _error(String message, [lang.SourceSpan location=null]) { |
| 114 if (location === null) { | 114 if (location === null) { |
| 115 location = _peekToken.span; | 115 location = _peekToken.span; |
| 116 } | 116 } |
| 117 | 117 |
| 118 lang.world.fatal(message, location); // syntax errors are fatal for now | 118 lang.world.fatal(message, location); // syntax errors are fatal for now |
| 119 } | 119 } |
| 120 | 120 |
| 121 void _warning(String message, [lang.SourceSpan location=null]) { |
| 122 if (location === null) { |
| 123 location = _peekToken.span; |
| 124 } |
| 125 |
| 126 lang.world.warning(message, location); |
| 127 } |
| 128 |
| 121 lang.SourceSpan _makeSpan(int start) { | 129 lang.SourceSpan _makeSpan(int start) { |
| 122 return new lang.SourceSpan(source, start, _previousToken.end); | 130 return new lang.SourceSpan(source, start, _previousToken.end); |
| 123 } | 131 } |
| 124 | 132 |
| 125 /////////////////////////////////////////////////////////////////// | 133 /////////////////////////////////////////////////////////////////// |
| 126 // Top level productions | 134 // Top level productions |
| 127 /////////////////////////////////////////////////////////////////// | 135 /////////////////////////////////////////////////////////////////// |
| 128 | 136 |
| 129 // Templates are @{selectors} single line nothing else. | 137 // Templates are @{selectors} single line nothing else. |
| 130 SelectorGroup parseTemplate() { | 138 SelectorGroup parseTemplate() { |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 _eat(TokenKind.RBRACK); | 764 _eat(TokenKind.RBRACK); |
| 757 | 765 |
| 758 return new ItemTerm(term.value, term.text, _makeSpan(start)); | 766 return new ItemTerm(term.value, term.text, _makeSpan(start)); |
| 759 case TokenKind.IDENTIFIER: | 767 case TokenKind.IDENTIFIER: |
| 760 var nameValue = identifier(); // Snarf up the ident we'll remap, maybe. | 768 var nameValue = identifier(); // Snarf up the ident we'll remap, maybe. |
| 761 | 769 |
| 762 if (_maybeEat(TokenKind.LPAREN)) { | 770 if (_maybeEat(TokenKind.LPAREN)) { |
| 763 // FUNCTION | 771 // FUNCTION |
| 764 return processFunction(nameValue); | 772 return processFunction(nameValue); |
| 765 } else { | 773 } else { |
| 774 // TODO(terry): Need to have a list of known identifiers today only |
| 775 // 'from' is special. |
| 776 if (nameValue.name == 'from') { |
| 777 return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start)); |
| 778 } |
| 779 |
| 766 // What kind of identifier is it? | 780 // What kind of identifier is it? |
| 767 int value; | 781 int value; |
| 768 try { | 782 try { |
| 769 // Named color? | 783 // Named color? |
| 770 value = TokenKind.matchColorName(nameValue.name); | 784 value = TokenKind.matchColorName(nameValue.name); |
| 771 | 785 |
| 772 // Yes, process the color as an RGB value. | 786 // Yes, process the color as an RGB value. |
| 773 String rgbColor = TokenKind.decimalToHex(value); | 787 String rgbColor = TokenKind.decimalToHex(value); |
| 774 int value; | 788 int value; |
| 775 try { | 789 try { |
| 776 value = parseHex(rgbColor); | 790 value = parseHex(rgbColor); |
| 777 } catch (HexNumberException hne) { | 791 } catch (HexNumberException hne) { |
| 778 _error('Bad hex number', _makeSpan(start)); | 792 _error('Bad hex number', _makeSpan(start)); |
| 779 } | 793 } |
| 780 return new HexColorTerm(value, rgbColor, _makeSpan(start)); | 794 return new HexColorTerm(value, rgbColor, _makeSpan(start)); |
| 781 } catch (var error) { | 795 } catch (final error) { |
| 782 if (error is NoColorMatchException) { | 796 if (error is NoColorMatchException) { |
| 783 // Other named things to match with validator? | 797 // TODO(terry): Other named things to match with validator? |
| 784 // TODO(terry): TBD | 798 _warning('Unknown property value ${error.name}', _makeSpan(start)); |
| 785 // _error('Unknown property value ${error.name}', _makeSpan(start)); | |
| 786 | |
| 787 value = nameValue.name; | |
| 788 print('Warning: unknown property value ${error.name}'); | |
| 789 return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start)); | 799 return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start)); |
| 790 | |
| 791 } | 800 } |
| 792 } | 801 } |
| 793 } | 802 } |
| 794 } | 803 } |
| 795 | 804 |
| 796 var term; | 805 var term; |
| 797 var unitType = this._peek(); | 806 var unitType = this._peek(); |
| 798 | 807 |
| 799 switch (unitType) { | 808 switch (unitType) { |
| 800 case TokenKind.UNIT_EM: | 809 case TokenKind.UNIT_EM: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 case TokenKind.SINGLE_QUOTE: | 865 case TokenKind.SINGLE_QUOTE: |
| 857 stopToken = TokenKind.SINGLE_QUOTE; | 866 stopToken = TokenKind.SINGLE_QUOTE; |
| 858 _next(); // Skip the SINGLE_QUOTE. | 867 _next(); // Skip the SINGLE_QUOTE. |
| 859 break; | 868 break; |
| 860 case TokenKind.DOUBLE_QUOTE: | 869 case TokenKind.DOUBLE_QUOTE: |
| 861 stopToken = TokenKind.DOUBLE_QUOTE; | 870 stopToken = TokenKind.DOUBLE_QUOTE; |
| 862 _next(); // Skip the DOUBLE_QUOTE. | 871 _next(); // Skip the DOUBLE_QUOTE. |
| 863 break; | 872 break; |
| 864 default: | 873 default: |
| 865 if (urlString) { | 874 if (urlString) { |
| 875 if (_peek() == TokenKind.LPAREN) { |
| 876 _next(); // Skip the LPAREN. |
| 877 } |
| 866 stopToken = TokenKind.RPAREN; | 878 stopToken = TokenKind.RPAREN; |
| 867 } else { | 879 } else { |
| 868 _error('unexpected string', _makeSpan(start)); | 880 _error('unexpected string', _makeSpan(start)); |
| 869 } | 881 } |
| 870 } | 882 } |
| 871 | 883 |
| 872 StringBuffer stringValue = new StringBuffer(); | 884 StringBuffer stringValue = new StringBuffer(); |
| 873 | 885 |
| 874 // Gobble up everything until we hit our stop token. | 886 // Gobble up everything until we hit our stop token. |
| 875 int runningStart = _peekToken.start; | 887 int runningStart = _peekToken.start; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 | 971 |
| 960 return result; | 972 return result; |
| 961 } | 973 } |
| 962 } | 974 } |
| 963 | 975 |
| 964 /** Not a hex number. */ | 976 /** Not a hex number. */ |
| 965 class HexNumberException implements Exception { | 977 class HexNumberException implements Exception { |
| 966 HexNumberException(); | 978 HexNumberException(); |
| 967 } | 979 } |
| 968 | 980 |
| OLD | NEW |