Skip to content

Instantly share code, notes, and snippets.

@yhirose
Last active May 23, 2019 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yhirose/e9c365a63a5105327676fbcfb61cb5ad to your computer and use it in GitHub Desktop.
Save yhirose/e9c365a63a5105327676fbcfb61cb5ad to your computer and use it in GitHub Desktop.
ArrayInt Translator examples with ANTLR 4 and cpp-peglib
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <sstream>
#include "peglib.h"
using namespace peg;
using namespace std;
bool translate(const string& text, string& result) {
static parser parser(R"(
init <- '{' value (',' value)* '}'
value <- INT / init
INT <- < [0-9]+ >
%whitespace <- [ \t\r\n]*
)");
parser["init"].enter = [&](const char* s, size_t n, any& dt) {
result += '"';
};
parser["init"].leave = [&](const char* s, size_t n, size_t matchlen, any& value, any& dt) {
result += '"';
};
parser["value"] = [&](const SemanticValues& sv) {
stringstream ss;
ss << "\\u" << setfill ('0') << setw(4) << hex << stoi(sv.token());
result += ss.str();
};
return parser.parse(text.c_str());
}
int main(int argc, const char** argv) {
std::string text;
while (std::getline(cin, text)) {
string result;
if (translate(text, result)) {
cout << result << endl;
}
}
return 0;
}
#include <antlr4-runtime.h>
#include <iostream>
#include "ArrayInitBaseListener.h"
#include "ArrayInitLexer.h"
#include "ArrayInitParser.h"
using namespace antlr4;
using namespace std;
/*
init : '{' value (',' value)* '}' ;
value : init | INT ;
INT : [0-9]+ ;
WS : [ \t\r\n]+ -> skip ;
*/
class ShortToUnicodeString : public ArrayInitBaseListener {
public:
ShortToUnicodeString(string& result) : result_(result) {}
void enterInit(ArrayInitParser::InitContext* /*ctx*/) override {
result_ += '"';
}
void exitInit(ArrayInitParser::InitContext* /*ctx*/) override {
result_ += '"';
}
void enterValue(ArrayInitParser::ValueContext* ctx) override {
stringstream ss;
ss << "\\u" << setfill('0') << setw(4) << hex
<< stoi(ctx->INT()->getText());
result_ += ss.str();
}
string& result_;
};
class ErrorListener : public BaseErrorListener {
public:
void syntaxError(Recognizer* recognizer, Token* offendingSymbol, size_t line,
size_t charPositionInLine, const std::string& msg,
std::exception_ptr e) override {
throw runtime_error(msg);
}
};
bool translate(const string& text, string& result) {
ANTLRInputStream input(text.data(), text.size());
ArrayInitLexer lexer(&input);
lexer.removeErrorListener(&ConsoleErrorListener::INSTANCE);
CommonTokenStream tokens(&lexer);
ArrayInitParser parser(&tokens);
ErrorListener errorListener;
parser.removeErrorListener(&ConsoleErrorListener::INSTANCE);
parser.addErrorListener(&errorListener);
try {
auto tree = parser.init();
tree::ParseTreeWalker walker;
ShortToUnicodeString shortToUnicodeString(result);
walker.walk(&shortToUnicodeString, tree);
} catch (...) {
return false;
}
return true;
}
int main(int argc, const char** argv) {
std::string text;
while (std::getline(cin, text)) {
string result;
if (translate(text, result)) {
cout << result << endl;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment