/** * Parse a filter ID, that is, an ID of the general form * "[f1] s1-t1/v1", with the filters optional, and the variants optional. * @param id the id to be parsed * @param pos INPUT-OUTPUT parameter. On input, the position of * the first character to parse. On output, the position after * the last character parsed. * @return a SingleID object or null if the parse fails */ public static SingleID ParseFilterID(string id, int[] pos) { int start = pos[0]; Specs specs = ParseFilterID(id, pos, true); if (specs == null) { pos[0] = start; return(null); } // Assemble return results SingleID single = SpecsToID(specs, Forward); single.Filter = specs.Filter; return(single); }
/** * Parse a compound ID, consisting of an optional forward global * filter, a separator, one or more single IDs delimited by * separators, an an optional reverse global filter. The * separator is a semicolon. The global filters are UnicodeSet * patterns. The reverse global filter must be enclosed in * parentheses. * @param id the pattern the parse * @param dir the direction. * @param canonID OUTPUT parameter that receives the canonical ID, * consisting of canonical IDs for all elements, as returned by * parseSingleID(), separated by semicolons. Previous contents * are discarded. * @param list OUTPUT parameter that receives a list of SingleID * objects representing the parsed IDs. Previous contents are * discarded. * @param globalFilter OUTPUT parameter that receives a pointer to * a newly created global filter for this ID in this direction, or * null if there is none. * @return true if the parse succeeds, that is, if the entire * id is consumed without syntax error. */ public static bool ParseCompoundID(string id, TransliterationDirection dir, StringBuffer canonID, IList <SingleID> list, UnicodeSet[] globalFilter) { int[] pos = new int[] { 0 }; int[] withParens = new int[1]; list.Clear(); UnicodeSet filter; globalFilter[0] = null; canonID.Length = 0; // Parse leading global filter, if any withParens[0] = 0; // parens disallowed filter = ParseGlobalFilter(id, pos, dir, withParens, canonID); if (filter != null) { if (!Utility.ParseChar(id, pos, ID_DELIM)) { // Not a global filter; backup and resume canonID.Length = 0; pos[0] = 0; } if (dir == Forward) { globalFilter[0] = filter; } } bool sawDelimiter = true; for (; ;) { SingleID single = ParseSingleID(id, pos, dir); if (single == null) { break; } if (dir == Forward) { list.Add(single); } else { list.Insert(0, single); } if (!Utility.ParseChar(id, pos, ID_DELIM)) { sawDelimiter = false; break; } } if (list.Count == 0) { return(false); } // Construct canonical ID for (int i = 0; i < list.Count; ++i) { SingleID single = list[i]; canonID.Append(single.CanonID); if (i != (list.Count - 1)) { canonID.Append(ID_DELIM); } } // Parse trailing global filter, if any, and only if we saw // a trailing delimiter after the IDs. if (sawDelimiter) { withParens[0] = 1; // parens required filter = ParseGlobalFilter(id, pos, dir, withParens, canonID); if (filter != null) { // Don't require trailing ';', but parse it if present Utility.ParseChar(id, pos, ID_DELIM); if (dir == Reverse) { globalFilter[0] = filter; } } } // Trailing unparsed text is a syntax error pos[0] = PatternProps.SkipWhiteSpace(id, pos[0]); if (pos[0] != id.Length) { return(false); } return(true); }