private AstNode memberExprTail(boolean allowCallSyntax,AstNode pn) throws IOException {
  if (pn == null)   codeBug();
  int pos=pn.getPosition();
  int lineno;
  tailLoop:   for (; ; ) {
    int tt=peekToken();
switch (tt) {
case Token.DOT:
case Token.DOTDOT:
      lineno=ts.lineno;
    pn=propertyAccess(tt,pn);
  pn.setLineno(lineno);
break;
case Token.DOTQUERY:
consumeToken();
int opPos=ts.tokenBeg, rp=-1;
lineno=ts.lineno;
mustHaveXML();
setRequiresActivation();
AstNode filter=expr();
int end=getNodeEnd(filter);
if (mustMatchToken(Token.RP,"msg.no.paren")) {
rp=ts.tokenBeg;
end=ts.tokenEnd;
}
XmlDotQuery q=new XmlDotQuery(pos,end - pos);
q.setLeft(pn);
q.setRight(filter);
q.setOperatorPosition(opPos);
q.setRp(rp - pos);
q.setLineno(lineno);
pn=q;
break;
case Token.LB:
consumeToken();
int lb=ts.tokenBeg, rb=-1;
lineno=ts.lineno;
AstNode expr=expr();
end=getNodeEnd(expr);
if (mustMatchToken(Token.RB,"msg.no.bracket.index")) {
rb=ts.tokenBeg;
end=ts.tokenEnd;
}
ElementGet g=new ElementGet(pos,end - pos);
g.setTarget(pn);
g.setElement(expr);
g.setParens(lb,rb);
g.setLineno(lineno);
pn=g;
break;
case Token.LP:
if (!allowCallSyntax) {
break tailLoop;
}
lineno=ts.lineno;
consumeToken();
checkCallRequiresActivation(pn);
FunctionCall f=new FunctionCall(pos);
f.setTarget(pn);
f.setLineno(lineno);
f.setLp(ts.tokenBeg - pos);
List<AstNode> args=argumentList();
if (args != null && args.size() > ARGC_LIMIT) reportError("msg.too.many.function.args");
f.setArguments(args);
f.setRp(ts.tokenBeg - pos);
f.setLength(ts.tokenEnd - pos);
pn=f;
break;
default :
break tailLoop;
}
}
return pn;
}

private AstNode memberExprTail ( boolean allowCallSyntax , AstNode pn ) throws IOException { if ( pn == null ) codeBug ( ) ; int pos = pn . getPosition ( ) ; int lineno ; tailLoop : for ( ; ; ) { int tt = peekToken ( ) ; switch ( tt ) { case Token . DOT : case Token . DOTDOT : lineno = ts . lineno ; pn = propertyAccess ( tt , pn ) ; pn . setLineno ( lineno ) ; break ; case Token . DOTQUERY : consumeToken ( ) ; int opPos = ts . tokenBeg , rp = - 1 ; lineno = ts . lineno ; mustHaveXML ( ) ; setRequiresActivation ( ) ; AstNode filter = expr ( ) ; int end = getNodeEnd ( filter ) ; if ( mustMatchToken ( Token . RP , "msg.no.paren" ) ) { rp = ts . tokenBeg ; end = ts . tokenEnd ; } XmlDotQuery q = new XmlDotQuery ( pos , end - pos ) ; q . setLeft ( pn ) ; q . setRight ( filter ) ; q . setOperatorPosition ( opPos ) ; q . setRp ( rp - pos ) ; q . setLineno ( lineno ) ; pn = q ; break ; case Token . LB : consumeToken ( ) ; int lb = ts . tokenBeg , rb = - 1 ; lineno = ts . lineno ; AstNode expr = expr ( ) ; end = getNodeEnd ( expr ) ; if ( mustMatchToken ( Token . RB , "msg.no.bracket.index" ) ) { rb = ts . tokenBeg ; end = ts . tokenEnd ; } ElementGet g = new ElementGet ( pos , end - pos ) ; g . setTarget ( pn ) ; g . setElement ( expr ) ; g . setParens ( lb , rb ) ; g . setLineno ( lineno ) ; pn = g ; break ; case Token . LP : if ( ! allowCallSyntax ) { break tailLoop ; } lineno = ts . lineno ; consumeToken ( ) ; checkCallRequiresActivation ( pn ) ; FunctionCall f = new FunctionCall ( pos ) ; f . setTarget ( pn ) ; f . setLineno ( lineno ) ; f . setLp ( ts . tokenBeg - pos ) ; List < AstNode > args = argumentList ( ) ; if ( args != null && args . size ( ) > ARGC_LIMIT ) reportError ( "msg.too.many.function.args" ) ; f . setArguments ( args ) ; f . setRp ( ts . tokenBeg - pos ) ; f . setLength ( ts . tokenEnd - pos ) ; pn = f ; break ; default : break tailLoop ; } } return pn ; }
parse any number of " ( expr ) " , " [ expr ] " " . expr " , " . . expr " , or " . ( expr ) " constructs trailing the passed expression .
