rendered paste body#include <iostream>#include <vector>#include <list>#include <cstring>#include <cctype>#include "parser.h"using namespace std;namespace Iscas {const char *Parser::token_names[] = { "TK_ERR\0", "TK_SPACE\0", "TK_ENDLINE\0", "TK_LBRACE\0", "TK_RBRACE\0", "TK_COMMA\0", "TK_EQUAL\0", "TK_ELEM\0", "TK_NAME\0"};Parser::Parser(const std::string& file, Dispatcher* dispatcher) : m_fileName( file ), m_edgeNumber(0), m_dispatcher(dispatcher){ m_edgeNames.resize(10, string(10, 0));}int Parser::parse(){ m_infile.open( m_fileName.c_str() ); if ( !m_infile.is_open() ) { cerr << "File not fund, aborting" << endl; return -1; } m_infile.read(m_buf, chunk_size); m_size = m_infile.gcount(); parser_token token; parser_state state = ST_NULL; bool lbrace_found = false; bool rbrace_found = false; m_edgeNumber = 0; while ( ( token = get_token() ) != TK_ERR ) { switch (state) { case ST_NULL : { if (token == TK_ENDLINE) break; if (token == TK_ELEM) { if ( m_curElement == EL_INPUT ) state = ST_INPUT; else if ( m_curElement == EL_OUTPUT ) state = ST_OUTPUT; } else if ( token == TK_NAME ) { state = ST_LNAME; } else { cout << "Expected INPUT, OUTPUT or edge name" << endl; return -1; } break; } case ST_LNAME : { if (token = TK_SPACE) { state = ST_LNAME_SPACE; m_edgeNames[m_edgeNumber].assign( m_start, m_end - m_start ); ++m_edgeNumber; } else { cout << "Expected space" << endl; return -1; } break; } case ST_LNAME_SPACE : { if (token = TK_EQUAL) state = ST_LNAME_SPACE_EQUAL; else { cout << "Expected equal" << endl; return -1; } break; } case ST_LNAME_SPACE_EQUAL : { if (token = TK_SPACE) state = ST_LNAME_COMPLETE; else { cout << "Expected space" << endl; return -1; } break; } case ST_LNAME_COMPLETE : { if ( (token == TK_ELEM) && (m_curElement != EL_INPUT) && (m_curElement != EL_OUTPUT) ) { state = ST_ELEMENT_NAME; } break; } case ST_ELEMENT_NAME : { if (token == TK_LBRACE) state = ST_ELEMENT_NAME_LBRACE; break; } case ST_ELEMENT_NAME_LBRACE : { if (token == TK_NAME) { m_edgeNames[m_edgeNumber].assign( m_start, m_end - m_start ); ++m_edgeNumber; state = ST_ELEMENT_NAME_EDGE_NAME; } break; } case ST_ELEMENT_NAME_EDGE_NAME : { if (token == TK_RBRACE) { state = ST_ELEMENT_NAME_RBRACE; break; } if (token == TK_COMMA) state = ST_ELEMENT_NAME_EDGE_NAME_COMMA; break; } case ST_ELEMENT_NAME_EDGE_NAME_COMMA : { if (token == TK_SPACE) state = ST_ELEMENT_NAME_LBRACE; break; } case ST_ELEMENT_NAME_RBRACE : { if (token == TK_ENDLINE) { state = ST_NULL; m_dispatcher->dispatchElement(m_edgeNames, m_curElement, m_edgeNumber); m_edgeNumber = 0; } break; } case ST_INPUT : { if (token == TK_LBRACE) state = ST_INPUT_LBRACE; break; } case ST_INPUT_LBRACE : { if (token == TK_NAME) { state = ST_INPUT_EDGE_NAME; m_inputOutputName = string( m_start, m_end - m_start ); } break; } case ST_INPUT_EDGE_NAME : { if (token == TK_RBRACE) state = ST_INPUT_RBRACE; break; } case ST_INPUT_RBRACE : { if (token == TK_ENDLINE) { state = ST_NULL; m_dispatcher->dispatchInput(m_inputOutputName); } break; } case ST_OUTPUT: { if (token == TK_LBRACE) state = ST_OUTPUT_LBRACE; break; } case ST_OUTPUT_LBRACE: { if (token == TK_NAME) { state = ST_OUTPUT_EDGE_NAME; m_inputOutputName = string( m_start, m_end - m_start ); } break; } case ST_OUTPUT_EDGE_NAME: { if (token == TK_RBRACE) state = ST_OUTPUT_RBRACE; break; } case ST_OUTPUT_RBRACE : { if (token == TK_ENDLINE) { state = ST_NULL; m_dispatcher->dispatchOutput(m_inputOutputName); } break; } } } return 0;}Parser::parser_token Parser::get_token(){ static int offset = -1; static bool word = false; static bool comment = false; static int start = 0; while (m_size != 0) { while (++offset != m_size) { char *cur = m_buf + offset; if ( (comment == true) ) { if (*cur == '\n') comment = false; continue; } if ( *cur == '#' ) { comment = true; continue; } if (isalnum(*cur)) { if (word == false) start = offset; word = true; } else if ( word == true ) { word = false; int found = -1; int i; for ( i =0; ( (i < elements_number) && (found != 0) ); ++i ) { found = strncmp(element_names[i], m_buf + start, element_name_length[i]); } if (found == 0) { m_curElement = (logical_elements)(--i); --offset; return TK_ELEM; } else { m_start = m_buf + start; m_end = m_buf + offset; --offset; return TK_NAME; } } if (*cur == '=') { return TK_EQUAL; } if (*cur == ',') { return TK_COMMA; } if (*cur == ' ') { return TK_SPACE; } if (*cur == '\n') { return TK_ENDLINE; } if (*cur == '(') { return TK_LBRACE; } if (*cur == ')') { return TK_RBRACE; } } if (word == true) { m_infile.seekg(start - m_size, ios_base::cur); start = 0; } offset = -1; m_infile.read(m_buf, chunk_size); m_size = m_infile.gcount(); } return TK_ERR;}} //namespace Iscas