⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inpbuf.cc

📁 PL/0源码
💻 CC
字号:
//////////////////////////////////////////////////////////////////////////////////  inpbuf.cc//#include <string>#include "inpbuf.h"#include "scanner.h"#include <iomanip>#define MAX_ERRORS  30//  Maximum number of errors before aborting compile.  More than that and the//  compiler is probably lost#define    TAB_WIDTH        8struct input_buffer_t {    int                 line_num;       // Line number of text.    input_buffer_t *    next;           // Next line.    input_buffer_t *    prev;           // Previous line.    string              buf;            // The (corrected) text of the line.    unsigned int        pointer;        // Index of the next character to read.    bool                modified;       // Were there any syntax corrections?    string              origBuf;        // Original before syntax corrections.    string              messages;       // Any error messages.};bool scanner_peeking = false;bool compile_ok = true;static input_buffer_t *   first_line;//  This is the root of the buffered source program.static input_buffer_t *   current_line;//  Current_line is one from which we return characters to the scanner.static int syntax_error_cnt = 0;static int insertion_cnt = 0;static int deletion_cnt = 0;static int semantic_error_cnt = 0;static int warning_cnt = 0;static bool compiler_dying = false;//  Catch recursive calls to die_compiler.//////////////////////////////////////////////////////////////////////////////////  Initialization and finalization functions.////////////  Initialize the input buffer module.//void init_input_buffer(void){    // fake a zero-th line that will be replaced immediately    current_line = new input_buffer_t;    first_line = current_line;    current_line->buf = "\n";    current_line->origBuf = "\n";    current_line->next = NULL;    current_line->prev = NULL;    current_line->pointer = 1;    current_line->line_num = 0;    current_line->modified = false;    current_line->messages = "";}//////////  Print out all accumulated lines.  Lines containing a syntax error are//  printed first in their original form, then as modified, with a leading//  '-S---------------- ', length-adjusted to come up to just before the//  first non-blank character of the line.//static void flush_lines(void){    for (input_buffer_t *temp_line = first_line; temp_line != NULL                                     ; temp_line = temp_line->next) {    if (temp_line->modified || temp_line->messages.length() != 0) {        if (temp_line->modified) {                cout << setw(6) << temp_line->line_num                    << "  "                    << temp_line->origBuf;                // origBuf has its own trailing linefeed        cout << "-S-----";        if (temp_line->buf[0] == '\n' || temp_line->buf[0] == ' ')                    cout << "-";        else                    cout << " ";                unsigned int i;        for (i = 0; temp_line->buf.length() >= i+1 &&                        temp_line->buf[i] == ' '                        && temp_line->buf[i+1] == ' '; i++) {            cout << "-";        }                cout << temp_line->buf.substr(i, temp_line->buf.length());        }        else                cout << setw(6) << temp_line->line_num                    << ": "                    << temp_line->buf;    } //if modified or messages        cout << temp_line->messages;    }}//////////  Print any error messages, and statistics about the compile.//void finalize_input_buffer(void){    flush_lines();    cout << "COMPLETED\n";    cout << " " << setw(4) << current_line->line_num << " line";    if (current_line->line_num != 1)        cout << "s";    cout << " in program\n";    cout << " " << setw(4) << syntax_error_cnt << " syntax error";    if (syntax_error_cnt != 1)        cout << "s";    cout << "\n";    cout << "     " << setw(4) << insertion_cnt << " insertion";    if (insertion_cnt != 1)        cout << "s";    cout << "\n";    cout << "     " << setw(4) << deletion_cnt << " deletion";    if (deletion_cnt != 1)        cout << "s";    cout << "\n";    cout << "     " << setw(4) << semantic_error_cnt << " semantic error";    if (semantic_error_cnt != 1)        cout << "s";    cout << "\n";    cout << "     " << setw(4) << warning_cnt << " warning";    if (warning_cnt != 1)        cout << "s";    cout << "\n";}//////////////////////////////////////////////////////////////////////////////////  Interface to scanner.////////////  Read in one character from the buffer.////  If necessary, read one line of input, or move to next line if//      one is buffered.//  Convert tabs to spaces.////  Put '\n' at end of line.//  Put FILE_END in first column of extra last line.////  Die if asked to return characters after end of file.//char read_char(void){    if (current_line->buf.length() == current_line->pointer) {        assert(current_line->buf[0] != FILE_END);            // can't return characters after end of file        if (current_line->next != NULL) {            current_line = current_line->next;        }        else {            char          temp[512];        char *        sp;        char *        ep;            unsigned int  pos;            char          c;            current_line->next = new input_buffer_t;            current_line->next->line_num = current_line->line_num + 1;            current_line->next->prev = current_line;            current_line = current_line->next;        strcpy(temp, "");        ep = temp + sizeof(temp) - 1;            for (sp = temp, pos = 0; pos < sizeof(temp) - 2;) {        if (cin.eof()) {            *sp++ = FILE_END;            *sp++ = '\n';            break;                   //leave for loop        }        cin.get(c);        if (c == EOF) {            *sp++ = FILE_END;            *sp++ = '\n';            break;        }        if (c == '\n') {            *sp++ = '\n';            break;        }        if (c == '\t') {                    for (int i = TAB_WIDTH - pos % TAB_WIDTH; i-- > 0; pos++)            *sp++ = ' ';        }        else {            *sp++ = c;                    pos++;                }        }        *sp = '\0';            current_line->origBuf = current_line->buf = temp;        current_line->pointer = 0;        current_line->modified = false;        current_line->next = NULL;        current_line->messages = "";        }    }    return current_line->buf[current_line->pointer++];}//////////  Try to put characters back into input stream.//void unread_chars(unsigned int how_many){    while (current_line->pointer < how_many) {        how_many -= current_line->pointer;        current_line->pointer = 0;        assert((int) current_line->prev);            // don't attempt to back up past beginning of program        current_line = current_line->prev;    }    current_line->pointer -= how_many;}//////////  Return location of character most recently read from the source program.//  Scanner calls this after reading first character of new token.//  We don't call it *before* reading first character of new token, because//  we don't know what line that first character will be on until the scanner//  has read and accepted it.//location_t get_source_location(void){    location_t  l;    l.line = current_line;    l.column = current_line->pointer-1;    return l;}//////////////////////////////////////////////////////////////////////////////////  Interface to syntax error corrector.//static location_t old_location;//  Point at which we should resume scanning when the corrector is done//////////  Parser has discovered a syntax error the corrector will be looking ahead.//  Save context, at first character of bad token (passed in).//  ASSUME bad token began on this line.//void prepare_to_correct(location_t where){    old_location = where;    scanner_peeking = true;    syntax_error_cnt++;}//////////  Corrector is looking ahead.  Restore saved context.  Leave the//  scanner_peeking flag on until unwanted tokens have been deleted with//  calls to scan.//void done_peeking(void){    current_line = old_location.line;    current_line->pointer = old_location.column;    for (input_buffer_t *t = current_line->next; t != NULL; t = t->next) {        // Reset pointers in all peeked-at lines.        t->pointer = 0;    }}//////////  Show that how_many tokens have been deleted.  Leave pointer at first//  character after the deletion.  Current_line points to the current line.//  The parser calls display_deletions before display_insertion.//void display_deletions(int how_many){    major_token_t       dum_id;    token_attrib_t      dum_attrs;    current_line->modified = true;    deletion_cnt += how_many;    for (int i = 0; i < how_many; i++) { // move past how_many tokens        dum_id = token_get(dum_attrs);        current_line->modified = true;        dum_attrs.location.line->buf.erase(dum_attrs.location.column,                                           dum_attrs.location.line->pointer                                           - dum_attrs.location.column);    }    // Next char will be first AFTER deletions.}//////////  Show that token has been inserted.  Put it before current_line^.pointer.//  Leave the pointer pointing after the change.  This code is really//  inefficient, but that's ok.//void display_insertion(string insertion){    insertion += ' ';    current_line->buf.insert(current_line->pointer, insertion);    current_line->modified = true;    insertion_cnt = insertion_cnt + 1;    current_line->pointer += insertion.length();    // Next char will be first after insertions.}//////////  Corrector is done inserting and deleting tokens, return to normal state.//void done_correcting(void){    scanner_peeking = false;}//////////////////////////////////////////////////////////////////////////////////  Manage listing and error messages.////////////  Utility routine called by both issue_error and issue_warning.//  Marks the source line and adds the message msg.  The mark looks like://  '-X------------------^', where the X is markChar and the caret appears//  at the location specified by loc.//static void issue_message(string msg, char markChar, location_t loc){    string    temp;    temp = "-";    temp += markChar;    for (int i = 0; i < 6 + loc.column; i++)    temp += '-';    temp += "^\n";    loc.line->messages += temp;    loc.line->messages += "  ";    loc.line->messages += msg;    loc.line->messages += "\n";}//////////  Issue non fatal error message and stop code generation.//void issue_error(location_t loc, string msg){    compile_ok = false;    if (++semantic_error_cnt > MAX_ERRORS)        die_compiler("Too many errors.  Compilation aborted.");    issue_message(msg, 'E', loc);}//////////  Issue warning message.//void issue_warning(location_t loc, string msg){    warning_cnt++;    issue_message(msg, 'W', loc);}//////////  Halt the program..//void halt(void){    cout << "* Program halted!\n" << flush;    exit(1999);}//////////  Print fatal error message and kill the compiler.//void die_compiler(string msg)    // NEED TO FIX CAST BELOW WHEN MOVING TO STANDARD STRINGS{    if (compiler_dying) {        cout << "Recursive call to procedure \"die_compiler\".\n";        halt();    }    compiler_dying = true;    flush_lines();    cout << msg << "\n";    halt();}//////////  Extract information from an input_buffer_t.//string get_line_info (const input_buffer_t *line, input_buffer_t *&next,                        int& line_num){    next = line->next;    line_num = line->line_num;    return line->origBuf;}//////////  Returns the line number of this location_t.//int location_t::get_lineno(void) const{    return line->line_num;}//////////  Returns the column number of this location_t.//int location_t::get_column(void) const{    return column;}// End of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -