public TokenizedExpression Tokenize(StringExpression exp) { TokenizedExpression ret = new TokenizedExpression(); ret.FunctionalGpTokens = exp.FunctionalGpTokens.Select((str) => { if (Regex.IsMatch(str, @"^\d+$")) { return(new Token(Operators.number, int.Parse(str))); } else { return(new Token(dictAllFunctionalGps[str], 0)); } }).ToList(); ret.ParentChainTokens = exp.ParentChainTokens.Select((str) => { return(new Token(dictAllParentChain[str], 0)); }).ToList(); ret.TailTokens = exp.TailTokens.Select((str) => { if (Regex.IsMatch(str, @"^\d+$")) { return(new Token(Operators.number, int.Parse(str))); } else { return(new Token(dictAllTail[str], 0)); } }).ToList(); return(ret); }
public void FromName(string name) { StringExpression exp = Lexer(name); TokenizedExpression texp = Tokenize(exp); GetRawMolecule(texp); FixMolecule(); }
public Molecule GetRawMolecule(TokenizedExpression exp) { //Make parent chain List <Node> parentChain = new List <Node>(); List <Bond> parentChainBonds = new List <Bond>(); for (int i = 0; i < (int)exp.ParentChainTokens[0].Type; i++) { Node tmp = new Node(Elements.Carbon); Nodes.Add(tmp); parentChain.Add(tmp); } for (int i = 0; i < parentChain.Count - 1; i++) { Bond tmp = new Bond(parentChain[i], parentChain[i + 1], BondType.Single, Orientation.Horizontal); parentChainBonds.Add(tmp); Bonds.Add(tmp); } //make bonds int mode = 0; List <int> numbers = new List <int>(); int engPreNum = 0; bool ignoreHyphen = true; for (int i = 0; i < exp.TailTokens.Count; i++) { Token t = exp.TailTokens[i]; if (mode == 0) { Operators op; Suffixes suffix; EngPrefixes engPre; if (t.Type is Operators) { op = (Operators)t.Type; if (op == Operators.number) { numbers.Add(t.data); } else if (op == Operators.comma) { } else if (op == Operators.hyphen && !ignoreHyphen) { mode = 1; } } else if (t.Type is EngPrefixes) { engPre = (EngPrefixes)t.Type; engPreNum = (int)engPre; } else if (t.Type is Suffixes) { suffix = (Suffixes)t.Type; if (suffix == Suffixes.oic_acid) { OicAcid(parentChain[0]); if (engPreNum == 2) { OicAcid(parentChain.Last()); } } else if (suffix == Suffixes.carboxylic_acid) { CarboxylicAcid(parentChain[0]); if (engPreNum == 2) { CarboxylicAcid(parentChain.Last()); } } else if (suffix == Suffixes.al) { Aldehyde(parentChain[0]); if (engPreNum == 2) { Aldehyde(parentChain.Last()); } } else if (suffix == Suffixes.ol) { Alcohol(parentChain[0]); if (engPreNum == 2) { Alcohol(parentChain.Last()); } } else if (suffix == Suffixes.one) { Ketone(parentChain[0]); if (engPreNum == 2) { Ketone(parentChain.Last()); } } else if (suffix == Suffixes.amine) { Amine(parentChain[0]); if (engPreNum == 2) { Amine(parentChain.Last()); } } numbers.Clear(); engPreNum = 0; mode = 0; } else { //TODO: implicit bond location ignoreHyphen = true; } } else if (mode == 1) { EngPrefixes engPrefix; Bonds btype; Suffixes suffix; if (t.Type is Operators && !ignoreHyphen) { throw new FormatException("Wrong token format at token #" + i); } else if (t.Type is EngPrefixes) { engPrefix = (EngPrefixes)t.Type; //TODO: check prefix validity } else if (t.Type is Bonds) { btype = (Bonds)t.Type; foreach (int k in numbers) { parentChainBonds[k - 1].Type = (BondType)(int)btype; } numbers.Clear(); engPreNum = 0; mode = 0; ignoreHyphen = true; } else if (t.Type is Suffixes) { suffix = (Suffixes)t.Type; if (suffix == Suffixes.ol) { foreach (int k in numbers) { Alcohol(parentChain[k - 1]); } } else if (suffix == Suffixes.carboxylic_acid) { foreach (int k in numbers) { CarboxylicAcid(parentChain[k - 1]); } } else if (suffix == Suffixes.one) { foreach (int k in numbers) { Ketone(parentChain[k - 1]); } } else if (suffix == Suffixes.amine) { foreach (int k in numbers) { Amine(parentChain[k - 1]); } } numbers.Clear(); engPreNum = 0; mode = 0; ignoreHyphen = true; } } if (ignoreHyphen && (t.Type is Operators && (Operators)t.Type == Operators.hyphen)) { ignoreHyphen = false; } } //make functional groups mode = 0; numbers = new List <int>(); engPreNum = 0; ignoreHyphen = false; for (int i = 0; i < exp.FunctionalGpTokens.Count; i++) { Token t = exp.FunctionalGpTokens[i]; if (mode == 0) { Operators op; EngPrefixes engPre; FunctionalGps fGp; if (t.Type is Operators) { op = (Operators)t.Type; if (op == Operators.number) { numbers.Add(t.data); } else if (op == Operators.comma) { } else if (op == Operators.hyphen && !ignoreHyphen) { mode = 1; } } else if (t.Type is EngPrefixes) { engPre = (EngPrefixes)t.Type; engPreNum = (int)engPre; } else if (t.Type is FunctionalGps) { fGp = (FunctionalGps)t.Type; if (fGp == FunctionalGps.cyclo) { if (parentChain.First() != parentChain.Last() && !GetOther(parentChain.First()).Select(b => b.GetOther(parentChain.First())).Contains(parentChain.Last())) { Bonds.Add(new Bond(parentChain.First(), parentChain.Last(), BondType.Single, Orientation.None)); } } //TODO: implicit functional group location ignoreHyphen = true; } } else if (mode == 1) { EngPrefixes engPrefix; FunctionalGps ftype; ChemPrefixes chemPrefix; if (t.Type is Operators && !ignoreHyphen) { throw new FormatException("Wrong token format at token #" + i); } else if (t.Type is EngPrefixes) { engPrefix = (EngPrefixes)t.Type; //TODO: check prefix validity } else if (t.Type is ChemPrefixes) { chemPrefix = (ChemPrefixes)t.Type; if (i < exp.FunctionalGpTokens.Count - 1) { ftype = (FunctionalGps)exp.FunctionalGpTokens[i + 1].Type; if (ftype == FunctionalGps.yl) { foreach (int k in numbers) { Alkane(parentChain[k - 1], (int)chemPrefix); } } else if (ftype == FunctionalGps.oxy) { foreach (int k in numbers) { Ether(parentChain[k - 1], (int)chemPrefix); } } } numbers.Clear(); engPreNum = 0; mode = 0; ignoreHyphen = true; } else if (t.Type is FunctionalGps) { ftype = (FunctionalGps)t.Type; if (ftype == FunctionalGps.bromo) { foreach (int k in numbers) { Bromine(parentChain[k - 1]); } } if (ftype == FunctionalGps.oxo) { foreach (int k in numbers) { Ketone(parentChain[k - 1]); } } else if (ftype == FunctionalGps.phenyl) { foreach (int k in numbers) { Phenyl(parentChain[k - 1]); } } else if (ftype == FunctionalGps.chloro) { foreach (int k in numbers) { Chlorine(parentChain[k - 1]); } } else if (ftype == FunctionalGps.fluoro) { foreach (int k in numbers) { Fluorine(parentChain[k - 1]); } } else if (ftype == FunctionalGps.hydroxy) { foreach (int k in numbers) { Alcohol(parentChain[k - 1]); } } numbers.Clear(); engPreNum = 0; mode = 0; ignoreHyphen = true; } } if (ignoreHyphen && (t.Type is Operators && (Operators)t.Type == Operators.hyphen)) { ignoreHyphen = false; } } return(this); }