Last active
May 23, 2019 14:48
-
-
Save yhirose/e9c365a63a5105327676fbcfb61cb5ad to your computer and use it in GitHub Desktop.
ArrayInt Translator examples with ANTLR 4 and cpp-peglib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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