#ifdef _MSC_VER #pragma warning (disable:4244) #pragma warning (disable:4267) #pragma warning (disable:4102) #endif #include "nasal_new_lexer.h" bool lexer::skip(char c) { return c==' '||c=='\n'||c=='\t'||c=='\r'||c==0; } bool lexer::is_id(char c) { return (c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||(c<0); } bool lexer::is_hex(char c) { return ('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c && c<='F'); } bool lexer::is_oct(char c) { return '0'<=c&&c<='7'; } bool lexer::is_dec(char c) { return '0'<=c&&c<='9'; } bool lexer::is_str(char c) { return c=='\''||c=='\"'||c=='`'; } bool lexer::is_single_opr(char c) { return ( c=='('||c==')'||c=='['||c==']'|| c=='{'||c=='}'||c==','||c==';'|| c==':'||c=='?'||c=='`'||c=='@'|| c=='%'||c=='$'||c=='\\' ); } bool lexer::is_calc_opr(char c) { return ( c=='='||c=='+'||c=='-'||c=='*'|| c=='!'||c=='/'||c=='<'||c=='>'|| c=='~'||c=='|'||c=='&'||c=='^' ); } void lexer::skip_note() { // avoid note, after this process ptr will point to a '\n', so next loop line counter+1 while(++ptr is not a regular file"); err.chkerr(); } // load filename = file; std::ifstream in(file, std::ios::binary); if (in.fail()) { err.err("lexer", "failed to open <" + file + ">"); } else { err.load(file); } std::stringstream ss; ss << in.rdbuf(); res = ss.str(); } tok lexer::get_type(const std::string& str) { return typetbl.count(str)?typetbl.at(str):tok::null; } std::string lexer::utf8_gen() { std::string str=""; while(ptr"); err.fatal("lexer", "fatal error occurred, stop"); } str+=tmp; column+=2; // may have some problems because not all the unicode takes 2 space } return str; } token lexer::id_gen() { u32 begin_line=line; u32 begin_column=column; std::string str=""; while(ptr [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*) std::string str=""; while(ptr=res.size()) { err.err("lexer", {begin_line, begin_column, line, column, filename}, "get EOF when generating string"); return {{begin_line, begin_column, line, column, filename}, tok::str, str}; } ++column; if (begin=='`' && str.length()!=1) { err.err("lexer", {begin_line, begin_column, line, column, filename}, "\'`\' is used for string including one character"); } return {{begin_line, begin_column, line, column, filename}, tok::str, str}; } token lexer::single_opr() { u32 begin_line=line; u32 begin_column=column; std::string str(1,res[ptr]); ++column; tok type=get_type(str); if (type==tok::null) { err.err("lexer", {begin_line, begin_column, line, column, filename}, "invalid operator `"+str+"`"); } ++ptr; return {{begin_line, begin_column, line, column, filename}, type, str}; } token lexer::dots() { u32 begin_line=line; u32 begin_column=column; std::string str="."; if (ptr+2=res.size()) { break; } if (is_id(res[ptr])) { toks.push_back(id_gen()); } else if (is_dec(res[ptr])) { toks.push_back(num_gen()); } else if (is_str(res[ptr])) { toks.push_back(str_gen()); } else if (is_single_opr(res[ptr])) { toks.push_back(single_opr()); } else if (res[ptr]=='.') { toks.push_back(dots()); } else if (is_calc_opr(res[ptr])) { toks.push_back(calc_opr()); } else if (res[ptr]=='#') { skip_note(); } else { err_char(); } } toks.push_back({{line, column, line, column, filename}, tok::eof, ""}); res=""; return err; }