#if !defined(COCO_PARSER_H__) #define COCO_PARSER_H__ -->headerdef #include "Scanner.h" -->namespace_open class Errors { public: int count; // number of errors detected Errors(); void SynErr(int line, int col, int n); void Error(int line, int col, const wchar_t *s); void Warning(int line, int col, const wchar_t *s); void Warning(const wchar_t *s); void Exception(const wchar_t *s); }; // Errors class Parser { private: -->constantsheader Token *dummyToken; int errDist; int minErrDist; void SynErr(int n); void Get(); void Expect(int n); bool StartOf(int s); void ExpectWeak(int n, int follow); bool WeakSeparator(int n, int syFol, int repFol); public: Scanner *scanner; Errors *errors; Token *t; // last recognized token Token *la; // lookahead token -->declarations Parser(Scanner *scanner); ~Parser(); void SemErr(const wchar_t* msg); -->productionsheader void Parse(); }; // end Parser -->namespace_close #endif // !defined(COCO_PARSER_H__) -->implementation /*---------------------------------------------------------------------- Parser.cpp Specification -----------------------------------------------------------------------*/ -->begin #include #include "Parser.h" #include "Scanner.h" -->namespace_open void Parser::SynErr(int n) { if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n); errDist = 0; } void Parser::SemErr(const wchar_t* msg) { if (errDist >= minErrDist) errors->Error(t->line, t->col, msg); errDist = 0; } void Parser::Get() { for (;;) { t = la; la = scanner->Scan(); if (la->kind <= maxT) { ++errDist; break; } -->pragmas if (dummyToken != t) { dummyToken->kind = t->kind; dummyToken->pos = t->pos; dummyToken->col = t->col; dummyToken->line = t->line; dummyToken->next = NULL; coco_string_delete(dummyToken->val); dummyToken->val = coco_string_create(t->val); t = dummyToken; } la = t; } } void Parser::Expect(int n) { if (la->kind==n) Get(); else { SynErr(n); } } void Parser::ExpectWeak(int n, int follow) { if (la->kind == n) Get(); else { SynErr(n); while (!StartOf(follow)) Get(); } } bool Parser::WeakSeparator(int n, int syFol, int repFol) { if (la->kind == n) {Get(); return true;} else if (StartOf(repFol)) {return false;} else { SynErr(n); while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) { Get(); } return StartOf(syFol); } } -->productions void Parser::Parse() { t = NULL; la = dummyToken = new Token(); la->val = coco_string_create(L"Dummy Token"); Get(); -->parseRoot } Parser::Parser(Scanner *scanner) { -->constants dummyToken = NULL; t = la = NULL; minErrDist = 2; errDist = minErrDist; this->scanner = scanner; errors = new Errors(); } bool Parser::StartOf(int s) { const bool T = true; const bool x = false; -->initialization return set[s][la->kind]; } Parser::~Parser() { delete errors; delete dummyToken; } Errors::Errors() { count = 0; } void Errors::SynErr(int line, int col, int n) { wchar_t* s; switch (n) { -->errors default: { wchar_t format[20]; coco_swprintf(format, 20, L"error %d", n); s = coco_string_create(format); } break; } wprintf(L"-- line %d col %d: %ls\n", line, col, s); coco_string_delete(s); count++; } void Errors::Error(int line, int col, const wchar_t *s) { wprintf(L"-- line %d col %d: %ls\n", line, col, s); count++; } void Errors::Warning(int line, int col, const wchar_t *s) { wprintf(L"-- line %d col %d: %ls\n", line, col, s); } void Errors::Warning(const wchar_t *s) { wprintf(L"%ls\n", s); } void Errors::Exception(const wchar_t* s) { wprintf(L"%ls", s); exit(1); } -->namespace_close