I think this answer provides an elegant solution -- at least for the less critical readers.
*(I was not going to post it but then it occurred to me that this answer is as continuation of discussion with Mr.Wizard [over programming styles](https://mathematica.stackexchange.com/a/110075/34008).)*
This generates a [EBNF](https://en.wikipedia.org/wiki/Extended_Backus–Naur_form) grammar for sequences of chemical elements:
Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/FunctionalParsers.m"]
elemNames =
ToLowerCase[
Sort[ElementData[#, "Abbreviation"] & /@ ElementData["*"]]];
ebnfChemElem =
"<chem-elem> = " <>
StringReplace[
ToString[
If[StringLength[#] == 1, "'" <> # <> "'",
StringJoin @@
Riffle["'" <> # <> "'" & /@ Characters[#], ","]] & /@
elemNames], {", " -> " | ", "{" -> "", "}" -> ""}] <> ";";
ebnfChemSplit = "<chem-split> = { <chem-elem> } ;";
ebnfChemElem <> "\n" <> ebnfChemSplit
[![enter image description here][1]][1]
The rule for the `<chem-split>` specifies that `<chem-split>` is a list of `<chem-elem>` strings.
The following code generates parsers and adds parser modifiers to concatenate the characters:
res = GenerateParsersFromEBNF[
ParseToEBNFTokens[ebnfChemElem <> ebnfChemSplit]];
LeafCount[res]
(* 4646 *)
SetParserModifier[pCHEMELEM, StringJoin[Flatten[{#}]] &];
SetParserModifier[pCHEMSPLIT, Map[StringJoin, #] &];
The following parsing examples are with the generated `pCHEMSPLIT`:
words = {"titanic", "silicon", "archbishop", "wombat", "mathematica"};
ParsingTestTable[pCHEMSPLIT, words, "TokenizerFunction" -> Characters,
"Layout" -> "Horizontal"]
[![enter image description here][2]][2]
The above does not parse all possible cases because `ParseMany` is implemented to pick shortest parsing paths. The parser generator uses `ParseMany` for `{ ... }` parts in the EBNF rules.
With alternative greedier `ParseMany` implementation we can get all possible valid parsings:
pChemElem =
ParseModify[DeleteDuplicates,
ParseApply[Flatten,ParseManyByBranching[pCHEMELEM]]];
words = {"titanic", "silicon", "archbishop", "wombat", "mathematica"};
ParsingTestTable[pChemElem, words, "TokenizerFunction" -> Characters,
"Layout" -> "Horizontal"]
[![enter image description here][3]][3]
[1]: https://i.sstatic.net/Rp1MW.png
[2]: https://i.sstatic.net/gXhry.png
[3]: https://i.sstatic.net/opgz5.png