code: private CompositeExpression parseTildeRange() {
          consumeNextToken(TILDE);
          int major = intOf(consumeNextToken(NUMERIC).lexeme);
          if (!tokens.positiveLookahead(DOT)) {
              return gte(versionFor(major)).and(lt(versionFor(major + 1)));
          }
          consumeNextToken(DOT);
          int minor = intOf(consumeNextToken(NUMERIC).lexeme);
          if (!tokens.positiveLookahead(DOT)) {
              return gte(versionFor(major, minor)).and(lt(versionFor(major, minor + 1)));
          }
          consumeNextToken(DOT);
          int patch = intOf(consumeNextToken(NUMERIC).lexeme);
          return gte(versionFor(major, minor, patch)).and(lt(versionFor(major, minor + 1)));
      }
docs: Parses the {@literal <tilde-range>} non-terminal.
  
  <pre>
  {@literal
  <tilde-range> ::= "~" <version>
  }
  </pre>
  
  @return the expression AST