1966 * character or unpaired surrogate. 1967 */ 1968 private static final boolean isSupplementary(int ch) { 1969 return ch >= Character.MIN_SUPPLEMENTARY_CODE_POINT || 1970 Character.isSurrogate((char)ch); 1971 } 1972 1973 /** 1974 * The following methods handle the main parsing. They are sorted 1975 * according to their precedence order, the lowest one first. 1976 */ 1977 1978 /** 1979 * The expression is parsed with branch nodes added for alternations. 1980 * This may be called recursively to parse sub expressions that may 1981 * contain alternations. 1982 */ 1983 private Node expr(Node end) { 1984 Node prev = null; 1985 Node firstTail = null; 1986 Node branchConn = null; 1987 1988 for (;;) { 1989 Node node = sequence(end); 1990 Node nodeTail = root; //double return 1991 if (prev == null) { 1992 prev = node; 1993 firstTail = nodeTail; 1994 } else { 1995 // Branch 1996 if (branchConn == null) { 1997 branchConn = new BranchConn(); 1998 branchConn.next = end; 1999 } 2000 if (node == end) { 2001 // if the node returned from sequence() is "end" 2002 // we have an empty expr, set a null atom into 2003 // the branch to indicate to go "next" directly. 2004 node = null; 2005 } else { 2006 // the "tail.next" of each atom goes to branchConn 2007 nodeTail.next = branchConn; 2008 } 2009 if (prev instanceof Branch) { 2010 ((Branch)prev).add(node); 2011 } else { 2012 if (prev == end) { 2013 prev = null; 2014 } else { 2015 // replace the "end" with "branchConn" at its tail.next 2016 // when put the "prev" into the branch as the first atom. 2017 firstTail.next = branchConn; 2018 } 2019 prev = new Branch(prev, node, branchConn); 2020 } 2021 } 2022 if (peek() != '|') { 2023 return prev; 2024 } 2025 next(); 2026 } 2027 } 2028 2029 @SuppressWarnings("fallthrough") 2030 /** 2031 * Parsing of sequences between alternations. 2032 */ 2033 private Node sequence(Node end) { 2034 Node head = null; 2035 Node tail = null; 2036 Node node = null; 2037 LOOP: 2038 for (;;) { 2039 int ch = peek(); | 1966 * character or unpaired surrogate. 1967 */ 1968 private static final boolean isSupplementary(int ch) { 1969 return ch >= Character.MIN_SUPPLEMENTARY_CODE_POINT || 1970 Character.isSurrogate((char)ch); 1971 } 1972 1973 /** 1974 * The following methods handle the main parsing. They are sorted 1975 * according to their precedence order, the lowest one first. 1976 */ 1977 1978 /** 1979 * The expression is parsed with branch nodes added for alternations. 1980 * This may be called recursively to parse sub expressions that may 1981 * contain alternations. 1982 */ 1983 private Node expr(Node end) { 1984 Node prev = null; 1985 Node firstTail = null; 1986 Branch branch = null; 1987 Node branchConn = null; 1988 1989 for (;;) { 1990 Node node = sequence(end); 1991 Node nodeTail = root; //double return 1992 if (prev == null) { 1993 prev = node; 1994 firstTail = nodeTail; 1995 } else { 1996 // Branch 1997 if (branchConn == null) { 1998 branchConn = new BranchConn(); 1999 branchConn.next = end; 2000 } 2001 if (node == end) { 2002 // if the node returned from sequence() is "end" 2003 // we have an empty expr, set a null atom into 2004 // the branch to indicate to go "next" directly. 2005 node = null; 2006 } else { 2007 // the "tail.next" of each atom goes to branchConn 2008 nodeTail.next = branchConn; 2009 } 2010 if (prev == branch) { 2011 branch.add(node); 2012 } else { 2013 if (prev == end) { 2014 prev = null; 2015 } else { 2016 // replace the "end" with "branchConn" at its tail.next 2017 // when put the "prev" into the branch as the first atom. 2018 firstTail.next = branchConn; 2019 } 2020 prev = branch = new Branch(prev, node, branchConn); 2021 } 2022 } 2023 if (peek() != '|') { 2024 return prev; 2025 } 2026 next(); 2027 } 2028 } 2029 2030 @SuppressWarnings("fallthrough") 2031 /** 2032 * Parsing of sequences between alternations. 2033 */ 2034 private Node sequence(Node end) { 2035 Node head = null; 2036 Node tail = null; 2037 Node node = null; 2038 LOOP: 2039 for (;;) { 2040 int ch = peek(); |