// item: ATOM('+'|'*'|'?') void Grammar::parseItem(string &ruleName, NFA **start, NFA **end) { parseAtom(ruleName, start, end); assert(*start != NULL); assert(*end != NULL); // check to see wether repeator exist? if (isMatch(TT_OP, "+")) { (*end)->arc(*start); advanceToken(); } else if (isMatch(TT_OP, "*")) { NFA *startState = new NFA(); NFA *endState = new NFA(); startState->arc(endState); startState->arc(*start); (*end)->arc(*start); (*end)->arc(endState); *start = startState; *end = endState; advanceToken(); } else if (isMatch(TT_OP, "?")) { NFA *endState = new NFA(); (*end)->arc(endState); (*start)->arc(endState); *end = endState; advanceToken(); } }
/// parse the alternative, such as alternative : items (| items)* void Grammar::parseAlternative(string &ruleName, NFA **start, NFA **end) { assert(start != NULL); assert(end != NULL); // parse items parseItems(ruleName, start, end); if (isMatch(TT_OP, "|")) { // make a closing state NFA *closingStartState = new NFA(); NFA *closingEndState = new NFA; closingStartState->arc(*start); (*end)->arc(closingEndState); while (isMatch(TT_OP, "|")) { advanceToken(); NFA *startState = NULL; NFA *endState = NULL; parseItems(ruleName, &startState, &endState); closingStartState->arc(startState); endState->arc(closingEndState); } *start = closingStartState; *end = closingEndState; } }