📄 nomparser.java
字号:
/* Generated By:JavaCC: Do not edit this line. NomParser.java *//* * Copyright (C) 2003-2007 University of Manchester * * 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.iupac.parser;import java.io.StringReader;import org.openscience.cdk.Molecule;import org.openscience.cdk.exception.*;import java.util.*;/** * A class partly generated by <a href="http://javacc.dev.java.net" target="_top">JavaCC</a> which breaks down the chemical name * into computable subparts and passes these parts to the MoleculeBuilder. * * @author David Robinson (University of Manchester) * @author Bhupinder Sandhu * @author Stephen Tomkinson * * @cdk.keyword IUPAC name */public class NomParser implements NomParserConstants { //private variables needed throughout the program private static int mainChainPrefix; private static boolean isMainCyclic; /** The tempory vector of locations the current group/substiuant is attached to */ private static Vector tempLocation; /** The vector of attached functional groups, with an instance of AttachedGroup for each * functional group. */ private static Vector attachedGroups; /** The vector of attached substituent, with an instance of AttachedGroup for each * substituent. */ private static Vector attachedSubstituents; /** * Used in the build up of ancient greek style prfixes */ private static int currentNumber; /** * Parses the chemical name and returns the built molecule. * * @param stringToParse A case-insensitive name of the chemical to build. * @return A molecule which represents the interpretatation of the name. * @throws ParseException Any error which occur in the parsing get wrapped * up in a ParseException and thrown. */ public static Molecule generate (String stringToParse) throws ParseException, CDKException { isMainCyclic = false; tempLocation = new Vector(); attachedSubstituents = new Vector(); attachedGroups = new Vector(); currentNumber = 0; StringReader stringReader = new StringReader (stringToParse.toLowerCase() + "\n"); NomParser parser = new NomParser (stringReader); parser.completeChemicalName(); //Scan substituents for a too high connection point checkConnections (attachedSubstituents.iterator()); //Scan functional groups for a too high connection point checkConnections (attachedGroups.iterator()); MoleculeBuilder moleculeBuilder = new MoleculeBuilder(); Molecule returnedMolecule = moleculeBuilder.buildMolecule(mainChainPrefix, attachedSubstituents, attachedGroups, isMainCyclic, stringToParse); return returnedMolecule; } /** * Checks to ensure that all groups/substituents attached to the main chain * are connected to a valid atom which occurs on the main chain. * * @param vectorIterator An iterator which provides instances of AttachedGroup to check * @throws ParseException A taylored instance of ParseException so nomen can display * the error to the user. */ private static void checkConnections (Iterator vectorIterator) throws ParseException { while (vectorIterator.hasNext()) { AttachedGroup ag = (AttachedGroup) vectorIterator.next(); Vector locations = ag.getLocations(); Iterator locationsIterator = locations.iterator(); while (locationsIterator.hasNext()) { Token tok = (Token) locationsIterator.next(); try { if (Integer.parseInt(tok.image) > mainChainPrefix) { //Create a tiny 2D array with a single slot for data, //insert 0 into it as as to reference the first slot in the stringArray int [][] intArray = new int [1][1]; intArray [0][0] = 0; //Put useful message in stringArray String [] stringArray = new String [1]; stringArray [0] = " MUST BE BELOW " + (mainChainPrefix + 1) + " "; tok.next = tok; throw new ParseException (tok, intArray, stringArray); } } catch (NumberFormatException nfe) { //Do nothing, as this should never happen } } } }/** * Stores "head tokens", the substituent prefix, in a vector of AttachedGroup objects. */ void AddHeadToken() throws ParseException { attachedSubstituents.add (new AttachedGroup (tempLocation, currentNumber) ); tempLocation = new Vector(); } void MakeMainChainIntoSubstituent() throws ParseException { attachedSubstituents.add (new AttachedGroup (tempLocation, mainChainPrefix) ); currentNumber = 0; mainChainPrefix = 0; tempLocation = new Vector(); }/** * Stores the functional groups in a vector of AttachedGroup objects. */ void AddFunGroup() throws ParseException { Token tok; tok = getToken(-1); attachedGroups.add (new AttachedGroup (tempLocation, tok.image) ); tempLocation = new Vector(); }/*** Stores the functional group positions, the number of the atom they * connect to, in an array.*/ void AddFunGroupPos() throws ParseException { Token tok; tok = getToken(-1); tempLocation.add(tok); }/*** Adds to the position array a location of -1 to indicate no location was* specified.*/ void AddUnknownFunGroupPos() throws ParseException { Token tok = new Token(); tok.image = "-1"; tempLocation.add(tok); }/** * Store the mainChainPrefix token, the chain prefix of the longest carbon chain */ void AddMainChain() throws ParseException { mainChainPrefix = currentNumber; currentNumber = 0; }/** * Sets the main chain to be cyclic. */ void SetMainCyclic() throws ParseException { isMainCyclic = true; }/** * The general form all chemical names must follow. */ final public void completeChemicalName() throws ParseException { if (jj_2_1(2)) { mainChainConstruct(); } else { prefixConstruct(); mainChainConstruct(); jj_consume_token(EOL); } }/** * Allows 1 or more prefixes */ final public void prefixConstruct() throws ParseException { prefixType(); label_1: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DASH: ; break; default: jj_la1[0] = jj_gen; break label_1; } jj_consume_token(DASH); prefixType(); } } final public void prefixType() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case CONSTANT: attachLocationSpecified(); break; default: jj_la1[1] = jj_gen; AddUnknownFunGroupPos(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case METH: case ETH: case PROP: case BUT: case UNDEC: case EICOS: case HENICOS: case HEN: case DO: case TRI: case TETR: case PENT: case HEX: case HEPT: case OCT: case NON: case DEC: subChain(); break; case CHLORO: case FLUORO: case BROMO: case IODO: case NITRO: case OXO: case PHENYL: case AMINO: case HYDROXY: functionalGroupPrefix(); break; default: jj_la1[2] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** The substituent part of the prefix */ final public void subChain() throws ParseException { chainPrefix(); AddHeadToken(); jj_consume_token(YL); }/** * An attach position has been specified using a * comma seperated list followed by a dash */ final public void attachLocationSpecified() throws ParseException { jj_consume_token(CONSTANT); AddFunGroupPos(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DASH: oneAttachLocation(); break; case COMMA: twoOrThreeAttachLocations(); break; default: jj_la1[3] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** * Only one attach location specified, should be followed by a dash. */ final public void oneAttachLocation() throws ParseException { jj_consume_token(DASH); }/** * Two or three attach locations specidied, handle the second and if needed, the third one here. */ final public void twoOrThreeAttachLocations() throws ParseException { jj_consume_token(COMMA); jj_consume_token(CONSTANT); AddFunGroupPos(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DASH: jj_consume_token(DASH); jj_consume_token(DI); break; case COMMA: jj_consume_token(COMMA); jj_consume_token(CONSTANT); AddFunGroupPos(); jj_consume_token(DASH); jj_consume_token(TRI); break; default: jj_la1[4] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** * A list of known tokens denoting a chain's length. */ final public void chainPrefix() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case METH: case ETH: case PROP: case BUT: case UNDEC: case EICOS: case HENICOS: case DEC: specialCase(); break; case HEN: case DO: case TRI: case TETR: case PENT: case HEX: case HEPT: case OCT: case NON: allBaseNumbers(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case HEN: case DO: case TRI: case TETR: case PENT: case HEX: case HEPT: case OCT: case NON: case DEC: case COS: case CONT: switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case HEN: case DO: case TRI: case TETR: case PENT: case HEX: case HEPT: case OCT: case NON: tensWithUnits(); break; case DEC: case COS: case CONT: tensNoUnits(); break; default: jj_la1[5] = jj_gen; jj_consume_token(-1); throw new ParseException(); } break; default: jj_la1[6] = jj_gen; ; } break; default: jj_la1[7] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** Deal with special cases where the rules don't apply. */ final public void specialCase() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case METH: jj_consume_token(METH); currentNumber = 1; break; case ETH: jj_consume_token(ETH); currentNumber = 2; break; case PROP: jj_consume_token(PROP); currentNumber = 3; break; case BUT: jj_consume_token(BUT); currentNumber = 4; break; case DEC: jj_consume_token(DEC); currentNumber = 10; break; case UNDEC: jj_consume_token(UNDEC); currentNumber = 11; break; case EICOS: jj_consume_token(EICOS); currentNumber = 20; break; case HENICOS: jj_consume_token(HENICOS); currentNumber = 21; break; default: jj_la1[8] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** The usual numbers .*/ final public void allBaseNumbers() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case HEN: jj_consume_token(HEN); currentNumber = 1; break; case DO: jj_consume_token(DO); currentNumber = 2; break; case TRI: jj_consume_token(TRI); currentNumber = 3; break; case TETR: jj_consume_token(TETR); currentNumber = 4; break; case PENT: jj_consume_token(PENT); currentNumber = 5; break; case HEX: jj_consume_token(HEX); currentNumber = 6; break; case HEPT: jj_consume_token(HEPT); currentNumber = 7; break; case OCT: jj_consume_token(OCT); currentNumber = 8; break; case NON: jj_consume_token(NON); currentNumber = 9; break; default: jj_la1[9] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** Deal with fragments refering to the positioning of the base numbers (denoting their magnitude) */ final public void tensNoUnits() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case DEC: jj_consume_token(DEC); currentNumber += 10; break; case COS: jj_consume_token(COS); currentNumber += 20; break; case CONT: jj_consume_token(CONT); currentNumber *= 10; break; default: jj_la1[10] = jj_gen; jj_consume_token(-1); throw new ParseException(); } }/** * Deals with numbers above 30 where the base numbers set appear twice. * For example, in the tens and the units. */ final public void tensWithUnits() throws ParseException { int tempBackup; tempBackup = currentNumber; allBaseNumbers(); jj_consume_token(CONT); currentNumber *= 10; currentNumber += tempBackup; }/** The functional group part of the prefix */ final public void functionalGroupPrefix() throws ParseException { prefixFunctionalGroups(); AddFunGroup(); }/** * Main chains are compulsary and consist of an optional "cyclo", a length prefix and * a posfix denoting functional groups. */ final public void mainChainConstruct() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case CYCLO: cycle(); break; default: jj_la1[11] = jj_gen; ; } mainChainPrefix(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case YL: jj_consume_token(YL); AddUnknownFunGroupPos(); MakeMainChainIntoSubstituent(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LITHIUM: case SODIUM: case POTASSIUM: case RUBIDIUM: case CESIUM: case FRANCIUM: case BERYLLIUM: case MAGNESIUM: case CALCIUM: case STRONTIUM: case BARIUM: case RADIUM: case SCANDIUM: case YTTRIUM: case LANTHANUM: case ACTINIUM: case TITANIUM: case ZIRCONIUM: case HAFNIUM: case RUTHERFORDIUM: case VANADIUM: case NIOBIUM: case TANTALUM: case DUBNIUM: case CHROMIUM: case MOLYBDENUM: case TUNGSTEN: case SEABORGIUM: case MANGANESE: case TECHNETIUM: case RHENIUM: case BOHRIUM: case IRON: case RUTHENIUM: case OSMIUM: case HASSIUM: case COBALT: case RHODIUM: case IRIDIUM: case MEITMERIUM: case NICKEL: case PALLADIUM: case PLATINUM: case COPPER: case SILVER: case GOLD: case ZINC: case CADMIUM: case MECURY: case ALUMINIUM: case GALLIUM: case INDIUM: case THALLIUM: case GERMAINIUM: case TIN: case LEAD: case ARSENIC: case ANTIMONY: case BISMUTH: case SELENIUM: case TELLURIUM: case POLONIUM: case CERIUM: case PRASEODYMIUM: case NEODYMIUM: case PROMETHIUM: case SANARIUM: case EUROPIUM: case GADOLINIUM:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -