private Node ParseElement() { if (Match(TokenType.Shorthand)) { // Drop the leading "$". string shorthand = Previous().Source.Substring(1); if (shorthand.StartsWith("-") || shorthand.StartsWith(".-")) { History.ActivateLog(); } return(new DynamicElement(shorthand, History, CyclicMatches)); } if (Match(TokenType.Escape)) { char source = Previous().Source[1]; switch (source) { case 'n': return(new Literal("\n")); case '\n': return(new Literal("¶")); default: return(new Literal(source.ToString())); } } if (Match(TokenType.Literal)) { return(new Literal(Previous().Source)); } if (Match(TokenType.ElementOpen)) { Node inner = ParseConcatenation(); // Consume the closing } if there is one. Match(TokenType.ElementClose); History.ActivateLog(); return(new DynamicElement(inner, History, CyclicMatches)); } if (Match(TokenType.ConcatOpen)) { bool length = Previous().Source[1] == '.'; Node inner = ParseConcatenation(); // Consume the closing } if there is one. Match(TokenType.ConcatClose); if (length) { return(new Length(inner)); } else { return(inner); } } throw new NoElementException(); }