summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorbecker33 <becker33@llnl.gov>2017-05-24 17:13:18 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2017-05-24 17:13:18 -0700
commit12ab882eba1631f85f4ebd2acfe1a9c41857ca79 (patch)
tree096d0e928d929fec69fe89ce85fc948e0bb84e9e /lib
parentc1cea7ebcfdcb2573439c8185dae35ce5e55c43f (diff)
downloadspack-12ab882eba1631f85f4ebd2acfe1a9c41857ca79.tar.gz
spack-12ab882eba1631f85f4ebd2acfe1a9c41857ca79.tar.bz2
spack-12ab882eba1631f85f4ebd2acfe1a9c41857ca79.tar.xz
spack-12ab882eba1631f85f4ebd2acfe1a9c41857ca79.zip
Fix issues parsing multiple anonymous specs (#4199)
* fix parser * Removed xfails * cleaned up debug print statements * make use of these changes in gcc * Added comment explaining unreachable line, line left for added protection
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/spec.py31
-rw-r--r--lib/spack/spack/test/spec_syntax.py11
2 files changed, 24 insertions, 18 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index ff213c5986..9e89feb148 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -2958,16 +2958,23 @@ class SpecParser(spack.parse.Parser):
# We're parsing an anonymous spec beginning with a
# key-value pair.
if not specs:
+ self.push_tokens([self.previous, self.token])
+ self.previous = None
specs.append(self.spec(None))
- self.expect(VAL)
- # Raise an error if the previous spec is already
- # concrete (assigned by hash)
- if specs[-1]._hash:
- raise RedundantSpecError(specs[-1],
- 'key-value pair')
- specs[-1]._add_flag(
- self.previous.value, self.token.value)
- self.previous = None
+ else:
+ if specs[-1].concrete:
+ # Trying to add k-v pair to spec from hash
+ raise RedundantSpecError(specs[-1],
+ 'key-value pair')
+ # We should never end up here.
+ # This requires starting a new spec with ID, EQ
+ # After another spec that is not concrete
+ # If the previous spec is not concrete, this is
+ # handled in the spec parsing loop
+ # If it is concrete, see the if statement above
+ # If there is no previous spec, we don't land in
+ # this else case.
+ self.unexpected_token()
else:
# We're parsing a new spec by name
self.previous = None
@@ -3151,7 +3158,11 @@ class SpecParser(spack.parse.Parser):
if self.accept(COLON):
if self.accept(ID):
- end = self.token.value
+ if self.next and self.next.type is EQ:
+ # This is a start: range followed by a key=value pair
+ self.push_tokens([self.token])
+ else:
+ end = self.token.value
elif start:
# No colon, but there was a version.
return Version(start)
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index 2ee9ef486c..906aa77bb2 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -140,10 +140,9 @@ class TestSpecSyntax(object):
self.check_parse("arch=test-None-None", "platform=test")
self.check_parse('@2.7:')
- @pytest.mark.xfail()
def test_anonymous_specs_with_multiple_parts(self):
# Parse anonymous spec with multiple tokens
- self.check_parse('languages=go @4.2:')
+ self.check_parse('@4.2: languages=go', 'languages=go @4.2:')
self.check_parse('@4.2: languages=go')
def test_simple_dependence(self):
@@ -551,12 +550,8 @@ class TestSpecSyntax(object):
@pytest.mark.parametrize('spec,anon_spec,spec_name', [
('openmpi languages=go', 'languages=go', 'openmpi'),
('openmpi @4.6:', '@4.6:', 'openmpi'),
- pytest.mark.xfail(
- ('openmpi languages=go @4.6:', 'languages=go @4.6:', 'openmpi')
- ),
- pytest.mark.xfail(
- ('openmpi @4.6: languages=go', '@4.6: languages=go', 'openmpi')
- ),
+ ('openmpi languages=go @4.6:', 'languages=go @4.6:', 'openmpi'),
+ ('openmpi @4.6: languages=go', '@4.6: languages=go', 'openmpi'),
])
def test_parse_anonymous_specs(spec, anon_spec, spec_name):