Explorar o código

Fixes #38, Lexer & parser now handles metrics segments that begin with numbers or only have numbers

Torkel Ödegaard %!s(int64=12) %!d(string=hai) anos
pai
achega
89224401a9

+ 4 - 4
src/app/services/graphite/lexer.js

@@ -116,6 +116,7 @@ define([
 
 
   for (var i = 0; i < 128; i++) {
   for (var i = 0; i < 128; i++) {
     identifierStartTable[i] =
     identifierStartTable[i] =
+      i >= 48 && i <= 57 || // 0-9
       i === 36 ||           // $
       i === 36 ||           // $
       i >= 65 && i <= 90 || // A-Z
       i >= 65 && i <= 90 || // A-Z
       i === 95 ||           // _
       i === 95 ||           // _
@@ -183,10 +184,10 @@ define([
       }
       }
 
 
       match =
       match =
-        this.scanIdentifier() ||
-        this.scanTemplateSequence() ||
         this.scanPunctuator() ||
         this.scanPunctuator() ||
-        this.scanNumericLiteral();
+        this.scanNumericLiteral() ||
+        this.scanIdentifier() ||
+        this.scanTemplateSequence();
 
 
       if (match) {
       if (match) {
         this.skip(match.value.length);
         this.skip(match.value.length);
@@ -402,7 +403,6 @@ define([
       }
       }
 
 
       // Numbers must start either with a decimal digit or a point.
       // Numbers must start either with a decimal digit or a point.
-
       if (char !== "." && !isDecimalDigit(char)) {
       if (char !== "." && !isDecimalDigit(char)) {
         return null;
         return null;
       }
       }

+ 3 - 3
src/app/services/graphite/parser.js

@@ -66,7 +66,7 @@ define([
         return curly;
         return curly;
       }
       }
 
 
-      if (this.match('identifier')) {
+      if (this.match('identifier') || this.match('number')) {
         return {
         return {
           type: 'segment',
           type: 'segment',
           value: this.consumeToken().value
           value: this.consumeToken().value
@@ -97,7 +97,7 @@ define([
     },
     },
 
 
     metricExpression: function() {
     metricExpression: function() {
-      if (!this.match('templateStart') && !this.match('identifier')) {
+      if (!this.match('templateStart') && !this.match('identifier') && !this.match('number')) {
         return null;
         return null;
       }
       }
 
 
@@ -153,8 +153,8 @@ define([
 
 
       var param =
       var param =
         this.functionCall() ||
         this.functionCall() ||
-        this.metricExpression() ||
         this.numericLiteral() ||
         this.numericLiteral() ||
+        this.metricExpression() ||
         this.stringLiteral();
         this.stringLiteral();
 
 
       if (!this.match(',')) {
       if (!this.match(',')) {

+ 15 - 11
src/test/specs/lexer-specs.js

@@ -31,21 +31,25 @@ define([
       expect(tokens[6].value).to.be('second');
       expect(tokens[6].value).to.be('second');
     });
     });
 
 
+    it('should tokenize metric expression with number segments', function() {
+      var lexer = new Lexer("metric.10.12_10.test");
+      var tokens = lexer.tokenize();
+      expect(tokens[0].type).to.be('identifier');
+      expect(tokens[2].type).to.be('identifier');
+      expect(tokens[2].value).to.be('10');
+      expect(tokens[4].value).to.be('12_10');
+      expect(tokens[4].type).to.be('identifier');
+    });
 
 
-    it('should tokenize functions and args', function() {
-      var lexer = new Lexer("sum(metric.test, 12, 'test')");
+    it('should tokenize func call with numbered metric and number arg', function() {
+      var lexer = new Lexer("scale(metric.10, 15)");
       var tokens = lexer.tokenize();
       var tokens = lexer.tokenize();
-      expect(tokens[0].value).to.be('sum');
       expect(tokens[0].type).to.be('identifier');
       expect(tokens[0].type).to.be('identifier');
-      expect(tokens[1].value).to.be('(');
-      expect(tokens[1].type).to.be('(');
-      expect(tokens[5].type).to.be(',');
-      expect(tokens[5].value).to.be(',');
+      expect(tokens[2].type).to.be('identifier');
+      expect(tokens[2].value).to.be('metric');
+      expect(tokens[4].value).to.be('10');
+      expect(tokens[4].type).to.be('number');
       expect(tokens[6].type).to.be('number');
       expect(tokens[6].type).to.be('number');
-      expect(tokens[6].value).to.be('12');
-      expect(tokens[8].type).to.be('string');
-      expect(tokens[8].value).to.be('test');
-      expect(tokens[tokens.length - 1].value).to.be(')');
     });
     });
 
 
     it('should tokenize metric with template parameter', function() {
     it('should tokenize metric with template parameter', function() {

+ 11 - 0
src/test/specs/parser-specs.js

@@ -13,6 +13,17 @@ define([
       expect(rootNode.segments[0].value).to.be('metric');
       expect(rootNode.segments[0].value).to.be('metric');
     });
     });
 
 
+    it('simple metric expression with numbers in segments', function() {
+      var parser = new Parser('metric.10.15_20.5');
+      var rootNode = parser.getAst();
+
+      expect(rootNode.type).to.be('metric');
+      expect(rootNode.segments.length).to.be(4);
+      expect(rootNode.segments[1].value).to.be('10');
+      expect(rootNode.segments[2].value).to.be('15_20');
+      expect(rootNode.segments[3].value).to.be('5');
+    });
+
     it('simple metric expression with curly braces', function() {
     it('simple metric expression with curly braces', function() {
       var parser = new Parser('metric.se1-{count, max}');
       var parser = new Parser('metric.se1-{count, max}');
       var rootNode = parser.getAst();
       var rootNode = parser.getAst();