lib/antlr4-native/generator.rb in antlr4-native-1.0.2 vs lib/antlr4-native/generator.rb in antlr4-native-1.1.0

- old
+ new

@@ -61,11 +61,11 @@ File.write(interop_file, interop_code) end def interop_code <<~END - #include "iostream" + #include <iostream> #include "antlr4-runtime.h" #include "#{parser_ns}.h" #include "#{antlr_ns}BaseVisitor.h" @@ -74,16 +74,42 @@ #include "rice/Array.hpp" #include "rice/Class.hpp" #include "rice/Constructor.hpp" #include "rice/Director.hpp" + #ifdef _WIN32 + #undef FALSE + #undef TRUE + #undef OPTIONAL + #undef IN + #undef OUT + #endif + using namespace std; using namespace Rice; using namespace antlr4; #{proxy_class_declarations} + template <> + Object to_ruby<Token*>(Token* const &x) { + if (!x) return Nil; + return Data_Object<Token>(x, rb_cToken, nullptr, nullptr); + } + + template <> + Object to_ruby<tree::ParseTree*>(tree::ParseTree* const &x) { + if (!x) return Nil; + return Data_Object<tree::ParseTree>(x, rb_cParseTree, nullptr, nullptr); + } + + template <> + Object to_ruby<tree::TerminalNode*>(tree::TerminalNode* const &x) { + if (!x) return Nil; + return Data_Object<tree::TerminalNode>(x, rb_cTerminalNode, nullptr, nullptr); + } + class ContextProxy { public: ContextProxy(tree::ParseTree* orig) { this -> orig = orig; } @@ -94,10 +120,22 @@ std::string getText() { return orig -> getText(); } + Object getStart() { + auto token = ((ParserRuleContext*) orig) -> getStart(); + + return to_ruby(token); + } + + Object getStop() { + auto token = ((ParserRuleContext*) orig) -> getStop(); + + return to_ruby(token); + } + Array getChildren() { if (children == nullptr) { children = new Array(); if (orig != nullptr) { @@ -189,35 +227,11 @@ ]) .join("\n") end def conversions - @conversions ||= begin - context_conversions = contexts.map(&:conversions).join("\n") - - <<~END - template <> - Object to_ruby<Token*>(Token* const &x) { - if (!x) return Nil; - return Data_Object<Token>(x, rb_cToken, nullptr, nullptr); - } - - template <> - Object to_ruby<tree::ParseTree*>(tree::ParseTree* const &x) { - if (!x) return Nil; - return Data_Object<tree::ParseTree>(x, rb_cParseTree, nullptr, nullptr); - } - - template <> - Object to_ruby<tree::TerminalNode*>(tree::TerminalNode* const &x) { - if (!x) return Nil; - return Data_Object<tree::TerminalNode>(x, rb_cTerminalNode, nullptr, nullptr); - } - - #{context_conversions} - END - end + @conversions ||= contexts.map(&:conversions).join("\n") end def proxy_class_methods @proxy_class_methods ||= contexts.flat_map(&:proxy_class_methods).join("\n") end @@ -241,18 +255,25 @@ stream.close(); return parser; } - VALUE visit(VisitorProxy* visitor) { - visitor -> visit(this -> parser -> #{parser_root_method}()); + Object #{parser_root_method}() { + auto ctx = this -> parser -> #{parser_root_method}(); + #{capitalize(parser_root_method)}ContextProxy proxy((#{parser_ns}::#{capitalize(parser_root_method)}Context*) ctx); + return to_ruby(proxy); + } + + Object visit(VisitorProxy* visitor) { + auto result = visitor -> visit(this -> parser -> #{parser_root_method}()); + // reset for the next visit call this -> lexer -> reset(); this -> parser -> reset(); - return Qnil; + return result; } ~ParserProxy() { delete this -> parser; delete this -> tokens; @@ -294,25 +315,30 @@ void Init_#{ext_name}() { Module rb_m#{parser_ns} = define_module("#{parser_ns}"); rb_cToken = rb_m#{parser_ns} .define_class<Token>("Token") - .define_method("text", &Token::getText); + .define_method("text", &Token::getText) + .define_method("channel", &Token::getChannel) + .define_method("token_index", &Token::getTokenIndex); rb_cParser = rb_m#{parser_ns} .define_class<ParserProxy>("Parser") .define_singleton_method("parse", &ParserProxy::parse) .define_singleton_method("parse_file", &ParserProxy::parseFile) + .define_method("#{parser_root_method}", &ParserProxy::#{parser_root_method}) .define_method("visit", &ParserProxy::visit); rb_cParseTree = rb_m#{parser_ns} .define_class<tree::ParseTree>("ParseTree"); rb_cContextProxy = rb_m#{parser_ns} .define_class<ContextProxy>("Context") .define_method("children", &ContextProxy::getChildren) .define_method("child_count", &ContextProxy::childCount) .define_method("text", &ContextProxy::getText) + .define_method("start", &ContextProxy::getStart) + .define_method("stop", &ContextProxy::getStop) .define_method("parent", &ContextProxy::getParent) .define_method("==", &ContextProxy::doubleEquals); rb_cTerminalNode = rb_m#{parser_ns} .define_class<TerminalNodeProxy, ContextProxy>("TerminalNodeImpl");