/* * Function: cat_expr * Description: Recursive descent regular expression parser. */ private static void cat_expr(NfaPair pair) { NfaPair e2_pair; #if DESCENT_DEBUG Utility.enter("cat_expr", spec.lexeme, spec.current_token); #endif #if DEBUG Utility.assert(null != pair); #endif e2_pair = Alloc.NewNfaPair(); if (first_in_cat(spec.current_token)) { factor(pair); } while (first_in_cat(spec.current_token)) { factor(e2_pair); /* Destroy */ pair.end.mimic(e2_pair.start); discardNfa(e2_pair.start); pair.end = e2_pair.end; } #if DESCENT_DEBUG Utility.leave("cat_expr", spec.lexeme, spec.current_token); #endif }
/* * Function: factor * Description: Recursive descent regular expression parser. */ private static void factor(NfaPair pair) { Nfa start = null; Nfa end = null; #if DESCENT_DEBUG Utility.enter("factor", spec.lexeme, spec.current_token); #endif term(pair); if (Gen.CLOSURE == spec.current_token || Gen.PLUS_CLOSE == spec.current_token || Gen.OPTIONAL == spec.current_token) { start = Alloc.NewNfa(spec); end = Alloc.NewNfa(spec); start.SetNext(pair.start); pair.end.SetNext(end); if (Gen.CLOSURE == spec.current_token || Gen.OPTIONAL == spec.current_token) { start.SetSib(end); } if (Gen.CLOSURE == spec.current_token || Gen.PLUS_CLOSE == spec.current_token) { pair.end.SetSib(pair.start); } pair.start = start; pair.end = end; gen.Advance(); } #if DESCENT_DEBUG Utility.leave("factor", spec.lexeme, spec.current_token); #endif }
/* * Function: expr * Description: Recursive descent regular expression parser. */ private static void expr(NfaPair pair) { NfaPair e2_pair; Nfa p; #if DESCENT_DEBUG Utility.enter("expr", spec.lexeme, spec.current_token); #endif #if DEBUG Utility.assert(null != pair); #endif e2_pair = Alloc.NewNfaPair(); cat_expr(pair); while (Gen.OR == spec.current_token) { gen.Advance(); cat_expr(e2_pair); p = Alloc.NewNfa(spec); p.SetSib(e2_pair.start); p.SetNext(pair.start); pair.start = p; p = Alloc.NewNfa(spec); pair.end.SetNext(p); e2_pair.end.SetNext(p); pair.end = p; } #if DESCENT_DEBUG Utility.leave("expr", spec.lexeme, spec.current_token); #endif }
/* * Function: term * Description: Recursive descent regular expression parser. */ private static void term(NfaPair pair) { Nfa start; bool isAlphaL; #if DESCENT_DEBUG Utility.enter("term", spec.lexeme, spec.current_token); #endif if (Gen.OPEN_PAREN == spec.current_token) { gen.Advance(); expr(pair); if (Gen.CLOSE_PAREN == spec.current_token) { gen.Advance(); } else { Error.parse_error(Error.E_SYNTAX, input.line_number); } } else { start = Alloc.NewNfa(spec); pair.start = start; start.SetNext(Alloc.NewNfa(spec)); pair.end = start.GetNext(); if (Gen.L == spec.current_token && Char.IsLetter(spec.lexeme)) { isAlphaL = true; } else { isAlphaL = false; } if (false == (Gen.ANY == spec.current_token || Gen.CCL_START == spec.current_token || (spec.ignorecase && isAlphaL))) { start.SetEdge(spec.lexeme); gen.Advance(); } else { start.SetEdge(Nfa.CCL); start.SetCharSet(new CharSet()); CharSet cset = start.GetCharSet(); /* Match case-insensitive letters using character class. */ if (spec.ignorecase && isAlphaL) { cset.addncase(spec.lexeme); } /* Match dot (.) using character class. */ else if (Gen.ANY == spec.current_token) { cset.add('\n'); cset.add('\r'); /* exclude BOL and EOF from character classes */ cset.add(spec.BOL); cset.add(spec.EOF); cset.complement(); } else { gen.Advance(); if (Gen.AT_BOL == spec.current_token) { gen.Advance(); /* exclude BOL and EOF from character classes */ cset.add(spec.BOL); cset.add(spec.EOF); cset.complement(); } if (!(Gen.CCL_END == spec.current_token)) { dodash(cset); } } gen.Advance(); } } #if DESCENT_DEBUG Utility.leave("term", spec.lexeme, spec.current_token); #endif }
/* * Function: rule * Description: Recursive descent regular expression parser. */ private static Nfa rule() { NfaPair pair; Nfa start = null; Nfa end = null; int anchor = Spec.NONE; #if DESCENT_DEBUG Utility.enter("rule", spec.lexeme, spec.current_token); #endif pair = Alloc.NewNfaPair(); if (Gen.AT_BOL == spec.current_token) { anchor = anchor | Spec.START; gen.Advance(); expr(pair); start = Alloc.NewNfa(spec); start.SetEdge(spec.BOL); start.SetNext(pair.start); end = pair.end; } else { expr(pair); start = pair.start; end = pair.end; } if (Gen.AT_EOL == spec.current_token) { gen.Advance(); NfaPair nlpair = Alloc.NewNLPair(spec); end.SetNext(Alloc.NewNfa(spec)); Nfa enext = end.GetNext(); enext.SetNext(nlpair.start); enext.SetSib(Alloc.NewNfa(spec)); enext.GetSib().SetEdge(spec.EOF); enext.GetSib().SetNext(nlpair.end); end = nlpair.end; anchor = anchor | Spec.END; } /* check for null rules */ if (end == null) { Error.parse_error(Error.E_ZERO, input.line_number); } /* Handle end of regular expression */ end.SetAccept(gen.packAccept()); end.SetAnchor(anchor); #if DESCENT_DEBUG Utility.leave("rule", spec.lexeme, spec.current_token); #endif return(start); }