5 minute read

parser만들기

command, data가 들어왔을때 해당 command에 대해서 파싱하는 함수를 클래스를 만들어서 처리함.

1.	클래스 정의:
	•	Parser 클래스는 생성자에서 커맨드 문자열을 해당 함수에 매핑합니다.
	•	parseData 메서드는 두 개의 인자 (command와 data)를 받아서 데이터를 파싱하고 적절한 함수를 호출합니다.
	•	logError 메서드는 오류 메시지를 로그 파일에 기록합니다.
2.	함수 통합:
	•	각 함수는 prefix와 data를 인자로 받아 처리합니다.
	•	모든 함수는 데이터와 함께 prefix를 출력합니다.
3.	main 파일:
	•	Parser 객체를 생성하고, 예제 데이터를 사용하여 parseData 메서드를 호출합니다.
	•	알 수 없는 커맨드를 예제로 추가하여 오류 로깅 기능을 시연합니다.

다음 단계:
 a. 다양한 데이터 샘플을 추가하여 파서를 테스트하세요.
 b. 유효하지 않은 입력 및 알 수 없는 커맨드에 대한 포괄적인 오류 처리를 추가하세요.

parser.hpp

#ifndef PARSER_H
#define PARSER_H

#include <iostream>
#include <string>
#include <unordered_map>
#include <functional>
#include <fstream>

class Parser {
public:
    Parser();
    void parseData(const std::string& command, const std::string& data);

private:
    void ArmSetDeltaMove(const std::string& prefix, const std::string& data);
    void ArmEndDeltaMove(const std::string& prefix, const std::string& data);
    void ArmDeltaMove(const std::string& prefix, const std::string& data);
    void ArmPositionMove(const std::string& prefix, const std::string& data);
    void ArmRequestPosition(const std::string& prefix, const std::string& data);
    void HandOpen(const std::string& prefix, const std::string& data);
    void HandApproach(const std::string& prefix, const std::string& data);
    void HandGrasp(const std::string& prefix, const std::string& data);
    void BehaviorFail(const std::string& prefix, const std::string& data);
    void Retry(const std::string& prefix, const std::string& data);
    void Status(const std::string& prefix, const std::string& data);
    void Run(const std::string& prefix, const std::string& data);
    void Position(const std::string& prefix, const std::string& data);

    void logError(const std::string& errorMessage);

    std::unordered_map<std::string, std::function<void(const std::string&, const std::string&)>> actionMap;
};

#endif // PARSER_H

parser.cpp

#include "Parser.h"

Parser::Parser() {
    actionMap = {
        {"ASD", std::bind(&Parser::ArmSetDeltaMove, this, std::placeholders::_1, std::placeholders::_2)},
        {"AED", std::bind(&Parser::ArmEndDeltaMove, this, std::placeholders::_1, std::placeholders::_2)},
        {"ADM", std::bind(&Parser::ArmDeltaMove, this, std::placeholders::_1, std::placeholders::_2)},
        {"APM", std::bind(&Parser::ArmPositionMove, this, std::placeholders::_1, std::placeholders::_2)},
        {"ARP", std::bind(&Parser::ArmRequestPosition, this, std::placeholders::_1, std::placeholders::_2)},
        {"HOP", std::bind(&Parser::HandOpen, this, std::placeholders::_1, std::placeholders::_2)},
        {"HAP", std::bind(&Parser::HandApproach, this, std::placeholders::_1, std::placeholders::_2)},
        {"HGR", std::bind(&Parser::HandGrasp, this, std::placeholders::_1, std::placeholders::_2)},
        {"BFA", std::bind(&Parser::BehaviorFail, this, std::placeholders::_1, std::placeholders::_2)},
        {"TRY", std::bind(&Parser::Retry, this, std::placeholders::_1, std::placeholders::_2)},
        {"STA", std::bind(&Parser::Status, this, std::placeholders::_1, std::placeholders::_2)},
        {"RUN", std::bind(&Parser::Run, this, std::placeholders::_1, std::placeholders::_2)},
        {"POS", std::bind(&Parser::Position, this, std::placeholders::_1, std::placeholders::_2)},
    };
}

