Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#include <string>
#include <iostream>
#define CAPTURE_TOKEN(t) \
token->value = std::string(ts, te-ts); \
token->type = Token::t
%%{
machine ExampleLexer;
main := |*
digit+ => {
CAPTURE_TOKEN(Num);
fbreak;
};
alpha (alpha | digit) * => {
CAPTURE_TOKEN(Var);
fbreak;
};
'+' => {
CAPTURE_TOKEN(Plus);
fbreak;
};
space+;
*|;
}%%
%%write data;
struct Token
{
enum TokenType {
Var,
Num,
Plus,
End,
None
};
TokenType type;
std::string value;
};
class Lexer
{
public:
Lexer(std::string input)
: buffer(input) {
%%write init;
// set up the buffer here
p = buffer.c_str();
pe = p + buffer.size();
eof = pe;
}
Token* next() {
auto token = new Token();
token->type = Token::None;
do {
if (cs >= ExampleLexer_first_final) {
token->type = Token::End;
}
%%write exec;
if (cs == ExampleLexer_error) {
token->type = Token::None;
return token;
}
} while (token->type == Token::None);
return token;
}
private:
// buffer state
const char* p, * pe, * eof;
// current token
const char* ts, * te;
// machine state
int act, cs, top, stack[1];
std::string buffer;
};
int main(int argc, const char* argv[]) {
auto lex = Lexer("test + 123");
Token* token;
do {
token = lex.next();
std::cout << "<" << token->value << ">" << std::endl;
} while (token->type != Token::None &&
token->type != Token::End);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment