docs: protected AstNode nonliteral() throws ScanException, ParseException {
  		AstNode v = null;
  		switch (token.getSymbol()) {
  			case IDENTIFIER:
  				String name = consumeToken().getImage();
  				if (token.getSymbol() == COLON && lookahead(0).getSymbol() == IDENTIFIER && lookahead(1).getSymbol() == LPAREN) { // ns:f(...)
  					consumeToken();
  					name += ":" + token.getImage();
  					consumeToken();
  				}
  				if (token.getSymbol() == LPAREN) { // function
  					v = function(name, params());
  				} else { // identifier
  					v = identifier(name);
  				}
  				break;
  			case LPAREN:
  				consumeToken();
  				v = expr(true);
  				consumeToken(RPAREN);
  				v = new AstNested(v);
  				break;
  		}
  		return v;
  	}