/* Generated By:JJTree&JavaCC: Do not edit this line. SMARTSParser.java */ /* $RCSfile$ * $Author: $ * $Date: $ * $Revision: $ * * Copyright (C) 2004-2007 The Chemistry Development Kit (CDK) project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * (or see http://www.gnu.org/copyleft/lesser.html) */ package org.openscience.cdk.smiles.smarts.parser; /** * * @cdk.module smarts */ import java.io.StringReader; import java.util.Stack; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.isomorphism.matchers.QueryAtomContainer; /** * This parser implements a nearly complete subset of the SMARTS syntax as defined on * <a href="http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html">the * Daylight website</a>. * * <p>Example code using SMARTS substructure search looks like: * <pre> * SmilesParser sp = new SmilesParser(); * AtomContainer atomContainer = sp.parseSmiles("CC(=O)OC(=O)C"); * QueryAtomContainer query = SMARTSParser.parse("C*C"); * boolean queryMatch = UniversalIsomorphismTester.isSubgraph(atomContainer, query); * </pre> * * <p>See the cdk.test.smiles.smarts.parser.ParserTest for examples of the implemented * subset. * * This parser is based on JJTree and it generates an AST (Abstract Syntax Tree) * <p>To get the AST, the code looks like: * <pre> * SMARTSParser parser = new SMARTSParser(new java.io.StringReader("C*C")); * ASTStart = parser.start(); * </pre> * * @see org.openscience.cdk.isomorphism.matchers.smarts.SMARTSAtom * * @author Dazhi Jiao * @cdk.created 2007-04-23 * @cdk.githash * * @cdk.require ant1.6 * @cdk.module smarts * * @cdk.keyword SMARTS * @cdk.keyword substructure search */ public class SMARTSParser/*@bgen(jjtree)*/implements SMARTSParserTreeConstants, SMARTSParserConstants {/*@bgen(jjtree)*/ protected JJTSMARTSParserState jjtree = new JJTSMARTSParserState(); /** * This method parses a Smarts String and returns an instance of * <code>QueryAtomContainer</code> */ public static QueryAtomContainer parse(String smarts) throws CDKException { QueryAtomContainer container = null; StringReader reader = new StringReader(smarts); try { SMARTSParser parser = new SMARTSParser(reader); ASTStart start = parser.Start(); org.openscience.cdk.smiles.smarts.parser.visitor.SmartsQueryVisitor visitor = new org.openscience.cdk.smiles.smarts.parser.visitor.SmartsQueryVisitor(); container = (QueryAtomContainer)start.jjtAccept(visitor, null); } catch (ParseException exception) { throw new CDKException("The string " + smarts + " is not a valid" + " SMARTS string: " + exception.getMessage(), exception); } return container; } /** * Start ::= <ReactionExpression> * ReactionExpression ::= <GroupExpression> (">>" <GroupExpression>)? | * ">" <GroupExpression> ">" | ">>" <GroupExpression> * GroupExpression ::= ["("] <SmartsExpresion> [")"] ( "." ["("] <SmartsExpression> [")"] )* * SmartsExpression ::= <AtomExpression> ( ( [ <LowAndBond> ] ( <Digit> | <AtomExpression> ) ) | ( "(" [ <LowAndBond> ] <SmartsExpression> ")" ) )* AtomExpression ::= ( "[" [ <AtomicMass> ] <LowAndExpression> "]" ) | <ExplicitAtomExpression> * LowAndBond ::= <OrBond> [ ";" <AndBond> ] * OrBond ::= <ExplicitHighAndBond> [ "," <OrBond> ] * ExplicitHighAndBond ::= <ImplicitHighAndBond> [ "&" <ExplicitHighAndBond> ] * ImplicitHighAndBond ::= <NotBond> [ <ImplicitHighAndBond> ] * NotBond ::= [ "!" ] <SimpleBond> * SimpleBond ::= "/" | "\\" | "/?" | "\\?" | "=" | "#" | "~" | "@" * ExplicitAtomExpression ::= [ "B" | "C" | "N" | "O" | "P" | "S" | "F" | "CL" | "BR" | "I" * | "c" | "o" | "n" | "*" | "A" | "a" | "p" | "as" | "se" ] * LowAndExpression ::= <OrExpression> ( ";" <LowAndExpression> )? * OrExpression ::= <ExplicitHighAndExpression> ( "," <OrExpression> ) ? * ExplicitHighAndExpression ::= <ImplicitHighAndExpression> ( "&" <ExplicitHighAndExpression> )? * ImplicitHighAndExpression ::= <NotExpression> ( <ImplicitHighAndExpression> ) ? * NotExpression ::= "!" ( <PrimitiveAtomExpression> | <RecursiveSmartsExpression> ) * RecursiveSmartsExpression ::= "$" "(" <SmartsExpression> ")" * PrimitiveAtomExpression ::= <NonHydrogenElement> | "*" | "A" | "a" | "D" (<Digits>)? | "H" (<Digits>)? | "h" (<Digits>)? * | "R" (<Digit>+)? | "r" (<Digit>+)? | "v" (<Digit>+)? | "#X" | "G" (<DIGIT>+) * | "X" (<Digit>+)? | "x" (<Digit>+)? | "^" (<DIGIT>) * | ("+" | "-") (<Digit>+)? | "#" (<Digit>+) | "@" | "@@" | <Digit>+ * Digit ::= ( "0" - "9") * NonHydrogenElement ::= [ "HE" | "LI" | "BE" | "NE" | "NA" | "MG" | "AL" | "SI" | "AR" | "CA" | "SC" | * "TI" | "CR" | "MN" | "FE" | "CO" | "NI" | "CU" | "ZN" | "GA" | "GE" | "AS" | * "SE" | "BR" | "KR" | "RB" | "SR" | "ZR" | "NB" | "MO" | "TC" | "RU" | "RH" | * "PD" | "AG" | "CD" | "IN" | "SN" | "SB" | "TE" | "XE" | "CS" | "BA" | "LA" | * "HF" | "TA" | "RE" | "OS" | "IR" | "PT" | "AU" | "HG" | "TL" | "PB" | "BI" | * "PO" | "AT" | "RN" | "FR" | "RA" | "AC" | "TH" | "PA" | * "B" | "C" | "N" | "O" | "F" | "P" | "S" | "K" | "V" | "Y" | "I" | "U" | * "c" | "o" | "n" | "p" | "as" | "se" ] */ final public ASTStart Start() throws ParseException { /*@bgen(jjtree) Start */ ASTStart jjtn000 = new ASTStart(JJTSTART); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ReactionExpression(); jj_consume_token(0); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; {if (true) return jjtn000;} } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } throw new Error("Missing return statement in function"); } final public void ReactionExpression() throws ParseException { /*@bgen(jjtree) Reaction */ ASTReaction jjtn000 = new ASTReaction(JJTREACTION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: case L_PAREN: case L_BRACKET: GroupExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 146: jj_consume_token(146); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: case L_PAREN: case L_BRACKET: GroupExpression(); break; default: jj_la1[0] = jj_gen; ; } break; default: jj_la1[1] = jj_gen; ; } break; case 147: jj_consume_token(147); GroupExpression(); jj_consume_token(147); break; case 146: jj_consume_token(146); GroupExpression(); break; default: jj_la1[2] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void GroupExpression() throws ParseException { /*@bgen(jjtree) Group */ ASTGroup jjtn000 = new ASTGroup(JJTGROUP); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);ASTSmarts smarts; try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case L_PAREN: jj_consume_token(L_PAREN); break; default: jj_la1[3] = jj_gen; ; } SmartsExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case R_PAREN: jj_consume_token(R_PAREN); break; default: jj_la1[4] = jj_gen; ; } label_1: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 148: ; break; default: jj_la1[5] = jj_gen; break label_1; } jj_consume_token(148); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case L_PAREN: jj_consume_token(L_PAREN); break; default: jj_la1[6] = jj_gen; ; } SmartsExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case R_PAREN: jj_consume_token(R_PAREN); break; default: jj_la1[7] = jj_gen; ; } } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void SmartsExpression() throws ParseException { /*@bgen(jjtree) Smarts */ ASTSmarts jjtn000 = new ASTSmarts(JJTSMARTS); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);ASTAtom atom; try { atom = AtomExpression(); label_2: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case UP_S_BOND: case DN_S_BOND: case UP_OR_UNSPECIFIED_S_BOND: case DN_OR_UNSPECIFIED_S_BOND: case D_BOND: case T_BOND: case AR_BOND: case ANY_BOND: case R_BOND: case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: case L_PAREN: case L_BRACKET: case DIGIT: ; break; default: jj_la1[8] = jj_gen; break label_2; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case UP_S_BOND: case DN_S_BOND: case UP_OR_UNSPECIFIED_S_BOND: case DN_OR_UNSPECIFIED_S_BOND: case D_BOND: case T_BOND: case AR_BOND: case ANY_BOND: case R_BOND: case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: case L_BRACKET: case DIGIT: switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case UP_S_BOND: case DN_S_BOND: case UP_OR_UNSPECIFIED_S_BOND: case DN_OR_UNSPECIFIED_S_BOND: case D_BOND: case T_BOND: case AR_BOND: case ANY_BOND: case R_BOND: LowAndBond(); break; default: jj_la1[9] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: jj_consume_token(DIGIT); ASTLowAndBond bond = null; ASTRingIdentifier ringId = new ASTRingIdentifier(JJTRINGIDENTIFIER); if (jjtree.peekNode() instanceof ASTLowAndBond) { bond = (ASTLowAndBond)jjtree.popNode(); // pop the bond ringId.jjtAddChild(bond, 0); } ringId.setRingId(Integer.parseInt(token.image)); atom.jjtAddChild(ringId, atom.jjtGetNumChildren()); break; case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: case L_BRACKET: atom = AtomExpression(); break; default: jj_la1[10] = jj_gen; jj_consume_token(-1); throw new ParseException(); } break; case L_PAREN: jj_consume_token(L_PAREN); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case UP_S_BOND: case DN_S_BOND: case UP_OR_UNSPECIFIED_S_BOND: case DN_OR_UNSPECIFIED_S_BOND: case D_BOND: case T_BOND: case AR_BOND: case ANY_BOND: case R_BOND: LowAndBond(); break; default: jj_la1[11] = jj_gen; ; } SmartsExpression(); jj_consume_token(R_PAREN); break; default: jj_la1[12] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public ASTAtom AtomExpression() throws ParseException { /*@bgen(jjtree) Atom */ ASTAtom jjtn000 = new ASTAtom(JJTATOM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);Token firstToken; Token secondToken; Token rightBracket; ASTAtomicMass massNode = null; try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case L_BRACKET: jj_consume_token(L_BRACKET); firstToken = getToken(1); secondToken = getToken(2); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: AtomicMass(); massNode = (ASTAtomicMass)jjtree.popNode(); break; default: jj_la1[13] = jj_gen; ; } LowAndExpression(); if (massNode != null) { // insert AtomicMass node into expression ASTLowAndExpression topNode = (ASTLowAndExpression)jjtree.popNode(); topNode.insertLeafChild(massNode); jjtree.pushNode(topNode); } jj_consume_token(R_BRACKET); rightBracket = token; Token HToken = null; // If the LowAndExpression is "[H]", change it to an ExplicitAtom if (firstToken.image.equals("H")) { HToken = firstToken; } else if (massNode != null && massNode.getMass() <= 3 && secondToken != null && secondToken.image.equals("H")) { HToken = secondToken; } if (HToken != null) { if ( (rightBracket.beginColumn - HToken.endColumn) == 1) { jjtree.popNode(); ASTExplicitAtom explicitAtom = new ASTExplicitAtom(JJTEXPLICITATOM); if (massNode!= null) { if (massNode.getMass() == 2) explicitAtom.setSymbol("D"); else if (massNode.getMass() == 3) explicitAtom.setSymbol("T"); else if (massNode.getMass() == 1) explicitAtom.setSymbol("H"); } else { explicitAtom.setSymbol("H"); } jjtree.pushNode(explicitAtom); } } break; case c: case n: case o: case s: case p: case as: case se: case B: case C: case N: case O: case F: case P: case S: case CL: case BR: case I: case WILDCARD: case a: case A: ExplicitAtomExpression(); break; default: jj_la1[14] = jj_gen; jj_consume_token(-1); throw new ParseException(); } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; {if (true) return jjtn000;} } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } throw new Error("Missing return statement in function"); } final public void LowAndBond() throws ParseException { /*@bgen(jjtree) LowAndBond */ ASTLowAndBond jjtn000 = new ASTLowAndBond(JJTLOWANDBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { OrBond(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case L_AND: jj_consume_token(L_AND); LowAndBond(); break; default: jj_la1[15] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void OrBond() throws ParseException { /*@bgen(jjtree) OrBond */ ASTOrBond jjtn000 = new ASTOrBond(JJTORBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ExplicitHighAndBond(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case OR: jj_consume_token(OR); OrBond(); break; default: jj_la1[16] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ExplicitHighAndBond() throws ParseException { /*@bgen(jjtree) ExplicitHighAndBond */ ASTExplicitHighAndBond jjtn000 = new ASTExplicitHighAndBond(JJTEXPLICITHIGHANDBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ImplicitHighAndBond(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case H_AND: jj_consume_token(H_AND); ExplicitHighAndBond(); break; default: jj_la1[17] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ImplicitHighAndBond() throws ParseException { /*@bgen(jjtree) ImplicitHighAndBond */ ASTImplicitHighAndBond jjtn000 = new ASTImplicitHighAndBond(JJTIMPLICITHIGHANDBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { NotBond(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case UP_S_BOND: case DN_S_BOND: case UP_OR_UNSPECIFIED_S_BOND: case DN_OR_UNSPECIFIED_S_BOND: case D_BOND: case T_BOND: case AR_BOND: case ANY_BOND: case R_BOND: ImplicitHighAndBond(); break; default: jj_la1[18] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void NotBond() throws ParseException { /*@bgen(jjtree) NotBond */ ASTNotBond jjtn000 = new ASTNotBond(JJTNOTBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: jj_consume_token(NOT); jjtn000.setType(SMARTSParserConstants.NOT); break; default: jj_la1[19] = jj_gen; ; } SimpleBond(); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void SimpleBond() throws ParseException { /*@bgen(jjtree) SimpleBond */ ASTSimpleBond jjtn000 = new ASTSimpleBond(JJTSIMPLEBOND); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { if (jj_2_1(2)) { jj_consume_token(S_BOND); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case UP_S_BOND: jj_consume_token(UP_S_BOND); break; case DN_S_BOND: jj_consume_token(DN_S_BOND); break; case UP_OR_UNSPECIFIED_S_BOND: jj_consume_token(UP_OR_UNSPECIFIED_S_BOND); break; case DN_OR_UNSPECIFIED_S_BOND: jj_consume_token(DN_OR_UNSPECIFIED_S_BOND); break; case D_BOND: jj_consume_token(D_BOND); break; case T_BOND: jj_consume_token(T_BOND); break; case AR_BOND: jj_consume_token(AR_BOND); break; case ANY_BOND: jj_consume_token(ANY_BOND); break; case R_BOND: jj_consume_token(R_BOND); break; default: jj_la1[20] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setBondType(token.kind); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ExplicitAtomExpression() throws ParseException { /*@bgen(jjtree) ExplicitAtom */ ASTExplicitAtom jjtn000 = new ASTExplicitAtom(JJTEXPLICITATOM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case B: jj_consume_token(B); break; case C: jj_consume_token(C); break; case N: jj_consume_token(N); break; case O: jj_consume_token(O); break; case P: jj_consume_token(P); break; case S: jj_consume_token(S); break; case F: jj_consume_token(F); break; case CL: jj_consume_token(CL); break; case BR: jj_consume_token(BR); break; case I: jj_consume_token(I); break; case WILDCARD: jj_consume_token(WILDCARD); break; case A: jj_consume_token(A); break; case a: jj_consume_token(a); break; case c: jj_consume_token(c); break; case n: jj_consume_token(n); break; case o: jj_consume_token(o); break; case s: jj_consume_token(s); break; case p: jj_consume_token(p); break; case se: jj_consume_token(se); break; case as: jj_consume_token(as); break; default: jj_la1[21] = jj_gen; jj_consume_token(-1); throw new ParseException(); } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setSymbol(token.image); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } // TODO: This requires a fully implemented SMARTSAtom API (or something else) that // could encapsulate logical criterias final public void LowAndExpression() throws ParseException { /*@bgen(jjtree) LowAndExpression */ ASTLowAndExpression jjtn000 = new ASTLowAndExpression(JJTLOWANDEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { OrExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case L_AND: jj_consume_token(L_AND); LowAndExpression(); break; default: jj_la1[22] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void OrExpression() throws ParseException { /*@bgen(jjtree) OrExpression */ ASTOrExpression jjtn000 = new ASTOrExpression(JJTOREXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ExplicitHighAndExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case OR: jj_consume_token(OR); OrExpression(); break; default: jj_la1[23] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ExplicitHighAndExpression() throws ParseException { /*@bgen(jjtree) ExplicitHighAndExpression */ ASTExplicitHighAndExpression jjtn000 = new ASTExplicitHighAndExpression(JJTEXPLICITHIGHANDEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ImplicitHighAndExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case H_AND: jj_consume_token(H_AND); ExplicitHighAndExpression(); break; default: jj_la1[24] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ImplicitHighAndExpression() throws ParseException { /*@bgen(jjtree) ImplicitHighAndExpression */ ASTImplicitHighAndExpression jjtn000 = new ASTImplicitHighAndExpression(JJTIMPLICITHIGHANDEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { NotExpression(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: case S_BOND: case T_BOND: case R_BOND: case c: case n: case o: case s: case p: case as: case se: case H: case HE: case LI: case BE: case B: case C: case N: case O: case F: case NE: case NA: case MG: case AL: case SI: case P: case S: case CL: case AR: case K: case CA: case SC: case TI: case V: case CR: case MN: case FE: case CO: case NI: case CU: case ZN: case GA: case GE: case AS: case SE: case BR: case KR: case RB: case SR: case Y: case ZR: case NB: case MO: case TC: case RU: case RH: case PD: case AG: case CD: case IN: case SN: case SB: case TE: case I: case XE: case CS: case BA: case LA: case HF: case TA: case W: case RE: case OS: case IR: case PT: case AU: case HG: case TL: case PB: case BI: case PO: case AT: case RN: case FR: case RA: case AC: case TH: case PA: case U: case PU: case AM: case CM: case BK: case CF: case ES: case FM: case MD: case NO: case LR: case NP: case CE: case ND: case PM: case SM: case EU: case GD: case TB: case DY: case HO: case ER: case TM: case YB: case LU: case PR: case WILDCARD: case h: case a: case A: case D: case R: case r: case v: case X: case x: case G: case HX: case CARET: case DOLLAR: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: case 164: ImplicitHighAndExpression(); break; default: jj_la1[25] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void NotExpression() throws ParseException { /*@bgen(jjtree) NotExpression */ ASTNotExpression jjtn000 = new ASTNotExpression(JJTNOTEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);jjtn000.setType(SMARTSParserConstants.DEFAULT); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NOT: jj_consume_token(NOT); jjtn000.setType(SMARTSParserConstants.NOT); break; default: jj_la1[26] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S_BOND: case T_BOND: case R_BOND: case c: case n: case o: case s: case p: case as: case se: case H: case HE: case LI: case BE: case B: case C: case N: case O: case F: case NE: case NA: case MG: case AL: case SI: case P: case S: case CL: case AR: case K: case CA: case SC: case TI: case V: case CR: case MN: case FE: case CO: case NI: case CU: case ZN: case GA: case GE: case AS: case SE: case BR: case KR: case RB: case SR: case Y: case ZR: case NB: case MO: case TC: case RU: case RH: case PD: case AG: case CD: case IN: case SN: case SB: case TE: case I: case XE: case CS: case BA: case LA: case HF: case TA: case W: case RE: case OS: case IR: case PT: case AU: case HG: case TL: case PB: case BI: case PO: case AT: case RN: case FR: case RA: case AC: case TH: case PA: case U: case PU: case AM: case CM: case BK: case CF: case ES: case FM: case MD: case NO: case LR: case NP: case CE: case ND: case PM: case SM: case EU: case GD: case TB: case DY: case HO: case ER: case TM: case YB: case LU: case PR: case WILDCARD: case h: case a: case A: case D: case R: case r: case v: case X: case x: case G: case HX: case CARET: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: case 164: PrimitiveAtomExpression(); break; case DOLLAR: RecursiveSmartsExpression(); break; default: jj_la1[27] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void RecursiveSmartsExpression() throws ParseException { /*@bgen(jjtree) RecursiveSmartsExpression */ ASTRecursiveSmartsExpression jjtn000 = new ASTRecursiveSmartsExpression(JJTRECURSIVESMARTSEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(DOLLAR); jj_consume_token(L_PAREN); SmartsExpression(); jj_consume_token(R_PAREN); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void PrimitiveAtomExpression() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case c: case n: case o: case s: case p: case as: case se: case HE: case LI: case BE: case B: case C: case N: case O: case F: case NE: case NA: case MG: case AL: case SI: case P: case S: case CL: case AR: case K: case CA: case SC: case TI: case V: case CR: case MN: case FE: case CO: case NI: case CU: case ZN: case GA: case GE: case AS: case SE: case BR: case KR: case RB: case SR: case Y: case ZR: case NB: case MO: case TC: case RU: case RH: case PD: case AG: case CD: case IN: case SN: case SB: case TE: case I: case XE: case CS: case BA: case LA: case HF: case TA: case W: case RE: case OS: case IR: case PT: case AU: case HG: case TL: case PB: case BI: case PO: case AT: case RN: case FR: case RA: case AC: case TH: case PA: case U: case PU: case AM: case CM: case BK: case CF: case ES: case FM: case MD: case NO: case LR: case NP: case CE: case ND: case PM: case SM: case EU: case GD: case TB: case DY: case HO: case ER: case TM: case YB: case LU: case PR: NoHydrogenElement(); break; case WILDCARD: AnyAtom(); break; case a: Aromatic(); break; case A: Aliphatic(); break; case D: ExplicitConnectivity(); break; case H: TotalHCount(); break; case h: ImplicitHCount(); break; case R: RingMembership(); break; case r: SmallestRingSize(); break; case v: Valence(); break; case X: TotalConnectivity(); break; case x: RingConnectivity(); break; case S_BOND: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: Charge(); break; case T_BOND: AtomicNumber(); break; case R_BOND: case 164: Chirality(); break; case G: PeriodicGroupNumber(); break; case HX: NonCHHeavyAtom(); break; case CARET: HybridizationNumber(); break; default: jj_la1[28] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } final public void TotalHCount() throws ParseException { /*@bgen(jjtree) TotalHCount */ ASTTotalHCount jjtn000 = new ASTTotalHCount(JJTTOTALHCOUNT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(H); jjtn000.setCount(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_3: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[29] = jj_gen; break label_3; } } jjtn000.setCount( Integer.parseInt(digits.toString()) ); break; default: jj_la1[30] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ImplicitHCount() throws ParseException { /*@bgen(jjtree) ImplicitHCount */ ASTImplicitHCount jjtn000 = new ASTImplicitHCount(JJTIMPLICITHCOUNT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(h); jjtn000.setCount(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_4: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[31] = jj_gen; break label_4; } } jjtn000.setCount( Integer.parseInt(digits.toString()) ); break; default: jj_la1[32] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ExplicitConnectivity() throws ParseException { /*@bgen(jjtree) ExplicitConnectivity */ ASTExplicitConnectivity jjtn000 = new ASTExplicitConnectivity(JJTEXPLICITCONNECTIVITY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(D); jjtn000.setNumOfConnection(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_5: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[33] = jj_gen; break label_5; } } jjtn000.setNumOfConnection( Integer.parseInt(digits.toString()) ); break; default: jj_la1[34] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void AtomicNumber() throws ParseException { /*@bgen(jjtree) AtomicNumber */ ASTAtomicNumber jjtn000 = new ASTAtomicNumber(JJTATOMICNUMBER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(T_BOND); label_6: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[35] = jj_gen; break label_6; } } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setNumber( Integer.parseInt(digits.toString()) ); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void HybridizationNumber() throws ParseException { /*@bgen(jjtree) HybrdizationNumber */ ASTHybrdizationNumber jjtn000 = new ASTHybrdizationNumber(JJTHYBRDIZATIONNUMBER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(CARET); jj_consume_token(DIGIT); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; int tmp = Integer.parseInt(token.image); if (tmp < 1 || tmp > 8) {if (true) throw new ParseException("Hybridization number must be between 1 & 8");} jjtn000.setHybridizationNumber(tmp); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Charge() throws ParseException { /*@bgen(jjtree) Charge */ ASTCharge jjtn000 = new ASTCharge(JJTCHARGE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { if (jj_2_2(2)) { jj_consume_token(149); jjtn000.setPositive(true); jjtn000.setCharge(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_7: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[36] = jj_gen; break label_7; } } jjtn000.setCharge( Integer.parseInt(digits.toString()) ); break; default: jj_la1[37] = jj_gen; ; } } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S_BOND: jj_consume_token(S_BOND); jjtn000.setPositive(false); jjtn000.setCharge(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_8: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[38] = jj_gen; break label_8; } } jjtn000.setCharge( Integer.parseInt(digits.toString()) ); break; default: jj_la1[39] = jj_gen; ; } break; case 150: jj_consume_token(150); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(2); break; case 151: jj_consume_token(151); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(3); break; case 152: jj_consume_token(152); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(4); break; case 153: jj_consume_token(153); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(5); break; case 154: jj_consume_token(154); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(6); break; case 155: jj_consume_token(155); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(7); break; case 156: jj_consume_token(156); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(false); jjtn000.setCharge(8); break; case 157: jj_consume_token(157); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(2); break; case 158: jj_consume_token(158); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(3); break; case 159: jj_consume_token(159); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(4); break; case 160: jj_consume_token(160); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(5); break; case 161: jj_consume_token(161); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(6); break; case 162: jj_consume_token(162); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(7); break; case 163: jj_consume_token(163); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setPositive(true); jjtn000.setCharge(8); break; default: jj_la1[40] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void RingConnectivity() throws ParseException { /*@bgen(jjtree) RingConnectivity */ ASTRingConnectivity jjtn000 = new ASTRingConnectivity(JJTRINGCONNECTIVITY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(x); jjtn000.setNumOfConnection(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_9: while (true) { jj_consume_token(DIGIT); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[41] = jj_gen; break label_9; } } jjtn000.setNumOfConnection( Integer.parseInt(token.image) ); break; default: jj_la1[42] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void PeriodicGroupNumber() throws ParseException, ParseException { /*@bgen(jjtree) PeriodicGroupNumber */ ASTPeriodicGroupNumber jjtn000 = new ASTPeriodicGroupNumber(JJTPERIODICGROUPNUMBER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(G); label_10: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[43] = jj_gen; break label_10; } } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; int tmpInt = Integer.parseInt(digits.toString()); if (tmpInt < 1 || tmpInt > 18) {if (true) throw new ParseException("Invalid group number");} jjtn000.setGroupNumber( Integer.parseInt(digits.toString()) ); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void TotalConnectivity() throws ParseException { /*@bgen(jjtree) TotalConnectivity */ ASTTotalConnectivity jjtn000 = new ASTTotalConnectivity(JJTTOTALCONNECTIVITY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(X); jjtn000.setNumOfConnection(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_11: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[44] = jj_gen; break label_11; } } jjtn000.setNumOfConnection( Integer.parseInt(digits.toString()) ); break; default: jj_la1[45] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Valence() throws ParseException { /*@bgen(jjtree) Valence */ ASTValence jjtn000 = new ASTValence(JJTVALENCE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(v); jjtn000.setOrder(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_12: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[46] = jj_gen; break label_12; } } jjtn000.setOrder( Integer.parseInt(digits.toString()) ); break; default: jj_la1[47] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void RingMembership() throws ParseException { /*@bgen(jjtree) RingMembership */ ASTRingMembership jjtn000 = new ASTRingMembership(JJTRINGMEMBERSHIP); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(R); jjtn000.setNumOfMembership(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_13: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[48] = jj_gen; break label_13; } } jjtn000.setNumOfMembership( Integer.parseInt(digits.toString()) ); break; default: jj_la1[49] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void SmallestRingSize() throws ParseException { /*@bgen(jjtree) SmallestRingSize */ ASTSmallestRingSize jjtn000 = new ASTSmallestRingSize(JJTSMALLESTRINGSIZE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { jj_consume_token(r); jjtn000.setSize(1); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_14: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[50] = jj_gen; break label_14; } } jjtn000.setSize( Integer.parseInt(digits.toString()) ); break; default: jj_la1[51] = jj_gen; ; } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Aliphatic() throws ParseException { /*@bgen(jjtree) Aliphatic */ ASTAliphatic jjtn000 = new ASTAliphatic(JJTALIPHATIC); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(A); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void NonCHHeavyAtom() throws ParseException { /*@bgen(jjtree) NonCHHeavyAtom */ ASTNonCHHeavyAtom jjtn000 = new ASTNonCHHeavyAtom(JJTNONCHHEAVYATOM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(HX); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Aromatic() throws ParseException { /*@bgen(jjtree) Aromatic */ ASTAromatic jjtn000 = new ASTAromatic(JJTAROMATIC); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(a); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void AnyAtom() throws ParseException { /*@bgen(jjtree) AnyAtom */ ASTAnyAtom jjtn000 = new ASTAnyAtom(JJTANYATOM); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(WILDCARD); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void AtomicMass() throws ParseException { /*@bgen(jjtree) AtomicMass */ ASTAtomicMass jjtn000 = new ASTAtomicMass(JJTATOMICMASS); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { label_15: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[52] = jj_gen; break label_15; } } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setMass( Integer.parseInt(digits.toString()) ); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void RingIdentifier() throws ParseException { /*@bgen(jjtree) RingIdentifier */ ASTRingIdentifier jjtn000 = new ASTRingIdentifier(JJTRINGIDENTIFIER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { LowAndBond(); jj_consume_token(DIGIT); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Chirality() throws ParseException { /*@bgen(jjtree) Chirality */ ASTChirality jjtn000 = new ASTChirality(JJTCHIRALITY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);StringBuffer digits = new StringBuffer(); try { if (jj_2_3(2)) { jj_consume_token(R_BOND); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setClockwise(true); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 164: jj_consume_token(164); jjtn000.setClockwise(false); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: label_16: while (true) { jj_consume_token(DIGIT); digits.append(token.image); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DIGIT: ; break; default: jj_la1[53] = jj_gen; break label_16; } } jjtn000.setDegree( Integer.parseInt(digits.toString()) ); break; default: jj_la1[54] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case Q_MARK: jj_consume_token(Q_MARK); jjtn000.setUnspecified(true); break; default: jj_la1[55] = jj_gen; ; } break; default: jj_la1[56] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void NoHydrogenElement() throws ParseException { /*@bgen(jjtree) Element */ ASTElement jjtn000 = new ASTElement(JJTELEMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case HE: jj_consume_token(HE); break; case LI: jj_consume_token(LI); break; case BE: jj_consume_token(BE); break; case NE: jj_consume_token(NE); break; case NA: jj_consume_token(NA); break; case MG: jj_consume_token(MG); break; case AL: jj_consume_token(AL); break; case SI: jj_consume_token(SI); break; case AR: jj_consume_token(AR); break; case CA: jj_consume_token(CA); break; case SC: jj_consume_token(SC); break; case TI: jj_consume_token(TI); break; case CR: jj_consume_token(CR); break; case MN: jj_consume_token(MN); break; case FE: jj_consume_token(FE); break; case CO: jj_consume_token(CO); break; case NI: jj_consume_token(NI); break; case CU: jj_consume_token(CU); break; case ZN: jj_consume_token(ZN); break; case GA: jj_consume_token(GA); break; case GE: jj_consume_token(GE); break; case AS: jj_consume_token(AS); break; case SE: jj_consume_token(SE); break; case BR: jj_consume_token(BR); break; case KR: jj_consume_token(KR); break; case RB: jj_consume_token(RB); break; case SR: jj_consume_token(SR); break; case ZR: jj_consume_token(ZR); break; case NB: jj_consume_token(NB); break; case MO: jj_consume_token(MO); break; case TC: jj_consume_token(TC); break; case RU: jj_consume_token(RU); break; case RH: jj_consume_token(RH); break; case PD: jj_consume_token(PD); break; case AG: jj_consume_token(AG); break; case CD: jj_consume_token(CD); break; case IN: jj_consume_token(IN); break; case SN: jj_consume_token(SN); break; case SB: jj_consume_token(SB); break; case TE: jj_consume_token(TE); break; case XE: jj_consume_token(XE); break; case CS: jj_consume_token(CS); break; case BA: jj_consume_token(BA); break; case LA: jj_consume_token(LA); break; case HF: jj_consume_token(HF); break; case TA: jj_consume_token(TA); break; case W: jj_consume_token(W); break; case RE: jj_consume_token(RE); break; case OS: jj_consume_token(OS); break; case IR: jj_consume_token(IR); break; case PT: jj_consume_token(PT); break; case AU: jj_consume_token(AU); break; case HG: jj_consume_token(HG); break; case TL: jj_consume_token(TL); break; case PB: jj_consume_token(PB); break; case BI: jj_consume_token(BI); break; case PO: jj_consume_token(PO); break; case AT: jj_consume_token(AT); break; case RN: jj_consume_token(RN); break; case FR: jj_consume_token(FR); break; case RA: jj_consume_token(RA); break; case AC: jj_consume_token(AC); break; case TH: jj_consume_token(TH); break; case PA: jj_consume_token(PA); break; case CL: jj_consume_token(CL); break; case B: jj_consume_token(B); break; case C: jj_consume_token(C); break; case N: jj_consume_token(N); break; case O: jj_consume_token(O); break; case F: jj_consume_token(F); break; case P: jj_consume_token(P); break; case S: jj_consume_token(S); break; case K: jj_consume_token(K); break; case V: jj_consume_token(V); break; case Y: jj_consume_token(Y); break; case I: jj_consume_token(I); break; case U: jj_consume_token(U); break; case c: jj_consume_token(c); break; case o: jj_consume_token(o); break; case n: jj_consume_token(n); break; case s: jj_consume_token(s); break; case p: jj_consume_token(p); break; case as: jj_consume_token(as); break; case se: jj_consume_token(se); break; case PU: jj_consume_token(PU); break; case AM: jj_consume_token(AM); break; case CM: jj_consume_token(CM); break; case BK: jj_consume_token(BK); break; case CF: jj_consume_token(CF); break; case ES: jj_consume_token(ES); break; case FM: jj_consume_token(FM); break; case MD: jj_consume_token(MD); break; case NO: jj_consume_token(NO); break; case LR: jj_consume_token(LR); break; case NP: jj_consume_token(NP); break; case CE: jj_consume_token(CE); break; case ND: jj_consume_token(ND); break; case PM: jj_consume_token(PM); break; case SM: jj_consume_token(SM); break; case EU: jj_consume_token(EU); break; case GD: jj_consume_token(GD); break; case TB: jj_consume_token(TB); break; case DY: jj_consume_token(DY); break; case HO: jj_consume_token(HO); break; case ER: jj_consume_token(ER); break; case TM: jj_consume_token(TM); break; case YB: jj_consume_token(YB); break; case LU: jj_consume_token(LU); break; case PR: jj_consume_token(PR); break; default: jj_la1[57] = jj_gen; jj_consume_token(-1); throw new ParseException(); } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setSymbol(token.image); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final private boolean jj_2_1(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_1(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(0, xla); } } final private boolean jj_2_2(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_2(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(1, xla); } } final private boolean jj_2_3(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_3(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(2, xla); } } final private boolean jj_3_2() { if (jj_scan_token(149)) return true; Token xsp; xsp = jj_scanpos; if (jj_3R_17()) jj_scanpos = xsp; return false; } final private boolean jj_3_3() { if (jj_scan_token(R_BOND)) return true; return false; } final private boolean jj_3R_18() { if (jj_scan_token(DIGIT)) return true; return false; } final private boolean jj_3R_17() { Token xsp; if (jj_3R_18()) return true; while (true) { xsp = jj_scanpos; if (jj_3R_18()) { jj_scanpos = xsp; break; } } return false; } final private boolean jj_3_1() { if (jj_scan_token(S_BOND)) return true; return false; } public SMARTSParserTokenManager token_source; SimpleCharStream jj_input_stream; public Token token, jj_nt; private int jj_ntk; private Token jj_scanpos, jj_lastpos; private int jj_la; public boolean lookingAhead = false; private boolean jj_semLA; private int jj_gen; final private int[] jj_la1 = new int[58]; static private int[] jj_la1_0; static private int[] jj_la1_1; static private int[] jj_la1_2; static private int[] jj_la1_3; static private int[] jj_la1_4; static private int[] jj_la1_5; static { jj_la1_0(); jj_la1_1(); jj_la1_2(); jj_la1_3(); jj_la1_4(); jj_la1_5(); } private static void jj_la1_0() { jj_la1_0 = new int[] {0xf87f0000,0x0,0xf87f0000,0x0,0x0,0x0,0x0,0x0,0xf87fffe0,0xffe0,0xf87f0000,0xffe0,0xf87fffe0,0x0,0xf87f0000,0x4,0x10,0x8,0xffe0,0x20,0xff80,0xf87f0000,0x4,0x10,0x8,0xffff9060,0x20,0xffff9040,0xffff9040,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff7f0000,}; } private static void jj_la1_1() { jj_la1_1 = new int[] {0x20000e0,0x0,0x20000e0,0x0,0x0,0x0,0x0,0x0,0x20000e0,0x0,0x20000e0,0x0,0x20000e0,0x0,0x20000e0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000e0,0x0,0x0,0x0,0xffffffff,0x0,0xffffffff,0xffffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffffffff,}; } private static void jj_la1_2() { jj_la1_2 = new int[] {0x800,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x800,0x0,0x800,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0xffffffff,0x0,0xffffffff,0xffffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffffffff,}; } private static void jj_la1_3() { jj_la1_3 = new int[] {0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x40000000,0x0,0x40000000,0x0,0x40000000,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x40000000,0x0,0x0,0x0,0xffffffff,0x0,0xffffffff,0xffffffff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3fffffff,}; } private static void jj_la1_4() { jj_la1_4 = new int[] {0x5003,0x40000,0xc5003,0x1000,0x2000,0x100000,0x1000,0x2000,0x25003,0x0,0x24003,0x0,0x25003,0x20000,0x4003,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0xffe00fff,0x0,0xffe00fff,0xffe007ff,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0xffc00000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x20000,0x10000,0x0,0x0,}; } private static void jj_la1_5() { jj_la1_5 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f,0x0,0x1f,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,}; } final private JJCalls[] jj_2_rtns = new JJCalls[3]; private boolean jj_rescan = false; private int jj_gc = 0; public SMARTSParser(java.io.InputStream stream) { jj_input_stream = new SimpleCharStream(stream, 1, 1); token_source = new SMARTSParserTokenManager(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } public void ReInit(java.io.InputStream stream) { jj_input_stream.ReInit(stream, 1, 1); token_source.ReInit(jj_input_stream); token = new Token(); jj_ntk = -1; jjtree.reset(); jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } public SMARTSParser(java.io.Reader stream) { jj_input_stream = new SimpleCharStream(stream, 1, 1); token_source = new SMARTSParserTokenManager(jj_input_stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } public void ReInit(java.io.Reader stream) { jj_input_stream.ReInit(stream, 1, 1); token_source.ReInit(jj_input_stream); token = new Token(); jj_ntk = -1; jjtree.reset(); jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } public SMARTSParser(SMARTSParserTokenManager tm) { token_source = tm; token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } public void ReInit(SMARTSParserTokenManager tm) { token_source = tm; token = new Token(); jj_ntk = -1; jjtree.reset(); jj_gen = 0; for (int i = 0; i < 58; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } final private Token jj_consume_token(int kind) throws ParseException { Token oldToken; if ((oldToken = token).next != null) token = token.next; else token = token.next = token_source.getNextToken(); jj_ntk = -1; if (token.kind == kind) { jj_gen++; if (++jj_gc > 100) { jj_gc = 0; for (int i = 0; i < jj_2_rtns.length; i++) { JJCalls c = jj_2_rtns[i]; while (c != null) { if (c.gen < jj_gen) c.first = null; c = c.next; } } } return token; } token = oldToken; jj_kind = kind; throw generateParseException(); } static private final class LookaheadSuccess extends java.lang.Error { } final private LookaheadSuccess jj_ls = new LookaheadSuccess(); final private boolean jj_scan_token(int kind) { if (jj_scanpos == jj_lastpos) { jj_la--; if (jj_scanpos.next == null) { jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); } else { jj_lastpos = jj_scanpos = jj_scanpos.next; } } else { jj_scanpos = jj_scanpos.next; } if (jj_rescan) { int i = 0; Token tok = token; while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } if (tok != null) jj_add_error_token(kind, i); } if (jj_scanpos.kind != kind) return true; if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; return false; } final public Token getNextToken() { if (token.next != null) token = token.next; else token = token.next = token_source.getNextToken(); jj_ntk = -1; jj_gen++; return token; } final public Token getToken(int index) { Token t = lookingAhead ? jj_scanpos : token; for (int i = 0; i < index; i++) { if (t.next != null) t = t.next; else t = t.next = token_source.getNextToken(); } return t; } final private int jj_ntk() { if ((jj_nt=token.next) == null) return (jj_ntk = (token.next=token_source.getNextToken()).kind); else return (jj_ntk = jj_nt.kind); } private java.util.Vector jj_expentries = new java.util.Vector(); private int[] jj_expentry; private int jj_kind = -1; private int[] jj_lasttokens = new int[100]; private int jj_endpos; private void jj_add_error_token(int kind, int pos) { if (pos >= 100) return; if (pos == jj_endpos + 1) { jj_lasttokens[jj_endpos++] = kind; } else if (jj_endpos != 0) { jj_expentry = new int[jj_endpos]; for (int i = 0; i < jj_endpos; i++) { jj_expentry[i] = jj_lasttokens[i]; } boolean exists = false; for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) { int[] oldentry = (int[])(e.nextElement()); if (oldentry.length == jj_expentry.length) { exists = true; for (int i = 0; i < jj_expentry.length; i++) { if (oldentry[i] != jj_expentry[i]) { exists = false; break; } } if (exists) break; } } if (!exists) jj_expentries.addElement(jj_expentry); if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; } } public ParseException generateParseException() { jj_expentries.removeAllElements(); boolean[] la1tokens = new boolean[165]; for (int i = 0; i < 165; i++) { la1tokens[i] = false; } if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; } for (int i = 0; i < 58; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1<<j)) != 0) { la1tokens[j] = true; } if ((jj_la1_1[i] & (1<<j)) != 0) { la1tokens[32+j] = true; } if ((jj_la1_2[i] & (1<<j)) != 0) { la1tokens[64+j] = true; } if ((jj_la1_3[i] & (1<<j)) != 0) { la1tokens[96+j] = true; } if ((jj_la1_4[i] & (1<<j)) != 0) { la1tokens[128+j] = true; } if ((jj_la1_5[i] & (1<<j)) != 0) { la1tokens[160+j] = true; } } } } for (int i = 0; i < 165; i++) { if (la1tokens[i]) { jj_expentry = new int[1]; jj_expentry[0] = i; jj_expentries.addElement(jj_expentry); } } jj_endpos = 0; jj_rescan_token(); jj_add_error_token(0, 0); int[][] exptokseq = new int[jj_expentries.size()][]; for (int i = 0; i < jj_expentries.size(); i++) { exptokseq[i] = (int[])jj_expentries.elementAt(i); } return new ParseException(token, exptokseq, tokenImage); } final public void enable_tracing() { } final public void disable_tracing() { } final private void jj_rescan_token() { jj_rescan = true; for (int i = 0; i < 3; i++) { JJCalls p = jj_2_rtns[i]; do { if (p.gen > jj_gen) { jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; switch (i) { case 0: jj_3_1(); break; case 1: jj_3_2(); break; case 2: jj_3_3(); break; } } p = p.next; } while (p != null); } jj_rescan = false; } final private void jj_save(int index, int xla) { JJCalls p = jj_2_rtns[index]; while (p.gen > jj_gen) { if (p.next == null) { p = p.next = new JJCalls(); break; } p = p.next; } p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; } static final class JJCalls { int gen; Token first; int arg; JJCalls next; } }