We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] Cannot use overrides containing '%' character
# 🐛 Bug
## Description
I am unable to override a value that contains the '%' character without doing special quoting around the override

## To reproduce

```
import hydra

@hydra.main()
def foo(*args, **kargs):
    pass

foo()
```

** Minimal Code/Config snippet to reproduce **
```
python test.py +bar=/path/to/pattern_%r.bin
```

** Stack trace/error message **
```
LexerNoViableAltException: +bar=/path/to/pattern_%r.bin
                                                 ^
See https://hydra.cc/docs/next/advanced/override_grammar/basic for details

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
```

## Expected Behavior
bar's value should be set to "/path/to/pattern_%r.bin".

## System information
- **Hydra Version** :  1.0.0
- **Python version** : 3.7.7
- **Virtual environment type and version** : 
- **Operating system** : 

## Additional context
Similar error to: Issue #798.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hydra/core/override_parser/overrides_visitor.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
2 import sys
3 import warnings
4 from typing import Any, Dict, List, Optional, Union
5 
6 from antlr4 import TerminalNode, Token
7 from antlr4.error.ErrorListener import ErrorListener
8 from antlr4.tree.Tree import TerminalNodeImpl
9 
10 from hydra._internal.grammar.functions import FunctionCall, Functions
11 from hydra.core.override_parser.types import (
12     ChoiceSweep,
13     Glob,
14     IntervalSweep,
15     Key,
16     Override,
17     OverrideType,
18     ParsedElementType,
19     Quote,
20     QuotedString,
21     RangeSweep,
22     ValueType,
23 )
24 from hydra.errors import HydraException
25 
26 try:
27     from hydra.grammar.gen.OverrideLexer import OverrideLexer
28     from hydra.grammar.gen.OverrideParser import OverrideParser
29     from hydra.grammar.gen.OverrideParserVisitor import OverrideParserVisitor
30 
31 except ModuleNotFoundError:
32     print(
33         "Error importing generated parsers, run `python setup.py antlr` to regenerate."
34     )
35     sys.exit(1)
36 
37 
38 class HydraOverrideVisitor(OverrideParserVisitor):  # type: ignore
39     def __init__(self, functions: Functions):
40         self.functions = functions
41 
42     def visitPackage(self, ctx: OverrideParser.PackageContext) -> str:
43         return ctx.getText()  # type: ignore
44 
45     def visitPackageOrGroup(self, ctx: OverrideParser.PackageOrGroupContext) -> str:
46         return ctx.getText()  # type: ignore
47 
48     def visitKey(self, ctx: OverrideParser.KeyContext) -> Key:
49         # key : packageOrGroup (AT package? (COLON package)? )?;
50 
51         nc = ctx.getChildCount()
52         pkg1 = None
53         pkg2 = None
54         if nc == 1:
55             # packageOrGroup
56             key = ctx.getChild(0).getText()
57         elif nc > 1:
58             key = ctx.getChild(0).getText()
59             if ctx.getChild(1).symbol.text == "@:":
60                 pkg1 = None
61                 pkg2 = ctx.getChild(2).getText()
62             elif ctx.getChild(1).symbol.text == "@":
63                 pkg1 = ctx.getChild(2).getText()
64                 if nc > 3:
65                     assert ctx.getChild(3).symbol.text == ":"
66                     pkg2 = ctx.getChild(4).getText()
67             else:
68                 assert False
69 
70         else:
71             assert False
72 
73         return Key(key_or_group=key, pkg1=pkg1, pkg2=pkg2)
74 
75     def is_ws(self, c: Any) -> bool:
76         return isinstance(c, TerminalNodeImpl) and c.symbol.type == OverrideLexer.WS
77 
78     def visitPrimitive(
79         self, ctx: OverrideParser.PrimitiveContext
80     ) -> Optional[Union[QuotedString, int, bool, float, str]]:
81         ret: Optional[Union[int, bool, float, str]]
82         first_idx = 0
83         last_idx = ctx.getChildCount()
84         # skip first if whitespace
85         if self.is_ws(ctx.getChild(0)):
86             if last_idx == 1:
87                 # Only whitespaces => this is not allowed.
88                 raise HydraException(
89                     "Trying to parse a primitive that is all whitespaces"
90                 )
91             first_idx = 1
92         if self.is_ws(ctx.getChild(-1)):
93             last_idx = last_idx - 1
94         num = last_idx - first_idx
95         if num > 1:
96             ret = ctx.getText().strip()
97         else:
98             node = ctx.getChild(first_idx)
99             if node.symbol.type == OverrideLexer.QUOTED_VALUE:
100                 text = node.getText()
101                 qc = text[0]
102                 text = text[1:-1]
103                 if qc == "'":
104                     quote = Quote.single
105                     text = text.replace("\\'", "'")
106                 elif qc == '"':
107                     quote = Quote.double
108                     text = text.replace('\\"', '"')
109                 else:
110                     assert False
111                 return QuotedString(text=text, quote=quote)
112             elif node.symbol.type in (OverrideLexer.ID, OverrideLexer.INTERPOLATION):
113                 ret = node.symbol.text
114             elif node.symbol.type == OverrideLexer.INT:
115                 ret = int(node.symbol.text)
116             elif node.symbol.type == OverrideLexer.FLOAT:
117                 ret = float(node.symbol.text)
118             elif node.symbol.type == OverrideLexer.NULL:
119                 ret = None
120             elif node.symbol.type == OverrideLexer.BOOL:
121                 text = node.getText().lower()
122                 if text == "true":
123                     ret = True
124                 elif text == "false":
125                     ret = False
126                 else:
127                     assert False
128             else:
129                 return node.getText()  # type: ignore
130         return ret
131 
132     def visitListValue(
133         self, ctx: OverrideParser.ListValueContext
134     ) -> List[ParsedElementType]:
135         ret: List[ParsedElementType] = []
136 
137         idx = 0
138         while True:
139             element = ctx.element(idx)
140             if element is None:
141                 break
142             else:
143                 idx = idx + 1
144                 ret.append(self.visitElement(element))
145         return ret
146 
147     def visitDictValue(
148         self, ctx: OverrideParser.DictValueContext
149     ) -> Dict[str, ParsedElementType]:
150         ret = {}
151         children = ctx.getChildren()
152         assert self.is_matching_terminal(next(children), OverrideLexer.BRACE_OPEN)
153         first = True
154         while True:
155             item = next(children)
156             if self.is_matching_terminal(item, OverrideLexer.BRACE_CLOSE):
157                 break
158             if not first and self.is_matching_terminal(item, OverrideLexer.COMMA):
159                 continue
160 
161             pkey = item.getText()
162 
163             assert self.is_matching_terminal(next(children), OverrideLexer.COLON)
164 
165             value = next(children)
166             if isinstance(value, OverrideParser.ElementContext):
167                 ret[pkey] = self.visitElement(value)
168             else:
169                 assert False
170             first = False
171 
172         return ret
173 
174     def visitElement(self, ctx: OverrideParser.ElementContext) -> ParsedElementType:
175         assert isinstance(ctx, OverrideParser.ElementContext)
176         if ctx.function():
177             return self.visitFunction(ctx.function())  # type: ignore
178         elif ctx.primitive():
179             return self.visitPrimitive(ctx.primitive())
180         elif ctx.listValue():
181             return self.visitListValue(ctx.listValue())
182         elif ctx.dictValue():
183             return self.visitDictValue(ctx.dictValue())
184         else:
185             assert False
186 
187     def visitValue(
188         self, ctx: OverrideParser.ValueContext
189     ) -> Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]:
190         if ctx.element():
191             return self.visitElement(ctx.element())
192         elif ctx.simpleChoiceSweep() is not None:
193             return self.visitSimpleChoiceSweep(ctx.simpleChoiceSweep())
194         assert False
195 
196     def visitOverride(self, ctx: OverrideParser.OverrideContext) -> Override:
197         override_type = OverrideType.CHANGE
198         children = ctx.getChildren()
199         first_node = next(children)
200         if isinstance(first_node, TerminalNodeImpl):
201             symbol_text = first_node.symbol.text
202             if symbol_text == "+":
203                 override_type = OverrideType.ADD
204             elif symbol_text == "~":
205                 override_type = OverrideType.DEL
206             else:
207                 assert False
208             key_node = next(children)
209         else:
210             key_node = first_node
211 
212         key = self.visitKey(key_node)
213         value: Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]
214         eq_node = next(children)
215         if (
216             override_type == OverrideType.DEL
217             and isinstance(eq_node, TerminalNode)
218             and eq_node.symbol.type == Token.EOF
219         ):
220             value = None
221             value_type = None
222         else:
223             assert self.is_matching_terminal(eq_node, OverrideLexer.EQUAL)
224             if ctx.value() is None:
225                 value = ""
226                 value_type = ValueType.ELEMENT
227             else:
228                 value = self.visitValue(ctx.value())
229                 if isinstance(value, ChoiceSweep):
230                     if value.simple_form:
231                         value_type = ValueType.SIMPLE_CHOICE_SWEEP
232                     else:
233                         value_type = ValueType.CHOICE_SWEEP
234                 elif isinstance(value, Glob):
235                     value_type = ValueType.GLOB_CHOICE_SWEEP
236                 elif isinstance(value, IntervalSweep):
237                     value_type = ValueType.INTERVAL_SWEEP
238                 elif isinstance(value, RangeSweep):
239                     value_type = ValueType.RANGE_SWEEP
240                 else:
241                     value_type = ValueType.ELEMENT
242 
243         return Override(
244             type=override_type,
245             key_or_group=key.key_or_group,
246             _value=value,
247             value_type=value_type,
248             pkg1=key.pkg1,
249             pkg2=key.pkg2,
250         )
251 
252     def is_matching_terminal(self, node: Any, symbol_type: int) -> bool:
253         return isinstance(node, TerminalNodeImpl) and node.symbol.type == symbol_type
254 
255     def visitSimpleChoiceSweep(
256         self, ctx: OverrideParser.SimpleChoiceSweepContext
257     ) -> ChoiceSweep:
258         ret = []
259         for child in ctx.getChildren(
260             predicate=lambda x: not self.is_matching_terminal(x, OverrideLexer.COMMA)
261         ):
262             ret.append(self.visitElement(child))
263         return ChoiceSweep(simple_form=True, list=ret)
264 
265     def visitFunction(self, ctx: OverrideParser.FunctionContext) -> Any:
266         args = []
267         kwargs = {}
268         children = ctx.getChildren()
269         func_name = next(children).getText()
270         assert self.is_matching_terminal(next(children), OverrideLexer.POPEN)
271         in_kwargs = False
272         while True:
273             cur = next(children)
274             if self.is_matching_terminal(cur, OverrideLexer.PCLOSE):
275                 break
276 
277             if isinstance(cur, OverrideParser.ArgNameContext):
278                 in_kwargs = True
279                 name = cur.getChild(0).getText()
280                 cur = next(children)
281                 value = self.visitElement(cur)
282                 kwargs[name] = value
283             else:
284                 if self.is_matching_terminal(cur, OverrideLexer.COMMA):
285                     continue
286                 if in_kwargs:
287                     raise HydraException("positional argument follows keyword argument")
288                 value = self.visitElement(cur)
289                 args.append(value)
290 
291         function = FunctionCall(name=func_name, args=args, kwargs=kwargs)
292         try:
293             return self.functions.eval(function)
294         except Exception as e:
295             raise HydraException(
296                 f"{type(e).__name__} while evaluating '{ctx.getText()}': {e}"
297             ) from e
298 
299 
300 class HydraErrorListener(ErrorListener):  # type: ignore
301     def syntaxError(
302         self,
303         recognizer: Any,
304         offending_symbol: Any,
305         line: Any,
306         column: Any,
307         msg: Any,
308         e: Any,
309     ) -> None:
310         if msg is not None:
311             raise HydraException(msg) from e
312         else:
313             raise HydraException(str(e)) from e
314 
315     def reportAmbiguity(
316         self,
317         recognizer: Any,
318         dfa: Any,
319         startIndex: Any,
320         stopIndex: Any,
321         exact: Any,
322         ambigAlts: Any,
323         configs: Any,
324     ) -> None:
325         warnings.warn(
326             message="reportAmbiguity: please file an issue with minimal repro instructions",
327             category=UserWarning,
328         )
329 
330     def reportAttemptingFullContext(
331         self,
332         recognizer: Any,
333         dfa: Any,
334         startIndex: Any,
335         stopIndex: Any,
336         conflictingAlts: Any,
337         configs: Any,
338     ) -> None:
339         warnings.warn(
340             message="reportAttemptingFullContext: please file an issue with a minimal repro instructions",
341             category=UserWarning,
342         )
343 
344     def reportContextSensitivity(
345         self,
346         recognizer: Any,
347         dfa: Any,
348         startIndex: Any,
349         stopIndex: Any,
350         prediction: Any,
351         configs: Any,
352     ) -> None:
353         warnings.warn(
354             message="reportContextSensitivity: please file an issue with minimal a repro instructions",
355             category=UserWarning,
356         )
357
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/hydra/core/override_parser/overrides_visitor.py b/hydra/core/override_parser/overrides_visitor.py
--- a/hydra/core/override_parser/overrides_visitor.py
+++ b/hydra/core/override_parser/overrides_visitor.py
@@ -1,7 +1,7 @@
 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
 import sys
 import warnings
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Tuple, Union
 
 from antlr4 import TerminalNode, Token
 from antlr4.error.ErrorListener import ErrorListener
