xiiregexbuilder

FPGA-Accelerated Regular Expression Matching Engine

src/lexer.cpp (3317B)


 1#include "lexer.h"
 2#include <stdexcept>
 3
 4std::string tokenTypeToString(TokenType type) {
 5    switch (type) {
 6        case TokenType::LITERAL:   return "LITERAL";
 7        case TokenType::DOT:       return "DOT";
 8        case TokenType::STAR:      return "STAR";
 9        case TokenType::PLUS:      return "PLUS";
10        case TokenType::QUESTION:  return "QUESTION";
11        case TokenType::PIPE:      return "PIPE";
12        case TokenType::LPAREN:    return "LPAREN";
13        case TokenType::RPAREN:    return "RPAREN";
14        case TokenType::LBRACKET:  return "LBRACKET";
15        case TokenType::RBRACKET:  return "RBRACKET";
16        case TokenType::END_OF_INPUT: return "END_OF_INPUT";
17        default:                   return "UNKNOWN";
18    }
19}
20
21Lexer::Lexer(const std::string& input, int lineNum)
22    : input(input), pos(0), line(lineNum), col(1) {}
23
24char Lexer::peek() const {
25    if (isAtEnd()) return '\0';
26    return input[pos];
27}
28
29char Lexer::advance() {
30    char current = input[pos++];
31    col++;
32    return current;
33}
34
35bool Lexer::isAtEnd() const {
36    return pos >= input.length();
37}
38
39std::vector<Token> Lexer::tokenize() {
40    std::vector<Token> tokens;
41
42    while (!isAtEnd()) {
43        char c = peek();
44        int currentCharCol = col;
45
46        switch (c) {
47            case '\\':
48                advance(); // consume '\'
49                if (isAtEnd()) throw std::runtime_error("Trailing backslash");
50                tokens.emplace_back(TokenType::LITERAL, advance(), line, currentCharCol);
51                break;
52            case '.':
53                tokens.emplace_back(TokenType::DOT, advance(), line, currentCharCol);
54                break;
55            case '*':
56                tokens.emplace_back(TokenType::STAR, advance(), line, currentCharCol);
57                break;
58            case '+':
59                tokens.emplace_back(TokenType::PLUS, advance(), line, currentCharCol);
60                break;
61            case '?':
62                tokens.emplace_back(TokenType::QUESTION, advance(), line, currentCharCol);
63                break;
64            case '|':
65                tokens.emplace_back(TokenType::PIPE, advance(), line, currentCharCol);
66                break;
67            case '(':
68                tokens.emplace_back(TokenType::LPAREN, advance(), line, currentCharCol);
69                break;
70            case ')':
71                tokens.emplace_back(TokenType::RPAREN, advance(), line, currentCharCol);
72                break;
73            case '[':
74                tokens.emplace_back(TokenType::LBRACKET, advance(), line, currentCharCol);
75                break;
76            case ']':
77                tokens.emplace_back(TokenType::RBRACKET, advance(), line, currentCharCol);
78                break;
79            default:
80                if (c >= 32 && c <= 126) {
81                    tokens.emplace_back(TokenType::LITERAL, advance(), line, currentCharCol);
82                } else {
83                    throw std::runtime_error("Invalid character at line " + std::to_string(line) + 
84                                             ", column " + std::to_string(currentCharCol) + ": code " + std::to_string(static_cast<unsigned char>(c)));
85                }
86                break;
87        }
88    }
89
90    tokens.emplace_back(TokenType::END_OF_INPUT, '\0', line, col);
91    return tokens;
92}