private static Atom ReadNode(List <Token> tokens, ref int offset, bool outer = false) { Atom atom = new Atom(AtomType.Undefined); Token token = tokens[offset]; switch (token.type) { case TokenType.Quoting: { offset++; Atom subnode = ReadNode(tokens, ref offset); atom.type = AtomType.Pair; atom.value = Atom.QUOTE; atom.next = new Atom(AtomType.Pair, subnode); } return(atom); case TokenType.Operator: { if (token.value != "(" && token.value != "[") { StringBuilder lastTokens = new StringBuilder("Last tokens:\n"); for (int i = -20; i < 0; i++) { lastTokens.AppendFormat(" {0}", tokens[offset + i].value); } throw new ArgumentException("Incorrect ( ) [ ] order!\n" + lastTokens.ToString()); } offset++; atom.type = AtomType.Pair; Atom node = atom; bool rest = false; bool dotted = false; string ending = ")"; if (token.value == "[") { ending = "]"; } while (tokens[offset].value != ending) { if (IsSeparator(tokens, ref offset)) { offset++; continue; } if (dotted) { throw new ArgumentException("Token \".\" not allowed here! "); } // Точка не может быть первой bool isDot = (tokens[offset].value == "."); if (!rest && isDot) { throw new ArgumentException("Token \".\" not allowed here!"); } if (rest) { if (isDot) { offset++; dotted = true; while (IsSeparator(tokens, ref offset)) { offset++; } } else { node.next = new Atom(); node = node.next; } } Atom subnode = ReadNode(tokens, ref offset); if (isDot) { node.next = subnode; } else { node.value = subnode; } rest = true; } } break; case TokenType.String: { atom.type = AtomType.String; atom.value = token.value .Substring(1, token.value.Length - 2) .Replace("\\n", "\n") .Replace("\\t", "\t") .Replace("\\\"", "\"") .Replace("\\\\", "\\"); } break; case TokenType.Symbol: { if (outer && token.value == ".") { throw new ArgumentException("Token \".\" not allowed here!"); } if (token.value == AllNames.NULL_SYMBOL) { atom = null; break; } bool parsed = false; int count = extensions_.Count; for (int i = 0; i < count; i++) { IParserExtension extension = extensions_[i]; if (extension.TryParseValue(token.value, ref atom.type, ref atom.value)) { parsed = true; break; } } if (parsed == false) { atom.type = AtomType.Symbol; atom.value = token.value; } } break; default: { throw new ArgumentException(string.Format("Unexpected token {0} '{1}'", token.type, token.value)); } } offset++; return(atom); }
public static void AddExtension(IParserExtension extension) { Init(); extensions_.Add(extension); }