### Instruction:
Write a C++ program that:
    a. Implements a basic lexer and parser for a custom programming language.
    b. Evaluates expressions written in this language.
    c. Supports variables, arithmetic operations, and conditional statements (if-else).

### Response:

```cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <cctype>

enum TokenType {
    NUMBER, VAR, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, ASSIGN, IF, ELSE, END
};

struct Token {
    TokenType type;
    std::string value;
};

class Lexer {
public:
    explicit Lexer(const std::string &input) : input(input), pos(0) {}

    Token getNextToken() {
        while (pos < input.size()) {
            char ch = input[pos];
            if (std::isspace(ch)) {
                ++pos;
            } else if (std::isdigit(ch)) {
                return parseNumber();
            } else if (std::isalpha(ch)) {
                return parseIdentifier();
            } else {
                switch (ch) {
                    case '+':
                        ++pos;
                        return {PLUS};
                    case '-':
                        ++pos;
                        return {MINUS};
                    case '*':
                        ++pos;
                        return {MUL};
                    case '/':
                        ++pos;
                        return {DIV};
                    case '(':
                        ++pos;
                        return {LPAREN};
                    case ')':
                        ++pos;
                        return {RPAREN};
                    case '=':
                        ++pos;
                        return {ASSIGN};
                    default:
                        throw std::runtime_error("Invalid character");
                }
            }
        }
        return {END};
    }

private:
    Token parseNumber() {
        std::string numStr;
        while (pos < input.size() && std::isdigit(input[pos])) {
            numStr += input[pos++];
        }
        return {NUMBER, numStr};
    }

    Token parseIdentifier() {
        std::string identifier;
        while (pos < input.size() && std::isalnum(input[pos])) {
            identifier += input[pos++];
        }
        if (identifier == "if") {
            return {IF};
        } else if (identifier == "else") {
            return {ELSE};
        }
        return {VAR, identifier};
    }

    std::string input;
    size_t pos;
};

class Parser {
public:
    explicit Parser(Lexer &lexer) : lexer(lexer), currentToken(lexer.getNextToken()) {}

    int parse() {
        return expression();
    }

private:
    void eat(TokenType type) {
        if (currentToken.type == type) {
            currentToken = lexer.getNextToken();
        } else {
            throw std::runtime_error("Invalid syntax");
        }
    }

    int factor() {
        Token token = currentToken;
        if (token.type == NUMBER) {
            eat(NUMBER);
            return std::stoi(token.value);
        } else if (token.type == VAR) {
            eat(VAR);
            return variables[token.value];
        } else if (token.type == LPAREN) {
            eat(LPAREN);
            int result = expression();
            eat(RPAREN);
            return result;
        }
        throw std::runtime_error("Invalid syntax");
    }

    int term() {
        int result = factor();
        while (currentToken.type == MUL || currentToken.type == DIV) {
            Token token = currentToken;
            if (token.type == MUL) {
                eat(MUL);
                result *= factor();
            } else if (token.type == DIV) {
                eat(DIV);
                result /= factor();
            }
        }
        return result;
    }

    int expression() {
        int result = term();
        while (currentToken.type == PLUS || currentToken.type == MINUS) {
            Token token = currentToken;
            if (token.type == PLUS) {
                eat(PLUS);
                result += term();
            } else if (token.type == MINUS) {
                eat(MINUS);
                result -= term();
            }
        }
        return result;
    }

    Lexer &lexer;
    Token currentToken;
    std::map<std::string, int> variables;
};

int main() {
    std::string input = "x = 10 + 20 * (5 - 3)";
    Lexer lexer(input);
    Parser parser(lexer);

    try {
        int result = parser.parse();
        std::cout << "Result: " << result << std::endl;
    } catch (const std::runtime_error &e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;
}
```

This C++ program implements a basic lexer and parser for a custom programming language that supports variables, arithmetic operations, and conditional statements (if-else). The `Lexer` class is responsible for tokenizing the input string, while the `Parser` class evaluates expressions written in this language. Note that this implementation does not fully support if-else statements, but it provides a foundation to build upon.

To test the program, you can modify the `input` variable with different expressions.