@@ -93,7 +93,20 @@
             last_idx = last_idx - 1
         num = last_idx - first_idx
         if num > 1:
-            ret = ctx.getText().strip()
+            # Concatenate, while un-escaping as needed.
+            tokens = []
+            for i, n in enumerate(ctx.getChildren()):
+                if n.symbol.type == OverrideLexer.WS and (
+                    i < first_idx or i >= last_idx
+                ):
+                    # Skip leading / trailing whitespaces.
+                    continue
+                tokens.append(
+                    n.symbol.text[1::2]  # un-escape by skipping every other char
+                    if n.symbol.type == OverrideLexer.ESC
+                    else n.symbol.text
+                )
+            ret = "".join(tokens)
         else:
             node = ctx.getChild(first_idx)
             if node.symbol.type == OverrideLexer.QUOTED_VALUE:
@@ -125,6 +138,8 @@
                     ret = False
                 else:
                     assert False
+            elif node.symbol.type == OverrideLexer.ESC:
+                ret = node.symbol.text[1::2]
             else:
                 return node.getText()  # type: ignore
         return ret
@@ -147,29 +162,23 @@
     def visitDictValue(
         self, ctx: OverrideParser.DictValueContext
     ) -> Dict[str, ParsedElementType]:
-        ret = {}
-        children = ctx.getChildren()
-        assert self.is_matching_terminal(next(children), OverrideLexer.BRACE_OPEN)
-        first = True
-        while True:
-            item = next(children)
-            if self.is_matching_terminal(item, OverrideLexer.BRACE_CLOSE):
-                break
-            if not first and self.is_matching_terminal(item, OverrideLexer.COMMA):
-                continue
-
-            pkey = item.getText()
-
-            assert self.is_matching_terminal(next(children), OverrideLexer.COLON)
-
-            value = next(children)
-            if isinstance(value, OverrideParser.ElementContext):
-                ret[pkey] = self.visitElement(value)
-            else:
-                assert False
-            first = False
+        assert self.is_matching_terminal(ctx.getChild(0), OverrideLexer.BRACE_OPEN)
+        return dict(
+            self.visitDictKeyValuePair(ctx.getChild(i))
+            for i in range(1, ctx.getChildCount() - 1, 2)
+        )
 
