From 50f94911b1e73549ca21859d70faee687332589c Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 7 Jun 2013 16:14:22 -0600 Subject: [PATCH] Scan string literals --- src/ol/expression/lexer.js | 35 ++++++++- test/spec/ol/expression/lexer.test.js | 105 ++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/src/ol/expression/lexer.js b/src/ol/expression/lexer.js index ea564bc6f7..881fb26361 100644 --- a/src/ol/expression/lexer.js +++ b/src/ol/expression/lexer.js @@ -691,7 +691,40 @@ ol.expression.Lexer.prototype.scanPunctuator_ = function() { * @private */ ol.expression.Lexer.prototype.scanStringLiteral_ = function() { - throw new Error('Not yet implemented'); + var quote = this.getCurrentCharCode_(); + goog.asserts.assert(quote === ol.expression.Char.SINGLE_QUOTE || + quote === ol.expression.Char.DOUBLE_QUOTE, + 'Strings must start with a quote: ' + String.fromCharCode(quote)); + + var start = this.index_; + this.increment_(1); + + var str = ''; + var code; + while (this.index_ < this.length_) { + code = this.getCurrentCharCode_(); + this.increment_(1); + if (code === quote) { + quote = 0; + break; + } + // look for escaped quote or backslash + if (code === ol.expression.Char.BACKSLASH) { + str += this.getCurrentChar_(); + this.increment_(1); + } else { + str += String.fromCharCode(code); + } + } + + if (quote !== 0) { + throw new Error('Unterminated string literal'); + } + + return { + type: ol.expression.TokenType.STRING_LITERAL, + value: str + }; }; diff --git a/test/spec/ol/expression/lexer.test.js b/test/spec/ol/expression/lexer.test.js index 0bb094a281..69aff7a6a3 100644 --- a/test/spec/ol/expression/lexer.test.js +++ b/test/spec/ol/expression/lexer.test.js @@ -147,6 +147,111 @@ describe('ol.expression.Lexer', function() { }); + describe('#scanStringLiteral_()', function() { + + function scan(source) { + var lexer = new ol.expression.Lexer(source); + return lexer.scanStringLiteral_(); + } + + it('parses double quoted string', function() { + var token = scan('"my string"'); + expect(token.value).to.be('my string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with internal single quotes', function() { + var token = scan('"my \'quoted\' string"'); + expect(token.value).to.be('my \'quoted\' string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with escaped double quotes', function() { + var token = scan('"my \\"quoted\\" string"'); + expect(token.value).to.be('my "quoted" string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with escaped backslash', function() { + var token = scan('"my \\\ string"'); + expect(token.value).to.be('my \ string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with unicode escape sequences', function() { + var token = scan('"\u006f\u006c\u0033"'); + expect(token.value).to.be('ol3'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with hex escape sequences', function() { + var token = scan('"\x6f\x6c\x33"'); + expect(token.value).to.be('ol3'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses double quoted string with tab', function() { + var token = scan('"a\ttab"'); + expect(token.value).to.be('a\ttab'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('throws on unterminated double quote', function() { + expect(function() { + scan('"never \'ending\' string'); + }).to.throwException(); + }); + + it('parses single quoted string', function() { + var token = scan('\'my string\''); + expect(token.value).to.be('my string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with internal double quotes', function() { + var token = scan('\'my "quoted" string\''); + expect(token.value).to.be('my "quoted" string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with escaped single quotes', function() { + var token = scan('\'my \\\'quoted\\\' string\''); + expect(token.value).to.be('my \'quoted\' string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with escaped backslash', function() { + var token = scan('\'my \\\ string\''); + expect(token.value).to.be('my \ string'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with unicode escape sequences', function() { + var token = scan('\'\u006f\u006c\u0033\''); + expect(token.value).to.be('ol3'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with hex escape sequences', function() { + var token = scan('\'\x6f\x6c\x33\''); + expect(token.value).to.be('ol3'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('parses single quoted string with tab', function() { + var token = scan('\'a\ttab\''); + expect(token.value).to.be('a\ttab'); + expect(token.type).to.be(ol.expression.TokenType.STRING_LITERAL); + }); + + it('throws on unterminated single quote', function() { + expect(function() { + scan('\'never "ending" string'); + }).to.throwException(); + }); + + }); + }); goog.require('ol.expression.Lexer');