public AST V()
  {
    // V -> D | W | ( L )
        
    List<String> emp = Collections.<String>emptyList();  // an empty list

    String next = toks.peek();  
    
    if ( isNumber(next) ) {
      // D
      double d1 = D();
      return new Value(new Quantity(d1, emp, emp));
      
    } else if ( isAlphabetic(next) ) {
      // W 
      String unitName = toks.pop();
      return new Value(new Quantity(1.0, Arrays.asList(unitName), emp));
      
    } else if ( "(".equals(next) ) {
      // ( L )

      toks.pop();  // Skip the left parenthesis
      AST l = L(); // Recursively grab the contents, which should match L.
 
      String after_l = toks.peek();

      // Immediately following that L should be a right parenthesis. Check
      if ( ")".equals(after_l) ) {
        // It's there, so get rid of it (since we want to remove all
        //    the tokens corresponding to V)
        toks.pop();
        return l;     // A parenthesized L has the same tree as a non-parenthesized L
                      //   (Since the tree structure *already* tells us the way that
                      //    our subexpressions are grouped, keeping around these
                      //    parentheses in the AST is unnecessary; they wouldn't affect
                      //    the final answer.)
      } else {
        throw new ParseError("Expected close-parenthesis, but found: '" + next + "'");
      }  

    } else {
      // The first token can't possibly be part of a V.
      throw new ParseError("Expected number or identifier or subexpression, but found: '" 
                   + next + "'");
    }
  }