-        return ret
+    def visitDictKeyValuePair(
+        self, ctx: OverrideParser.DictKeyValuePairContext
+    ) -> Tuple[str, ParsedElementType]:
+        children = ctx.getChildren()
+        item = next(children)
+        assert self.is_matching_terminal(item, OverrideLexer.ID)
+        pkey = item.getText()
+        assert self.is_matching_terminal(next(children), OverrideLexer.COLON)
+        value = next(children)
+        assert isinstance(value, OverrideParser.ElementContext)
+        return pkey, self.visitElement(value)
 
     def visitElement(self, ctx: OverrideParser.ElementContext) -> ParsedElementType:
         assert isinstance(ctx, OverrideParser.ElementContext)

{"golden_diff": "diff --git a/hydra/core/override_parser/overrides_visitor.py b/hydra/core/override_parser/overrides_visitor.py\n--- a/hydra/core/override_parser/overrides_visitor.py\n+++ b/hydra/core/override_parser/overrides_visitor.py\n@@ -1,7 +1,7 @@\n # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\n import sys\n import warnings\n-from typing import Any, Dict, List, Optional, Union\n+from typing import Any, Dict, List, Optional, Tuple, Union\n \n from antlr4 import TerminalNode, Token\n from antlr4.error.ErrorListener import ErrorListener\n@@ -93,7 +93,20 @@\n             last_idx = last_idx - 1\n         num = last_idx - first_idx\n         if num > 1:\n-            ret = ctx.getText().strip()\n+            # Concatenate, while un-escaping as needed.\n+            tokens = []\n+            for i, n in enumerate(ctx.getChildren()):\n+                if n.symbol.type == OverrideLexer.WS and (\n+                    i < first_idx or i >= last_idx\n+                ):\n+                    # Skip leading / trailing whitespaces.\n+                    continue\n+                tokens.append(\n+                    n.symbol.text[1::2]  # un-escape by skipping every other char\n+                    if n.symbol.type == OverrideLexer.ESC\n+                    else n.symbol.text\n+                )\n+            ret = \"\".join(tokens)\n         else:\n             node = ctx.getChild(first_idx)\n             if node.symbol.type == OverrideLexer.QUOTED_VALUE:\n@@ -125,6 +138,8 @@\n                     ret = False\n                 else:\n                     assert False\n+            elif node.symbol.type == OverrideLexer.ESC:\n+                ret = node.symbol.text[1::2]\n             else:\n                 return node.getText()  # type: ignore\n         return ret\n@@ -147,29 +162,23 @@\n     def visitDictValue(\n         self, ctx: OverrideParser.DictValueContext\n     ) -> Dict[str, ParsedElementType]:\n-        ret = {}\n-        children = ctx.getChildren()\n-        assert self.is_matching_terminal(next(children), OverrideLexer.BRACE_OPEN)\n-        first = True\n-        while True:\n-            item = next(children)\n-            if self.is_matching_terminal(item, OverrideLexer.BRACE_CLOSE):\n-                break\n-            if not first and self.is_matching_terminal(item, OverrideLexer.COMMA):\n-                continue\n-\n-            pkey = item.getText()\n-\n-            assert self.is_matching_terminal(next(children), OverrideLexer.COLON)\n-\n-            value = next(children)\n-            if isinstance(value, OverrideParser.ElementContext):\n-                ret[pkey] = self.visitElement(value)\n-            else:\n-                assert False\n-            first = False\n+        assert self.is_matching_terminal(ctx.getChild(0), OverrideLexer.BRACE_OPEN)\n+        return dict(\n+            self.visitDictKeyValuePair(ctx.getChild(i))\n+            for i in range(1, ctx.getChildCount() - 1, 2)\n+        )\n \n-        return ret\n+    def visitDictKeyValuePair(\n+        self, ctx: OverrideParser.DictKeyValuePairContext\n+    ) -> Tuple[str, ParsedElementType]:\n+        children = ctx.getChildren()\n+        item = next(children)\n+        assert self.is_matching_terminal(item, OverrideLexer.ID)\n+        pkey = item.getText()\n+        assert self.is_matching_terminal(next(children), OverrideLexer.COLON)\n+        value = next(children)\n+        assert isinstance(value, OverrideParser.ElementContext)\n+        return pkey, self.visitElement(value)\n \n     def visitElement(self, ctx: OverrideParser.ElementContext) -> ParsedElementType:\n         assert isinstance(ctx, OverrideParser.ElementContext)\n", "issue": "[Bug] Cannot use overrides containing '%' character\n# \ud83d\udc1b Bug\r\n## Description\r\nI am unable to override a value that contains the '%' character without doing special quoting around the override\r\n\r\n## To reproduce\r\n\r\n```\r\nimport hydra\r\n\r\n@hydra.main()\r\ndef foo(*args, **kargs):\r\n    pass\r\n\r\nfoo()\r\n```\r\n\r\n** Minimal Code/Config snippet to reproduce **\r\n```\r\npython test.py +bar=/path/to/pattern_%r.bin\r\n```\r\n\r\n** Stack trace/error message **\r\n```\r\nLexerNoViableAltException: +bar=/path/to/pattern_%r.bin\r\n                                                 ^\r\nSee https://hydra.cc/docs/next/advanced/override_grammar/basic for details\r\n\r\nSet the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.\r\n```\r\n\r\n## Expected Behavior\r\nbar's value should be set to \"/path/to/pattern_%r.bin\".\r\n\r\n## System information\r\n- **Hydra Version** :  1.0.0\r\n- **Python version** : 3.7.7\r\n- **Virtual environment type and version** : \r\n- **Operating system** : \r\n\r\n## Additional context\r\nSimilar error to: Issue #798.\r\n\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport sys\nimport warnings\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom antlr4 import TerminalNode, Token\nfrom antlr4.error.ErrorListener import ErrorListener\nfrom antlr4.tree.Tree import TerminalNodeImpl\n\nfrom hydra._internal.grammar.functions import FunctionCall, Functions\nfrom hydra.core.override_parser.types import (\n    ChoiceSweep,\n    Glob,\n    IntervalSweep,\n    Key,\n    Override,\n    OverrideType,\n    ParsedElementType,\n    Quote,\n    QuotedString,\n    RangeSweep,\n    ValueType,\n)\nfrom hydra.errors import HydraException\n\ntry:\n    from hydra.grammar.gen.OverrideLexer import OverrideLexer\n    from hydra.grammar.gen.OverrideParser import OverrideParser\n    from hydra.grammar.gen.OverrideParserVisitor import OverrideParserVisitor\n\nexcept ModuleNotFoundError:\n    print(\n        \"Error importing generated parsers, run `python setup.py antlr` to regenerate.\"\n    )\n    sys.exit(1)\n\n\nclass HydraOverrideVisitor(OverrideParserVisitor):  # type: ignore\n    def __init__(self, functions: Functions):\n        self.functions = functions\n\n    def visitPackage(self, ctx: OverrideParser.PackageContext) -> str:\n        return ctx.getText()  # type: ignore\n\n    def visitPackageOrGroup(self, ctx: OverrideParser.PackageOrGroupContext) -> str:\n        return ctx.getText()  # type: ignore\n\n    def visitKey(self, ctx: OverrideParser.KeyContext) -> Key:\n        # key : packageOrGroup (AT package? (COLON package)? )?;\n\n        nc = ctx.getChildCount()\n        pkg1 = None\n        pkg2 = None\n        if nc == 1:\n            # packageOrGroup\n            key = ctx.getChild(0).getText()\n        elif nc > 1:\n            key = ctx.getChild(0).getText()\n            if ctx.getChild(1).symbol.text == \"@:\":\n                pkg1 = None\n                pkg2 = ctx.getChild(2).getText()\n            elif ctx.getChild(1).symbol.text == \"@\":\n                pkg1 = ctx.getChild(2).getText()\n                if nc > 3:\n                    assert ctx.getChild(3).symbol.text == \":\"\n                    pkg2 = ctx.getChild(4).getText()\n            else:\n                assert False\n\n        else:\n            assert False\n\n        return Key(key_or_group=key, pkg1=pkg1, pkg2=pkg2)\n\n    def is_ws(self, c: Any) -> bool:\n        return isinstance(c, TerminalNodeImpl) and c.symbol.type == OverrideLexer.WS\n\n    def visitPrimitive(\n        self, ctx: OverrideParser.PrimitiveContext\n    ) -> Optional[Union[QuotedString, int, bool, float, str]]:\n        ret: Optional[Union[int, bool, float, str]]\n        first_idx = 0\n        last_idx = ctx.getChildCount()\n        # skip first if whitespace\n        if self.is_ws(ctx.getChild(0)):\n            if last_idx == 1:\n                # Only whitespaces => this is not allowed.\n                raise HydraException(\n                    \"Trying to parse a primitive that is all whitespaces\"\n                )\n            first_idx = 1\n        if self.is_ws(ctx.getChild(-1)):\n            last_idx = last_idx - 1\n        num = last_idx - first_idx\n        if num > 1:\n            ret = ctx.getText().strip()\n        else:\n            node = ctx.getChild(first_idx)\n            if node.symbol.type == OverrideLexer.QUOTED_VALUE:\n                text = node.getText()\n                qc = text[0]\n                text = text[1:-1]\n                if qc == \"'\":\n                    quote = Quote.single\n                    text = text.replace(\"\\\\'\", \"'\")\n                elif qc == '\"':\n                    quote = Quote.double\n                    text = text.replace('\\\\\"', '\"')\n                else:\n                    assert False\n                return QuotedString(text=text, quote=quote)\n            elif node.symbol.type in (OverrideLexer.ID, OverrideLexer.INTERPOLATION):\n                ret = node.symbol.text\n            elif node.symbol.type == OverrideLexer.INT:\n                ret = int(node.symbol.text)\n            elif node.symbol.type == OverrideLexer.FLOAT:\n                ret = float(node.symbol.text)\n            elif node.symbol.type == OverrideLexer.NULL:\n                ret = None\n            elif node.symbol.type == OverrideLexer.BOOL:\n                text = node.getText().lower()\n                if text == \"true\":\n                    ret = True\n                elif text == \"false\":\n                    ret = False\n                else:\n                    assert False\n            else:\n                return node.getText()  # type: ignore\n        return ret\n\n    def visitListValue(\n        self, ctx: OverrideParser.ListValueContext\n    ) -> List[ParsedElementType]:\n        ret: List[ParsedElementType] = []\n\n        idx = 0\n        while True:\n            element = ctx.element(idx)\n            if element is None:\n                break\n            else:\n                idx = idx + 1\n                ret.append(self.visitElement(element))\n        return ret\n\n    def visitDictValue(\n        self, ctx: OverrideParser.DictValueContext\n    ) -> Dict[str, ParsedElementType]:\n        ret = {}\n        children = ctx.getChildren()\n        assert self.is_matching_terminal(next(children), OverrideLexer.BRACE_OPEN)\n        first = True\n        while True:\n            item = next(children)\n            if self.is_matching_terminal(item, OverrideLexer.BRACE_CLOSE):\n                break\n            if not first and self.is_matching_terminal(item, OverrideLexer.COMMA):\n                continue\n\n            pkey = item.getText()\n\n            assert self.is_matching_terminal(next(children), OverrideLexer.COLON)\n\n            value = next(children)\n            if isinstance(value, OverrideParser.ElementContext):\n                ret[pkey] = self.visitElement(value)\n            else:\n                assert False\n            first = False\n\n        return ret\n\n    def visitElement(self, ctx: OverrideParser.ElementContext) -> ParsedElementType:\n        assert isinstance(ctx, OverrideParser.ElementContext)\n        if ctx.function():\n            return self.visitFunction(ctx.function())  # type: ignore\n        elif ctx.primitive():\n            return self.visitPrimitive(ctx.primitive())\n        elif ctx.listValue():\n            return self.visitListValue(ctx.listValue())\n        elif ctx.dictValue():\n            return self.visitDictValue(ctx.dictValue())\n        else:\n            assert False\n\n    def visitValue(\n        self, ctx: OverrideParser.ValueContext\n    ) -> Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]:\n        if ctx.element():\n            return self.visitElement(ctx.element())\n        elif ctx.simpleChoiceSweep() is not None:\n            return self.visitSimpleChoiceSweep(ctx.simpleChoiceSweep())\n        assert False\n\n    def visitOverride(self, ctx: OverrideParser.OverrideContext) -> Override:\n        override_type = OverrideType.CHANGE\n        children = ctx.getChildren()\n        first_node = next(children)\n        if isinstance(first_node, TerminalNodeImpl):\n            symbol_text = first_node.symbol.text\n            if symbol_text == \"+\":\n                override_type = OverrideType.ADD\n            elif symbol_text == \"~\":\n                override_type = OverrideType.DEL\n            else:\n                assert False\n            key_node = next(children)\n        else:\n            key_node = first_node\n\n        key = self.visitKey(key_node)\n        value: Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]\n        eq_node = next(children)\n        if (\n            override_type == OverrideType.DEL\n            and isinstance(eq_node, TerminalNode)\n            and eq_node.symbol.type == Token.EOF\n        ):\n            value = None\n            value_type = None\n        else:\n            assert self.is_matching_terminal(eq_node, OverrideLexer.EQUAL)\n            if ctx.value() is None:\n                value = \"\"\n                value_type = ValueType.ELEMENT\n            else:\n                value = self.visitValue(ctx.value())\n                if isinstance(value, ChoiceSweep):\n                    if value.simple_form:\n                        value_type = ValueType.SIMPLE_CHOICE_SWEEP\n                    else:\n                        value_type = ValueType.CHOICE_SWEEP\n                elif isinstance(value, Glob):\n                    value_type = ValueType.GLOB_CHOICE_SWEEP\n                elif isinstance(value, IntervalSweep):\n                    value_type = ValueType.INTERVAL_SWEEP\n                elif isinstance(value, RangeSweep):\n                    value_type = ValueType.RANGE_SWEEP\n                else:\n                    value_type = ValueType.ELEMENT\n\n        return Override(\n            type=override_type,\n            key_or_group=key.key_or_group,\n            _value=value,\n            value_type=value_type,\n            pkg1=key.pkg1,\n            pkg2=key.pkg2,\n        )\n\n    def is_matching_terminal(self, node: Any, symbol_type: int) -> bool:\n        return isinstance(node, TerminalNodeImpl) and node.symbol.type == symbol_type\n\n    def visitSimpleChoiceSweep(\n        self, ctx: OverrideParser.SimpleChoiceSweepContext\n    ) -> ChoiceSweep:\n        ret = []\n        for child in ctx.getChildren(\n            predicate=lambda x: not self.is_matching_terminal(x, OverrideLexer.COMMA)\n        ):\n            ret.append(self.visitElement(child))\n        return ChoiceSweep(simple_form=True, list=ret)\n\n    def visitFunction(self, ctx: OverrideParser.FunctionContext) -> Any:\n        args = []\n        kwargs = {}\n        children = ctx.getChildren()\n        func_name = next(children).getText()\n        assert self.is_matching_terminal(next(children), OverrideLexer.POPEN)\n        in_kwargs = False\n        while True:\n            cur = next(children)\n            if self.is_matching_terminal(cur, OverrideLexer.PCLOSE):\n                break\n\n            if isinstance(cur, OverrideParser.ArgNameContext):\n                in_kwargs = True\n                name = cur.getChild(0).getText()\n                cur = next(children)\n                value = self.visitElement(cur)\n                kwargs[name] = value\n            else:\n                if self.is_matching_terminal(cur, OverrideLexer.COMMA):\n                    continue\n                if in_kwargs:\n                    raise HydraException(\"positional argument follows keyword argument\")\n                value = self.visitElement(cur)\n                args.append(value)\n\n        function = FunctionCall(name=func_name, args=args, kwargs=kwargs)\n        try:\n            return self.functions.eval(function)\n        except Exception as e:\n            raise HydraException(\n                f\"{type(e).__name__} while evaluating '{ctx.getText()}': {e}\"\n            ) from e\n\n\nclass HydraErrorListener(ErrorListener):  # type: ignore\n    def syntaxError(\n        self,\n        recognizer: Any,\n        offending_symbol: Any,\n        line: Any,\n        column: Any,\n        msg: Any,\n        e: Any,\n    ) -> None:\n        if msg is not None:\n            raise HydraException(msg) from e\n        else:\n            raise HydraException(str(e)) from e\n\n    def reportAmbiguity(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        exact: Any,\n        ambigAlts: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportAmbiguity: please file an issue with minimal repro instructions\",\n            category=UserWarning,\n        )\n\n    def reportAttemptingFullContext(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        conflictingAlts: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportAttemptingFullContext: please file an issue with a minimal repro instructions\",\n            category=UserWarning,\n        )\n\n    def reportContextSensitivity(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        prediction: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportContextSensitivity: please file an issue with minimal a repro instructions\",\n            category=UserWarning,\n        )\n", "path": "hydra/core/override_parser/overrides_visitor.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport sys\nimport warnings\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom antlr4 import TerminalNode, Token\nfrom antlr4.error.ErrorListener import ErrorListener\nfrom antlr4.tree.Tree import TerminalNodeImpl\n\nfrom hydra._internal.grammar.functions import FunctionCall, Functions\nfrom hydra.core.override_parser.types import (\n    ChoiceSweep,\n    Glob,\n    IntervalSweep,\n    Key,\n    Override,\n    OverrideType,\n    ParsedElementType,\n    Quote,\n    QuotedString,\n    RangeSweep,\n    ValueType,\n)\nfrom hydra.errors import HydraException\n\ntry:\n    from hydra.grammar.gen.OverrideLexer import OverrideLexer\n    from hydra.grammar.gen.OverrideParser import OverrideParser\n    from hydra.grammar.gen.OverrideParserVisitor import OverrideParserVisitor\n\nexcept ModuleNotFoundError:\n    print(\n        \"Error importing generated parsers, run `python setup.py antlr` to regenerate.\"\n    )\n    sys.exit(1)\n\n\nclass HydraOverrideVisitor(OverrideParserVisitor):  # type: ignore\n    def __init__(self, functions: Functions):\n        self.functions = functions\n\n    def visitPackage(self, ctx: OverrideParser.PackageContext) -> str:\n        return ctx.getText()  # type: ignore\n\n    def visitPackageOrGroup(self, ctx: OverrideParser.PackageOrGroupContext) -> str:\n        return ctx.getText()  # type: ignore\n\n    def visitKey(self, ctx: OverrideParser.KeyContext) -> Key:\n        # key : packageOrGroup (AT package? (COLON package)? )?;\n\n        nc = ctx.getChildCount()\n        pkg1 = None\n        pkg2 = None\n        if nc == 1:\n            # packageOrGroup\n            key = ctx.getChild(0).getText()\n        elif nc > 1:\n            key = ctx.getChild(0).getText()\n            if ctx.getChild(1).symbol.text == \"@:\":\n                pkg1 = None\n                pkg2 = ctx.getChild(2).getText()\n            elif ctx.getChild(1).symbol.text == \"@\":\n                pkg1 = ctx.getChild(2).getText()\n                if nc > 3:\n                    assert ctx.getChild(3).symbol.text == \":\"\n                    pkg2 = ctx.getChild(4).getText()\n            else:\n                assert False\n\n        else:\n            assert False\n\n        return Key(key_or_group=key, pkg1=pkg1, pkg2=pkg2)\n\n    def is_ws(self, c: Any) -> bool:\n        return isinstance(c, TerminalNodeImpl) and c.symbol.type == OverrideLexer.WS\n\n    def visitPrimitive(\n        self, ctx: OverrideParser.PrimitiveContext\n    ) -> Optional[Union[QuotedString, int, bool, float, str]]:\n        ret: Optional[Union[int, bool, float, str]]\n        first_idx = 0\n        last_idx = ctx.getChildCount()\n        # skip first if whitespace\n        if self.is_ws(ctx.getChild(0)):\n            if last_idx == 1:\n                # Only whitespaces => this is not allowed.\n                raise HydraException(\n                    \"Trying to parse a primitive that is all whitespaces\"\n                )\n            first_idx = 1\n        if self.is_ws(ctx.getChild(-1)):\n            last_idx = last_idx - 1\n        num = last_idx - first_idx\n        if num > 1:\n            # Concatenate, while un-escaping as needed.\n            tokens = []\n            for i, n in enumerate(ctx.getChildren()):\n                if n.symbol.type == OverrideLexer.WS and (\n                    i < first_idx or i >= last_idx\n                ):\n                    # Skip leading / trailing whitespaces.\n                    continue\n                tokens.append(\n                    n.symbol.text[1::2]  # un-escape by skipping every other char\n                    if n.symbol.type == OverrideLexer.ESC\n                    else n.symbol.text\n                )\n            ret = \"\".join(tokens)\n        else:\n            node = ctx.getChild(first_idx)\n            if node.symbol.type == OverrideLexer.QUOTED_VALUE:\n                text = node.getText()\n                qc = text[0]\n                text = text[1:-1]\n                if qc == \"'\":\n                    quote = Quote.single\n                    text = text.replace(\"\\\\'\", \"'\")\n                elif qc == '\"':\n                    quote = Quote.double\n                    text = text.replace('\\\\\"', '\"')\n                else:\n                    assert False\n                return QuotedString(text=text, quote=quote)\n            elif node.symbol.type in (OverrideLexer.ID, OverrideLexer.INTERPOLATION):\n                ret = node.symbol.text\n            elif node.symbol.type == OverrideLexer.INT:\n                ret = int(node.symbol.text)\n            elif node.symbol.type == OverrideLexer.FLOAT:\n                ret = float(node.symbol.text)\n            elif node.symbol.type == OverrideLexer.NULL:\n                ret = None\n            elif node.symbol.type == OverrideLexer.BOOL:\n                text = node.getText().lower()\n                if text == \"true\":\n                    ret = True\n                elif text == \"false\":\n                    ret = False\n                else:\n                    assert False\n            elif node.symbol.type == OverrideLexer.ESC:\n                ret = node.symbol.text[1::2]\n            else:\n                return node.getText()  # type: ignore\n        return ret\n\n    def visitListValue(\n        self, ctx: OverrideParser.ListValueContext\n    ) -> List[ParsedElementType]:\n        ret: List[ParsedElementType] = []\n\n        idx = 0\n        while True:\n            element = ctx.element(idx)\n            if element is None:\n                break\n            else:\n                idx = idx + 1\n                ret.append(self.visitElement(element))\n        return ret\n\n    def visitDictValue(\n        self, ctx: OverrideParser.DictValueContext\n    ) -> Dict[str, ParsedElementType]:\n        assert self.is_matching_terminal(ctx.getChild(0), OverrideLexer.BRACE_OPEN)\n        return dict(\n            self.visitDictKeyValuePair(ctx.getChild(i))\n            for i in range(1, ctx.getChildCount() - 1, 2)\n        )\n\n    def visitDictKeyValuePair(\n        self, ctx: OverrideParser.DictKeyValuePairContext\n    ) -> Tuple[str, ParsedElementType]:\n        children = ctx.getChildren()\n        item = next(children)\n        assert self.is_matching_terminal(item, OverrideLexer.ID)\n        pkey = item.getText()\n        assert self.is_matching_terminal(next(children), OverrideLexer.COLON)\n        value = next(children)\n        assert isinstance(value, OverrideParser.ElementContext)\n        return pkey, self.visitElement(value)\n\n    def visitElement(self, ctx: OverrideParser.ElementContext) -> ParsedElementType:\n        assert isinstance(ctx, OverrideParser.ElementContext)\n        if ctx.function():\n            return self.visitFunction(ctx.function())  # type: ignore\n        elif ctx.primitive():\n            return self.visitPrimitive(ctx.primitive())\n        elif ctx.listValue():\n            return self.visitListValue(ctx.listValue())\n        elif ctx.dictValue():\n            return self.visitDictValue(ctx.dictValue())\n        else:\n            assert False\n\n    def visitValue(\n        self, ctx: OverrideParser.ValueContext\n    ) -> Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]:\n        if ctx.element():\n            return self.visitElement(ctx.element())\n        elif ctx.simpleChoiceSweep() is not None:\n            return self.visitSimpleChoiceSweep(ctx.simpleChoiceSweep())\n        assert False\n\n    def visitOverride(self, ctx: OverrideParser.OverrideContext) -> Override:\n        override_type = OverrideType.CHANGE\n        children = ctx.getChildren()\n        first_node = next(children)\n        if isinstance(first_node, TerminalNodeImpl):\n            symbol_text = first_node.symbol.text\n            if symbol_text == \"+\":\n                override_type = OverrideType.ADD\n            elif symbol_text == \"~\":\n                override_type = OverrideType.DEL\n            else:\n                assert False\n            key_node = next(children)\n        else:\n            key_node = first_node\n\n        key = self.visitKey(key_node)\n        value: Union[ChoiceSweep, RangeSweep, IntervalSweep, ParsedElementType]\n        eq_node = next(children)\n        if (\n            override_type == OverrideType.DEL\n            and isinstance(eq_node, TerminalNode)\n            and eq_node.symbol.type == Token.EOF\n        ):\n            value = None\n            value_type = None\n        else:\n            assert self.is_matching_terminal(eq_node, OverrideLexer.EQUAL)\n            if ctx.value() is None:\n                value = \"\"\n                value_type = ValueType.ELEMENT\n            else:\n                value = self.visitValue(ctx.value())\n                if isinstance(value, ChoiceSweep):\n                    if value.simple_form:\n                        value_type = ValueType.SIMPLE_CHOICE_SWEEP\n                    else:\n                        value_type = ValueType.CHOICE_SWEEP\n                elif isinstance(value, Glob):\n                    value_type = ValueType.GLOB_CHOICE_SWEEP\n                elif isinstance(value, IntervalSweep):\n                    value_type = ValueType.INTERVAL_SWEEP\n                elif isinstance(value, RangeSweep):\n                    value_type = ValueType.RANGE_SWEEP\n                else:\n                    value_type = ValueType.ELEMENT\n\n        return Override(\n            type=override_type,\n            key_or_group=key.key_or_group,\n            _value=value,\n            value_type=value_type,\n            pkg1=key.pkg1,\n            pkg2=key.pkg2,\n        )\n\n    def is_matching_terminal(self, node: Any, symbol_type: int) -> bool:\n        return isinstance(node, TerminalNodeImpl) and node.symbol.type == symbol_type\n\n    def visitSimpleChoiceSweep(\n        self, ctx: OverrideParser.SimpleChoiceSweepContext\n    ) -> ChoiceSweep:\n        ret = []\n        for child in ctx.getChildren(\n            predicate=lambda x: not self.is_matching_terminal(x, OverrideLexer.COMMA)\n        ):\n            ret.append(self.visitElement(child))\n        return ChoiceSweep(simple_form=True, list=ret)\n\n    def visitFunction(self, ctx: OverrideParser.FunctionContext) -> Any:\n        args = []\n        kwargs = {}\n        children = ctx.getChildren()\n        func_name = next(children).getText()\n        assert self.is_matching_terminal(next(children), OverrideLexer.POPEN)\n        in_kwargs = False\n        while True:\n            cur = next(children)\n            if self.is_matching_terminal(cur, OverrideLexer.PCLOSE):\n                break\n\n            if isinstance(cur, OverrideParser.ArgNameContext):\n                in_kwargs = True\n                name = cur.getChild(0).getText()\n                cur = next(children)\n                value = self.visitElement(cur)\n                kwargs[name] = value\n            else:\n                if self.is_matching_terminal(cur, OverrideLexer.COMMA):\n                    continue\n                if in_kwargs:\n                    raise HydraException(\"positional argument follows keyword argument\")\n                value = self.visitElement(cur)\n                args.append(value)\n\n        function = FunctionCall(name=func_name, args=args, kwargs=kwargs)\n        try:\n            return self.functions.eval(function)\n        except Exception as e:\n            raise HydraException(\n                f\"{type(e).__name__} while evaluating '{ctx.getText()}': {e}\"\n            ) from e\n\n\nclass HydraErrorListener(ErrorListener):  # type: ignore\n    def syntaxError(\n        self,\n        recognizer: Any,\n        offending_symbol: Any,\n        line: Any,\n        column: Any,\n        msg: Any,\n        e: Any,\n    ) -> None:\n        if msg is not None:\n            raise HydraException(msg) from e\n        else:\n            raise HydraException(str(e)) from e\n\n    def reportAmbiguity(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        exact: Any,\n        ambigAlts: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportAmbiguity: please file an issue with minimal repro instructions\",\n            category=UserWarning,\n        )\n\n    def reportAttemptingFullContext(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        conflictingAlts: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportAttemptingFullContext: please file an issue with a minimal repro instructions\",\n            category=UserWarning,\n        )\n\n    def reportContextSensitivity(\n        self,\n        recognizer: Any,\n        dfa: Any,\n        startIndex: Any,\n        stopIndex: Any,\n        prediction: Any,\n        configs: Any,\n    ) -> None:\n        warnings.warn(\n            message=\"reportContextSensitivity: please file an issue with minimal a repro instructions\",\n            category=UserWarning,\n        )\n", "path": "hydra/core/override_parser/overrides_visitor.py"}]}