SyntaxTree* Parser::m_parse_op_postfix(Parser* my, Parser* exp, Parser* op, bool allowRepeat) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree* ste = exp->parse(); if (ste->isFail()) { m_fail(startPos); return ste; } for (;;) { m_ErrorPos midPos = m_curErrPos(); SyntaxTree* sto = op->parse(); if (sto->isError()) { m_fail(startPos); SyntaxTree::deleteRecursively(ste); return sto; } if (sto->isFail()) { m_back(midPos); return ste; } SyntaxTree::Childs* childs = new SyntaxTree::Childs(2); childs->setContentsMemID("pcpo"); exp->addSyntaxTreeToParent(childs, ste); op->addSyntaxTreeToParent(childs, sto); ste = my->createSyntaxTree(startPos.parsePos, childs); if (! allowRepeat) return ste; } }
SyntaxTree::Childs* Parser::m_parse_infix_common(Parser* exp, Parser* op, bool rep) { // Exp (Op Exp)* のパース // rep が false なら Exp (Op Exp)? のパース // 結果はSyntaxTreeの配列で [exp op exp op exp ....] m_ErrorPos startPos = m_curErrPos(); SyntaxTree* st = exp->parse(); if (st->isError()) { m_fail(startPos); return m_INFIX_COMMON_FATAL_ERROR; } if (st->isFail()) { m_fail(startPos); return NULL; } SyntaxTree::Childs* childs = new SyntaxTree::Childs(3); childs->setContentsMemID("pcif"); childs->add(st); //exp->addSyntaxTreeToParent(childs, st); for (;;) { m_ErrorPos midPos = m_curErrPos(); SyntaxTree* sto = op->parse(); if (sto->isError()) { m_fail(startPos); if (! m_bUseMemoize) { SyntaxTree::Childs::deleteRecursively(childs); } else { delete childs; } return m_INFIX_COMMON_FATAL_ERROR; } if (sto->isFail()) { m_back(midPos); break; } SyntaxTree* ste = exp->parse(); if (ste->isError()) { m_fail(startPos); if (! m_bUseMemoize) { SyntaxTree::Childs::deleteRecursively(childs); } else { delete childs; } return m_INFIX_COMMON_FATAL_ERROR; } if (ste->isFail()) { if (! m_bUseMemoize) SyntaxTree::deleteRecursively(sto); m_back(midPos); break; } op->addSyntaxTreeToParent(childs, sto); exp->addSyntaxTreeToParent(childs, ste); if (!rep) break; } return childs; }
SyntaxTree* Parser::m_parse_m2n(Parser* p, int m, int n) { int count = 0; m_ErrorPos startPos = m_curErrPos(); SyntaxTree::Childs* childs = new SyntaxTree::Childs(m > 0 ? m : 1); childs->setContentsMemID("pcmn"); for (;;) { SyntaxTree* st = p->parse(); if (st->isError()) { m_fail(startPos); return st; } if (! st->isFail()) { p->addSyntaxTreeToParent(childs, st); if (++count >= MAX_MANY) count = MAX_MANY - 1; if (count >= n) break; // all ok } else { break; } } if (count < m) { m_fail(startPos); if (! m_bUseMemoize) { SyntaxTree::Childs::deleteRecursively(childs); } else { delete childs; } return m_PARSE_FAILED; } m_errors->clear(); return createSyntaxTree(startPos.parsePos, childs); }
SyntaxTree* Parser::m_parse_orderedChoice(TArray<Parser*>* ps) { m_ErrorPos startPos = m_curErrPos(); int i = 0; for (TArrayIterator<Parser*> itr(ps); itr.hasMore(); ++i) { Parser* p = itr.next(); SyntaxTree* st = p->parse(); if (st->isError()) { m_fail(startPos); return st; } if (! st->isFail()) { SyntaxTree::Childs* childs = new SyntaxTree::Childs(1); childs->setContentsMemID("pcoc"); p->addSyntaxTreeToParent(childs, st); SyntaxTree* ordst = createSyntaxTree(startPos.parsePos, childs); ordst->chooseNum = i; return ordst; } if (itr.hasMore()) m_back(startPos); } m_fail(startPos); return m_PARSE_FAILED; }
SyntaxTree* Parser::m_parse_sequence(TArray<Parser*>* ps) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree::Childs* childs = new SyntaxTree::Childs(ps->size()); childs->setContentsMemID("pcsq"); int errorCutId = 0; hyu32 errorCutPos = 0; for (TArrayIterator<Parser*> itr(ps); itr.hasMore(); ) { Parser* p = itr.next(); SyntaxTree* st = p->parse(); if (st->isErrorCut()) { errorCutId = st->errorCutId; errorCutPos = st->str.startPos; delete st; } else if (! st->isFail()) { p->addSyntaxTreeToParent(childs, st); } else { if (st->isFailNotError() && errorCutId > 0) { SyntaxTree* e = new SyntaxTree(errorCutPos, errorCutId, this); if (! m_bUseMemoize) delete st; st = e; } m_fail(startPos); if (! m_bUseMemoize) { SyntaxTree::Childs::deleteRecursively(childs); } else { delete childs; } return st; } } return createSyntaxTree(startPos.parsePos, childs); }
SyntaxTree* Parser::m_parse_op_prefix(Parser* my, Parser* exp, Parser* op, bool allowRepeat) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree::Childs* firstChilds = new SyntaxTree::Childs(2); firstChilds->setContentsMemID("pcpr"); SyntaxTree::Childs* lastChilds = firstChilds; for (;;) { m_ErrorPos midPos = m_curErrPos(); SyntaxTree* sto = op->parse(); if (sto->isError()) { m_fail(startPos); SyntaxTree::Childs::deleteRecursively(firstChilds); return sto; } if (sto->isFail()) { m_back(midPos); break; } else { if (lastChilds->size() > 0) { SyntaxTree::Childs* newChilds = new SyntaxTree::Childs(2); newChilds->setContentsMemID("pcpr"); lastChilds->add(my->createSyntaxTree(m_curPos(), newChilds)); lastChilds = newChilds; } op->addSyntaxTreeToParent(lastChilds, sto); if (! allowRepeat) break; } } SyntaxTree* ste = exp->parse(); if (ste->isFail()) { m_fail(startPos); SyntaxTree::Childs::deleteRecursively(firstChilds); return ste; } if (lastChilds->size() == 0) { // no op SyntaxTree::Childs::deleteRecursively(firstChilds); return ste; } lastChilds->add(ste); return my->createSyntaxTree(startPos.parsePos, firstChilds); }
SyntaxTree* Parser::m_parse_noTree(Parser* p) { SyntaxTree* st = p->parse(); if (st->isFail()) return st; if (! m_bUseMemoize) { SyntaxTree::deleteRecursively(st); } return m_NO_SYNTAX_TREE; }
SyntaxTree* Parser::m_parse_andPredicate(Parser* p) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree* st = p->parse(); if (st->isFail()) { m_fail(startPos); return m_PARSE_FAILED; } m_back(startPos); SyntaxTree::deleteRecursively(st); return m_NO_SYNTAX_TREE; }
SyntaxTree* UserParser::m_parse1(m_ErrorPos startPos) { const char* n = name(); SyntaxTree* st; if (m_bUseMemoize) { st = m_memo.getAt(startPos.parsePos); if (st == m_PARSING) { // left recursion char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); HMD_PRINTF("LEFT RECURSION DETECTED: %s %s\n", n, pbuf); return m_FATAL_PARSER_ERROR; } else if (st != m_NOT_PARSED_YET) { if (st->isValidTree()) gpInp->setPos(st->str.endPos); if (m_printIntermediateLevel > 1 || (m_printIntermediateLevel > 0 && !st->isFail())) { char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); HMD_PRINTF("%s %s -> memoized ", n, pbuf); if (st->isValidTree()) { char b[44]; gpInp->copySummary(b, 40, st->str); HMD_PRINTF("pos=%d-%d '%s'\n", st->str.startPos, st->str.endPos, b); } else { if (st == m_NO_SYNTAX_TREE) HMD_PRINTF("no syntax tree\n"); else if (st == m_PARSE_FAILED) HMD_PRINTF("parse failed\n"); else if (st->isErrorCut()) HMD_PRINTF("ErrorCut(%d)\n",st->errorCutId); else HMD_PRINTF("(UNKNOWN BUG?)\n"); } } return st; } // not parsed yet m_memo.setAt(startPos.parsePos, m_PARSING); } if (m_printIntermediateLevel > 1) { char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); HMD_PRINTF("try %s %s pos=%d:\n", n, pbuf, startPos.parsePos); } return NULL; }
SyntaxTree* OperatorParser::parse(void) { HMD_ASSERT(m_parser); m_ErrorPos startPos = m_curErrPos(); SyntaxTree* st = m_parser->parse(); const char* n = name(); if (st->isError()) { m_fail(startPos); if (! st->isFatalError()) { char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); HMD_PRINTF("%s %s -> ERROR %d\n", n, pbuf, st->errorCutId); } return m_FATAL_PARSER_ERROR; } if (st->isFail()) { if (m_printIntermediateLevel > 2) { char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); HMD_PRINTF("%s %s -> fail\n", n, pbuf); } m_fail(startPos); return m_PARSE_FAILED; } if (m_printIntermediateLevel > 1) { char pbuf[128]; gpInp->sprintSourceInfo(pbuf, 128, startPos.parsePos); if (st->isValidTree()) { char b[44]; gpInp->copySummary(b, 40, st->str); HMD_PRINTF("%s %s -> '%s'\n", n, pbuf, b); } else { HMD_PRINTF("%s %s -> (notree)\n", n, pbuf); } } #if 0 if (st->isValidTree()) { if (st->numChild() == 1) { // no operator, so that this node is not needed SyntaxTree* tmp = st->replace(0, NULL); if (! m_bUseMemoize) delete st; return tmp; } } #endif return st; }
SyntaxTree* Parser::m_parse_op_ternary(Parser* my, Parser* exp, Parser* op1, Parser* op2) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree* ste = exp->parse(); if (ste->isFail()) { m_fail(startPos); return m_PARSE_FAILED; } SyntaxTree::Childs* childs = new SyntaxTree::Childs(5); childs->setContentsMemID("pcte"); m_ErrorPos midPos = m_curErrPos(); exp->addSyntaxTreeToParent(childs, ste); SyntaxTree* st = op1->parse(); if (! st->isFail()) { op1->addSyntaxTreeToParent(childs, st); st = my->parse(); if (! st->isFail()) { my->addSyntaxTreeToParent(childs, st); st = op2->parse(); if (! st->isFail()) { op2->addSyntaxTreeToParent(childs, st); st = my->parse(); if (! st->isFail()) { // success my->addSyntaxTreeToParent(childs, st); return my->createSyntaxTree(startPos.parsePos, childs); } } } } m_back(midPos); delete childs; return ste; }
SyntaxTree* Parser::m_parse_notPredicate(Parser* p) { m_ErrorPos startPos = m_curErrPos(); SyntaxTree* st = p->parse(); if (st->isFatalError()) { m_fail(startPos); return st; } m_back(startPos); if (! st->isFail()) { if (! m_bUseMemoize) { SyntaxTree::deleteRecursively(st); } return m_PARSE_FAILED; } return m_NO_SYNTAX_TREE; }