From e19d3a531cec778b3f04dcad351a297501e30416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 24 Dec 2013 11:13:50 +0100 Subject: [PATCH] parser and lexer is working ok --- grafana.sublime-project | 32 ++++++++-------- src/app/services/graphite/lexer.js | 16 +++++--- src/app/services/graphite/parser.js | 57 +++++++++++++---------------- src/test/specs/lexer-specs.js | 1 + src/test/specs/parser-specs.js | 19 +++++++++- 5 files changed, 70 insertions(+), 55 deletions(-) diff --git a/grafana.sublime-project b/grafana.sublime-project index 9a0481f92df..127807d37de 100644 --- a/grafana.sublime-project +++ b/grafana.sublime-project @@ -1,18 +1,18 @@ { - "folders": - [ - { - "follow_symlinks": true, - "path": ".", - "folder_exclude_patterns": [ - "node_modules" - ] - } - ], - "settings": - { - "tab_size": 2, - "translate_tabs_to_spaces": true, - "trim_trailing_white_space_on_save": true - } + "folders": + [ + { + "follow_symlinks": true, + "path": ".", + "folder_exclude_patterns": [ + "node_modules" + ] + } + ], + "settings": + { + "tab_size": 2, + "translate_tabs_to_spaces": true, + "trim_trailing_white_space_on_save": true + } } diff --git a/src/app/services/graphite/lexer.js b/src/app/services/graphite/lexer.js index 81754ce314e..00fc57a1f70 100644 --- a/src/app/services/graphite/lexer.js +++ b/src/app/services/graphite/lexer.js @@ -339,7 +339,8 @@ define([ return { type: type, - value: id + value: id, + pos: this.char }; }, @@ -407,7 +408,8 @@ define([ return { type: 'number', value: value, - isMalformed: true + isMalformed: true, + pos: this.char }; } @@ -422,7 +424,8 @@ define([ type: 'number', value: value, base: 16, - isMalformed: false + isMalformed: false, + pos: this.char }; } @@ -538,6 +541,7 @@ define([ type: 'number', value: value, base: 10, + pos: this.char, isMalformed: !isFinite(value) }; }, @@ -554,7 +558,8 @@ define([ case "}": return { type: ch1, - value: ch1 + value: ch1, + pos: this.char }; } @@ -658,7 +663,8 @@ define([ type: 'string', value: value, isUnclosed: false, - quote: quote + quote: quote, + pos: this.char }; }, diff --git a/src/app/services/graphite/parser.js b/src/app/services/graphite/parser.js index f43c2c78da6..675de8ed8ac 100644 --- a/src/app/services/graphite/parser.js +++ b/src/app/services/graphite/parser.js @@ -54,23 +54,17 @@ define([ if (this.match('.')) { this.index++; var rest = this.metricExpression(); + if (!rest) { + this.errorMark('Expected metric identifier'); + return null; + } + node.segments = node.segments.concat(rest.segments) } return node; }, - matchToken: function(type, index) { - var token = this.tokens[this.index + index]; - return (token === undefined && type === '') || - token && token.type === type; - }, - - match: function(token1, token2) { - return this.matchToken(token1, 0) && - (!token2 || this.matchToken(token2, 1)) - }, - functionCall: function() { if (!this.match('identifier', '(')) { return null; @@ -86,7 +80,7 @@ define([ node.params = this.functionParameters(); if (!this.match(')')) { - this.error = 'missing closing paranthesis'; + this.errorMark('Expected closing paranthesis'); return null; } @@ -140,27 +134,26 @@ define([ }; }, - isUnexpectedToken: function (expected, value) { - if (this.token === null) { - this.error = "Expected token: " + expected + " instead found end of string"; - return true; - } - - if (this.token.type === expected) { - return false; - } - - if (value && this.token.value === value) { - return false; - } - - this.error = "Expected token " + expected + - ' instead found token ' + this.token.type + - ' ("' + this.token.value + '")' + - " at position: " + this.lexer.char; - - return true; + errorMark: function(text) { + var currentToken = this.tokens[this.index]; + var type = currentToken ? currentToken.type : 'end of string'; + this.error = { + text: text + " instead found " + type, + pos: currentToken ? currentToken.pos : this.lexer.char + }; }, + + matchToken: function(type, index) { + var token = this.tokens[this.index + index]; + return (token === undefined && type === '') || + token && token.type === type; + }, + + match: function(token1, token2) { + return this.matchToken(token1, 0) && + (!token2 || this.matchToken(token2, 1)) + }, + }; return Parser; diff --git a/src/test/specs/lexer-specs.js b/src/test/specs/lexer-specs.js index a87883f3d05..ba01a584e56 100644 --- a/src/test/specs/lexer-specs.js +++ b/src/test/specs/lexer-specs.js @@ -11,6 +11,7 @@ define([ expect(tokens[1].value).to.be('.'); expect(tokens[2].type).to.be('identifier'); expect(tokens[4].type).to.be('identifier'); + expect(tokens[4].pos).to.be(13); }); it('should tokenize functions and args', function() { diff --git a/src/test/specs/parser-specs.js b/src/test/specs/parser-specs.js index d85a730679b..7565de3a0d5 100644 --- a/src/test/specs/parser-specs.js +++ b/src/test/specs/parser-specs.js @@ -2,7 +2,7 @@ define([ '../../app/services/graphite/Parser' ], function(Parser) { - describe('when parsing graphite expression', function() { + describe('when parsing', function() { it('simple metric expression', function() { var parser = new Parser('metric.test.*.asd.count'); @@ -12,7 +12,6 @@ define([ expect(rootNode.type).to.be('metric'); expect(rootNode.segments.length).to.be(5); expect(rootNode.segments[0].value).to.be('metric'); - }); it('simple function', function() { @@ -60,6 +59,22 @@ define([ expect(rootNode.params[1].type).to.be('metric'); }); + it('invalid metric expression', function() { + var parser = new Parser('metric.test.*.asd.'); + var rootNode = parser.getAst(); + + expect(parser.error.text).to.be('Expected metric identifier instead found end of string'); + expect(parser.error.pos).to.be(19); + }); + + it('invalid function expression missing closing paranthesis', function() { + var parser = new Parser('sum(test'); + var rootNode = parser.getAst(); + + expect(parser.error.text).to.be('Expected closing paranthesis instead found end of string'); + expect(parser.error.pos).to.be(9); + }); + }); });