4#include "antlr4-runtime.h"
7#include "OMDTreeVisitor.hpp"
8#include "io/Globals.hpp"
13class OMDErrorListener :
public antlr4::BaseErrorListener {
16 antlr4::Recognizer *recognizer,
17 antlr4::Token *offendingSymbol,
19 size_t charPositionInLine,
20 const std::string &msg,
23 std::cerr <<
"Syntax error at line " << line
24 <<
":" << charPositionInLine
25 <<
" - " << msg << std::endl;
33Globals* parseOmdFile(
const std::string& filename) {
36 std::ifstream stream(filename);
37 if (!stream.is_open()) {
38 std::cerr <<
"Failed to open file: " << filename << std::endl;
43 antlr4::ANTLRInputStream input(stream);
53 antlr4::CommonTokenStream tokens(&lexer);
59 OMDErrorListener errorListener;
60 parser.removeErrorListeners();
61 parser.addErrorListener(&errorListener);
67 if (parser.getNumberOfSyntaxErrors() > 0) {
68 std::cerr <<
"Parsing failed with "
69 << parser.getNumberOfSyntaxErrors()
70 <<
" errors" << std::endl;
76 Globals* conf = visitor.walkTree(tree);
80 }
catch (
const std::exception& e) {
81 std::cerr <<
"Exception during parsing: " << e.what() << std::endl;
87Globals* parseOmdString(
const std::string& input) {
90 antlr4::ANTLRInputStream inputStream(input);
96 antlr4::CommonTokenStream tokens(&lexer);
106 Globals* conf = visitor.walkTree(tree);
110 }
catch (
const std::exception& e) {
111 std::cerr <<
"Exception during parsing: " << e.what() << std::endl;
117int main(
int argc,
char* argv[]) {
119 std::cerr <<
"Usage: " << argv[0] <<
" <input.omd>" << std::endl;
123 std::string filename = argv[1];
125 std::cout <<
"Parsing file: " << filename << std::endl;
127 Globals* config = parseOmdFile(filename);
130 std::cout <<
"Parsing successful!" << std::endl;
137 std::cerr <<
"Parsing failed!" << std::endl;
149 int moleculeCount = 0;
152 virtual antlrcpp::Any visitMoleculeblock(OMDParser::MoleculeblockContext *ctx)
override {
154 std::cout <<
"Found molecule #" << moleculeCount << std::endl;
155 return OMDTreeVisitor::visitMoleculeblock(ctx);
158 virtual antlrcpp::Any visitAtomblock(OMDParser::AtomblockContext *ctx)
override {
160 std::cout <<
"Found atom #" << atomCount << std::endl;
161 return OMDTreeVisitor::visitAtomblock(ctx);
166void printParseTree(antlr4::tree::ParseTree* tree,
const OMDParser& parser,
int indent = 0) {
167 std::string indentStr(indent * 2,
' ');
169 if (
auto* terminalNode =
dynamic_cast<antlr4::tree::TerminalNode*
>(tree)) {
171 std::cout << indentStr <<
"TOKEN: " << terminalNode->getText() << std::endl;
172 }
else if (
auto* ruleNode =
dynamic_cast<antlr4::RuleContext*
>(tree)) {
174 std::string ruleName = parser.getRuleNames()[ruleNode->getRuleIndex()];
175 std::cout << indentStr <<
"RULE: " << ruleName << std::endl;
178 for (
size_t i = 0; i < ruleNode->children.size(); i++) {
179 printParseTree(ruleNode->children[i], parser, indent + 1);
185bool validateOmdFile(
const std::string& filename) {
186 std::ifstream stream(filename);
187 if (!stream.is_open()) {
191 antlr4::ANTLRInputStream input(stream);
193 antlr4::CommonTokenStream tokens(&lexer);
199 return parser.getNumberOfSyntaxErrors() == 0;
209class DetailedErrorListener :
public antlr4::BaseErrorListener {
211 std::vector<ParseError> errors;
214 antlr4::Recognizer *recognizer,
215 antlr4::Token *offendingSymbol,
217 size_t charPositionInLine,
218 const std::string &msg,
223 error.column = charPositionInLine;
225 errors.push_back(error);
229std::vector<ParseError> getParseErrors(
const std::string& filename) {
230 std::ifstream stream(filename);
231 antlr4::ANTLRInputStream input(stream);
233 antlr4::CommonTokenStream tokens(&lexer);
236 DetailedErrorListener errorListener;
237 parser.removeErrorListeners();
238 parser.addErrorListener(&errorListener);
242 return errorListener.errors;