Repository: joshtemple/lkml

Issue:
Multiple colons
This is a fun one - turns out Looker is accepting of lkml code that has multiple colon (`:`) characters in a row, possibly with spaces between.

This works in both measure/dimension definitions and in value_format, and probably in other places too.

```
view: my_view {
  # other stuff

  measure: :: ::::: my_measure {
    type: number
    value_format:: : "0.00%"
  }
}
```

The current lkml parser (v1.3.1) throws an exception on this input.

Discussion:

Patch:
diff --git a/lkml/parser.py b/lkml/parser.py
index c6cdc43..cbf25ca 100644
--- a/lkml/parser.py
+++ b/lkml/parser.py
@@ -371,13 +371,15 @@ class Parser:
             return None
 
         prefix = self.consume_trivia()
-        if self.check(tokens.ValueToken):
+
+        colon = None
+        while self.check(tokens.ValueToken):
             token = self.consume()
             suffix = self.consume_trivia()
             colon = tree.Colon(
                 line_number=token.line_number, prefix=prefix, suffix=suffix
             )
-        else:
+        if not colon:
             return None
 
         if self.log_debug:


Test patch:
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 3f0d3de..421b82d 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -215,6 +215,23 @@ def test_parse_key_without_value_token():
     assert result is None
 
 
+def test_parse_key_with_many_value_tokens():
+    stream = (
+        tokens.LiteralToken("label", 1),
+        tokens.ValueToken(1),
+        tokens.WhitespaceToken(" ", 1),
+        tokens.ValueToken(1),
+        tokens.ValueToken(1),
+        tokens.WhitespaceToken("  ", 1),
+        tokens.ValueToken(1),
+        tokens.WhitespaceToken("\t", 1),
+        tokens.StreamEndToken(1),
+    )
+    parser = lkml.parser.Parser(stream)
+    result = parser.parse_key()
+    assert result == (SyntaxToken("label", 1), Colon(line_number=1, suffix="\t"))
+
+
 def test_debug_logging_statements_execute_successfully(parser):
     parser.log_debug = True
     parser.parse()