diff options
author | becker33 <becker33@llnl.gov> | 2017-05-24 17:13:18 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2017-05-24 17:13:18 -0700 |
commit | 12ab882eba1631f85f4ebd2acfe1a9c41857ca79 (patch) | |
tree | 096d0e928d929fec69fe89ce85fc948e0bb84e9e /lib/spack | |
parent | c1cea7ebcfdcb2573439c8185dae35ce5e55c43f (diff) | |
download | spack-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/spack')
-rw-r--r-- | lib/spack/spack/spec.py | 31 | ||||
-rw-r--r-- | lib/spack/spack/test/spec_syntax.py | 11 |
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): |