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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 122 |
123 void _eatSemicolon() { | 123 void _eatSemicolon() { |
124 _eat(TokenKind.SEMICOLON); | 124 _eat(TokenKind.SEMICOLON); |
125 } | 125 } |
126 | 126 |
127 void _errorExpected(String expected) { | 127 void _errorExpected(String expected) { |
128 var tok = _next(); | 128 var tok = _next(); |
129 var message; | 129 var message; |
130 try { | 130 try { |
131 message = 'expected $expected, but found $tok'; | 131 message = 'expected $expected, but found $tok'; |
132 } catch (final e) { | 132 } catch (e) { |
133 message = 'parsing error expected $expected'; | 133 message = 'parsing error expected $expected'; |
134 } | 134 } |
135 _error(message, tok.span); | 135 _error(message, tok.span); |
136 } | 136 } |
137 | 137 |
138 void _error(String message, [SourceSpan location=null]) { | 138 void _error(String message, [SourceSpan location=null]) { |
139 if (location === null) { | 139 if (location === null) { |
140 location = _peekToken.span; | 140 location = _peekToken.span; |
141 } | 141 } |
142 | 142 |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 } | 750 } |
751 } else if (_peekIdentifier()) { | 751 } else if (_peekIdentifier()) { |
752 hexText = identifier().name; | 752 hexText = identifier().name; |
753 } else { | 753 } else { |
754 _errorExpected("hex number"); | 754 _errorExpected("hex number"); |
755 } | 755 } |
756 | 756 |
757 try { | 757 try { |
758 int hexValue = parseHex(hexText); | 758 int hexValue = parseHex(hexText); |
759 return new HexColorTerm(hexValue, hexText, _makeSpan(start)); | 759 return new HexColorTerm(hexValue, hexText, _makeSpan(start)); |
760 } catch (HexNumberException hne) { | 760 } on HexNumberException catch (hne) { |
761 _error('Bad hex number', _makeSpan(start)); | 761 _error('Bad hex number', _makeSpan(start)); |
762 } | 762 } |
763 break; | 763 break; |
764 case TokenKind.INTEGER: | 764 case TokenKind.INTEGER: |
765 t = _next(); | 765 t = _next(); |
766 value = Math.parseInt("${unary}${t.text}"); | 766 value = Math.parseInt("${unary}${t.text}"); |
767 break; | 767 break; |
768 case TokenKind.DOUBLE: | 768 case TokenKind.DOUBLE: |
769 t = _next(); | 769 t = _next(); |
770 value = Math.parseDouble("${unary}${t.text}"); | 770 value = Math.parseDouble("${unary}${t.text}"); |
771 break; | 771 break; |
772 case TokenKind.SINGLE_QUOTE: | 772 case TokenKind.SINGLE_QUOTE: |
773 case TokenKind.DOUBLE_QUOTE: | 773 case TokenKind.DOUBLE_QUOTE: |
774 value = processQuotedString(false); | 774 value = processQuotedString(false); |
775 value = '"${value}"'; | 775 value = '"${value}"'; |
776 return new LiteralTerm(value, value, _makeSpan(start)); | 776 return new LiteralTerm(value, value, _makeSpan(start)); |
777 case TokenKind.LPAREN: | 777 case TokenKind.LPAREN: |
778 _next(); | 778 _next(); |
779 | 779 |
780 GroupTerm group = new GroupTerm(_makeSpan(start)); | 780 GroupTerm group = new GroupTerm(_makeSpan(start)); |
781 | 781 |
782 do { | 782 do { |
783 var term = processTerm(); | 783 var term = processTerm(); |
784 if (term != null && term is LiteralTerm) { | 784 if (term != null && term is LiteralTerm) { |
785 group.add(term); | 785 group.add(term); |
786 } | 786 } |
787 } while (!_maybeEat(TokenKind.RPAREN)); | 787 } while (!_maybeEat(TokenKind.RPAREN)); |
788 | 788 |
789 return group; | 789 return group; |
790 case TokenKind.LBRACK: | 790 case TokenKind.LBRACK: |
791 _next(); | 791 _next(); |
792 | 792 |
793 var term = processTerm(); | 793 var term = processTerm(); |
794 if (!(term is NumberTerm)) { | 794 if (!(term is NumberTerm)) { |
795 _error('Expecting a positive number', _makeSpan(start)); | 795 _error('Expecting a positive number', _makeSpan(start)); |
796 } | 796 } |
(...skipping 16 matching lines...) Expand all Loading... |
813 | 813 |
814 // What kind of identifier is it? | 814 // What kind of identifier is it? |
815 try { | 815 try { |
816 // Named color? | 816 // Named color? |
817 int colorValue = TokenKind.matchColorName(nameValue.name); | 817 int colorValue = TokenKind.matchColorName(nameValue.name); |
818 | 818 |
819 // Yes, process the color as an RGB value. | 819 // Yes, process the color as an RGB value. |
820 String rgbColor = TokenKind.decimalToHex(colorValue, 3); | 820 String rgbColor = TokenKind.decimalToHex(colorValue, 3); |
821 try { | 821 try { |
822 colorValue = parseHex(rgbColor); | 822 colorValue = parseHex(rgbColor); |
823 } catch (HexNumberException hne) { | 823 } on HexNumberException catch (hne) { |
824 _error('Bad hex number', _makeSpan(start)); | 824 _error('Bad hex number', _makeSpan(start)); |
825 } | 825 } |
826 return new HexColorTerm(colorValue, rgbColor, _makeSpan(start)); | 826 return new HexColorTerm(colorValue, rgbColor, _makeSpan(start)); |
827 } catch (final error) { | 827 } catch (error) { |
828 if (error is NoColorMatchException) { | 828 if (error is NoColorMatchException) { |
829 // TODO(terry): Other named things to match with validator? | 829 // TODO(terry): Other named things to match with validator? |
830 | 830 |
831 // TODO(terry): Disable call to _warning need one World class for | 831 // TODO(terry): Disable call to _warning need one World class for |
832 // both CSS parser and other parser (e.g., template) | 832 // both CSS parser and other parser (e.g., template) |
833 // so all warnings, errors, options, etc. are driven | 833 // so all warnings, errors, options, etc. are driven |
834 // from the one World. | 834 // from the one World. |
835 // _warning('Unknown property value ${error.name}', _makeSpan(start)); | 835 // _warning('Unknown property value ${error.name}', _makeSpan(start)); |
836 return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start)); | 836 return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start)); |
837 } | 837 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 | 1008 |
1009 return result; | 1009 return result; |
1010 } | 1010 } |
1011 } | 1011 } |
1012 | 1012 |
1013 /** Not a hex number. */ | 1013 /** Not a hex number. */ |
1014 class HexNumberException implements Exception { | 1014 class HexNumberException implements Exception { |
1015 HexNumberException(); | 1015 HexNumberException(); |
1016 } | 1016 } |
1017 | 1017 |
OLD | NEW |