code: private Expression parseTildeExpression() {
      consumeNextToken(TILDE);
      int major = intOf(consumeNextToken(NUMERIC).lexeme);
      if (!tokens.positiveLookahead(DOT)) {
        return new GreaterOrEqual(versionOf(major, 0, 0));
      }
      consumeNextToken(DOT);
      int minor = intOf(consumeNextToken(NUMERIC).lexeme);
      if (!tokens.positiveLookahead(DOT)) {
        return new And(new GreaterOrEqual(versionOf(major, minor, 0)),
            new Less(versionOf(major + 1, 0, 0)));
      }
      consumeNextToken(DOT);
      int patch = intOf(consumeNextToken(NUMERIC).lexeme);
      return new And(new GreaterOrEqual(versionOf(major, minor, patch)),
          new Less(versionOf(major, minor + 1, 0)));
    }
docs: Parses the {@literal <tilde-expr>} non-terminal.
  
  <pre>
  {@literal
  <tilde-expr> ::= "~" <version>
  }
  </pre>
  
  @return the expression AST