2017-04-10 10 views
1

私はC++を使用してChip-8アセンブリ用のレクサーを作成していますが、常に3番目のトークンをスキップします。lexerは最後のトークンをスキップし続けます

例えば(My機能アセンブリの一行を読み込む)

ADD V1,V2

それだけV2をスキップし、トークンとして、V1を追加見つけます。 同じ

DRW V3,V4,2

それだけDRW、V3、V4 はどこ私は間違っ見つけましたか?

#include <fstream> 
#include <sstream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <exception> 
#include <iostream> 
#include <iterator> 
static std::string C8InsTable[] = {"ADD", "SUB", "SUBN", "AND", "OR", "XOR", 
    "SE", "SNE", "SYS", "JP", "LD", "DRW", 
    "SKP", "CALL", "CLS", "RET"}; //Instruction Table 
static const std::string C88BitReg[] = {"V1", "V2", "V3", "V4", "V5", 
      "V6", "V7", "V8", "V9", "VA", 
      "VB", "VC", "VD", "VE", "VF"}; //Name of Regsiters 
//Define Exceptions 
class LexEmptyExc : public std::runtime_error { 
public: 
    LexEmptyExc() : runtime_error("Empty Line."){}; 
    virtual const char* what() const throw() { return runtime_error::what();} 
} LexEE; 
class LexErrorVar : public std::runtime_error { 
public: 
    LexErrorVar() 
    : runtime_error("Error var type.Out of range or not a valid var."){}; 
    virtual const char* what() const throw() { 
     return runtime_error::what();}}LexEV; 

class LexErrorToken : public std::runtime_error { 
public: 
    LexErrorToken() : runtime_error("Error Token."){}; 
    virtual const char* what() const throw() { return runtime_error::what(); } 
    } LexET; 
//To write Log (Test purpose) 
bool LexerLogWriter(std::string LogLine, std::ofstream& LexerLogFile) { 
    if (!LexerLogFile.good()) 
    return false; 
    else { 
    LexerLogFile << LogLine; 
    return true; 
    } 
}; 
//It returns Tokens into a string vector 
std::vector<std::string> lexer(std::string ProgLine, 
std::ofstream& LexerLogFile) { 
    try { 
    if (ProgLine.length() == 0) throw LexEE; 
    bool IsVar = false; 
    bool Is8BitReg = false; 
    bool IsIns = false; 
    std::stringstream LogStream; 
    std::string Token(""); 
    std::string Var(""); 
    std::vector<std::string> TokenList; 
    std::string param(""); 
    for (auto& x : ProgLine) { 
    std::string LogType; 
    if ((x != ',' && x != ' ')){ //Skip spaces and commas 
     Token += x; 
     std::cout << "Now Token is " << Token << "(lexing)" << std::endl; 
    } else{ 
     if (find(std::begin(C8InsTable), std::end(C8InsTable), Token) !=std::end(C8InsTable)) { //Find Instruction 
     LogType = "Instruction"; 
    } else if (find(std::begin(C88BitReg), std::end(C88BitReg), Token) !=std::end(C88BitReg)) { 
     LogType = "8 Bit Register"; 
    } else if (Token == "DT") { 
     LogType = "Delay Timer"; 
    } else if (Token == "ST") { 
     LogType = "Sound Timer"; 
    } else if (Token == "I") { 
    LogType = "Address Register"; 
    } else { 
     if (Token.length() <= 4) { //4~16bitvar 
     LogType = "Var"; 
     } else { //Var bigger than 16bit-max 
      LogStream << "Error:Invalid var exist." << std::endl; 
      throw LexEE; 
      } 
     } 
     std::cout << "Now Token is " << Token << "(not lexing)" << std::endl; 
     if (!LogType.empty()) { //Is correct token 
     LogStream << LogType << " found: " << Token << std::endl; 
     LogType = ""; 
     std::cout << "Pushing " << Token << "..." << std::endl; 
     TokenList.push_back(Token); 
     Token = ""; //clear the string to store next one 
    } 
    } 
} 
    if (!LogStream.str().empty() && LexerLogFile.good()) 
    LexerLogWriter(LogStream.str(), LexerLogFile); //Write logs 
    return TokenList; 
    } catch (std::exception& e) { 
    std::cerr << "Error occured!Error info: " << e.what() << std::endl; 
    } 
    } 
//Test Main Func 
int main() { 
std::ofstream a("Test.log"); //Output log file 
std::ifstream b("test.asm"); //Infile 
for (std::string s; getline(b, s, '\n');) 
for (auto x : lexer(s, a)) std::cout << x << std::endl; 
    return 0; 
} 

ありがとうございます!私は

if ((x == ',' || x == ' ' || &x == &ProgLine.back())) 

に枝

if ((x == ',' && x == ' ')) 

を変更した後に実際に

+0

私は初めてStackOverflowで質問しています。私のコードを貼り付けるのに問題があります。すでにフォーマットされているコードブロックを挿入するには?私はこのような長い時間を自分のコードにスペースを追加するのに費やしました。 –

+0

'(x!= '、' && x!= '')'で改行(または文字列の終わり)もチェックしようとしましたか?最後のトークンが読み込まれますが、 "else"の場合は残っていないので、処理されません。 (末尾の ""を追加しても助けになるかもしれませんが、それはうんざりでしょう) – Tommylee2k

答えて

1

は、その後、それが動作します。

+0

最初のバージョンは決して意味がありません。変数は同時に2つの値を持つことはできません。 – EJP

関連する問題