void Parser::parseData(const std::string& command, const std::string& data) {
    if (command.size() != 4) {
        logError("Invalid command size: " + command);
        return;
    }

    std::string prefix(1, command[0]);
    std::string action = command.substr(1, 3);

    if (actionMap.find(action) != actionMap.end()) {
        std::cout << "Prefix: " << prefix << std::endl;
        std::cout << "Action: " << action << std::endl;
        actionMap[action](prefix, data);
    } else {
        logError("Unknown action: " + action);
    }
}

void Parser::ArmSetDeltaMove(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-ArmSetDeltaMove with data: " << data << std::endl;
}

void Parser::ArmEndDeltaMove(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-ArmEndDeltaMove with data: " << data << std::endl;
}

void Parser::ArmDeltaMove(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-ArmDeltaMove with data: " << data << std::endl;
}

void Parser::ArmPositionMove(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-ArmPositionMove with data: " << data << std::endl;
}

void Parser::ArmRequestPosition(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-ArmRequestPosition with data: " << data << std::endl;
}

void Parser::HandOpen(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-HandOpen with data: " << data << std::endl;
}

void Parser::HandApproach(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-HandApproach with data: " << data << std::endl;
}

void Parser::HandGrasp(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-HandGrasp with data: " << data << std::endl;
}

void Parser::BehaviorFail(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-BehaviorFail with data: " << data << std::endl;
}

void Parser::Retry(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-Retry with data: " << data << std::endl;
}

void Parser::Status(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-Status with data: " << data << std::endl;
}

void Parser::Run(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-Run with data: " << data << std::endl;
}

void Parser::Position(const std::string& prefix, const std::string& data) {
    std::cout << "Handling " << prefix << "-Position with data: " << data << std::endl;
}

void Parser::logError(const std::string& errorMessage) {
    std::cerr << errorMessage << std::endl;
    std::ofstream errorLog("error_log.txt", std::ios_base::app);
    if (errorLog.is_open()) {
        errorLog << errorMessage << std::endl;
    }
}

main.cpp

#include "Parser.h"

int main() {
    Parser parser;

    // Example data inputs
    std::string command1 = "LASD";
    std::string data1 = "additionalDataForASD";
    
    std::string command2 = "RHOP";
    std::string data2 = "additionalDataForHOP";

    std::string command3 = "XUNK";  // Unknown command example
    std::string data3 = "additionalDataForUnknown";

    parser.parseData(command1, data1);
    parser.parseData(command2, data2);
    parser.parseData(command3, data3);

    return 0;
}

data parser

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

// 데이터 파싱 함수
std::vector<float> parseData(const std::string& data) {
    std::vector<float> result;
    std::istringstream iss(data);
    std::string token;

    while (std::getline(iss, token, ',')) {
        try {
            float value = std::stof(token);
            result.push_back(value);
        } catch (const std::exception& e) {
            // 파싱 오류 처리
            std::cerr << "파싱 오류: " << e.what() << std::endl;
        }
    }

    return result;
}

int main() {
    std::string data = "[200.2,-130.2,0,200,180.0,0,180.0]";
    std::vector<float> parsedValues = parseData(data);

    if (parsedValues.size() == 7) {
        float x = parsedValues[0];
        float y = parsedValues[1];
        float z = parsedValues[2];
        float rx = parsedValues[3];
        float ry = parsedValues[4];
        float rz = parsedValues[5];

        // 변수 사용 예시
        std::cout << "x = " << x << std::endl;
        std::cout << "y = " << y << std::endl;
        std::cout << "z = " << z << std::endl;
        std::cout << "rx = " << rx << std::endl;
        std::cout << "ry = " << ry << std::endl;
        std::cout << "rz = " << rz << std::endl;
    } else {
        std::cerr << "잘못된 데이터 형식입니다." << std::endl;
    }

    return 0;
}

comm.cpp

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

// 데이터를 문자열로 변환하는 함수
std::string createDataString(float x, float y, float z, float rx, float ry, float rz) {
    std::ostringstream oss;
    oss << "[" << x << "," << y << "," << z << "," << rx << "," << ry << "," << rz << "]";
    return oss.str();
}

int main() {
    float x = 200.2;
    float y = -130.2;
    float z = 0;
    float rx = 200;
    float ry = 180.0;
    float rz = 180.0;

    std::string dataString = createDataString(x, y, z, rx, ry, rz);
    std::cout << "생성된 데이터 문자열: " << dataString << std::endl;

    return 0;
}

Tags:

Categories:

Updated: