From 75f71259a083ea785912e3d97273571d8be9afb3 Mon Sep 17 00:00:00 2001 From: Atreya Bain Date: Fri, 30 Oct 2020 20:35:01 +0530 Subject: [PATCH] introduce transpile to cpp --- .vscode/launch.json | 19 +++++++ CMakeLists.txt | 1 + README.md | 14 +++-- include/toBFListener.hpp | 2 + include/toCPPListener.hpp | 27 ++++++++++ samples/test.bfe | 48 +++++++++++++++++ src/main.cpp | 107 +++++++++++++++++++++++--------------- src/toBFListener.cpp | 11 ++++ src/toCPPListener.cpp | 79 ++++++++++++++++++++++++++++ 9 files changed, 263 insertions(+), 45 deletions(-) create mode 100644 include/toCPPListener.hpp create mode 100644 samples/test.bfe create mode 100644 src/toCPPListener.cpp diff --git a/.vscode/launch.json b/.vscode/launch.json index f54449a..7d2ae92 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -47,6 +47,25 @@ } ] }, + { + "name": "GDB - simple.bfe - Translate to BF", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/main.out", + "args": ["samples/simple.bfe","-a","bf"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, { "name": "GDB - group.bfe", "type": "cppdbg", diff --git a/CMakeLists.txt b/CMakeLists.txt index f84838f..0bc321f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) set(SOURCES src/main.cpp src/toBFListener.cpp + src/toCPPListener.cpp src/executeBFE.cpp lib/generated/bfeLexer.cpp lib/generated/bfeParser.cpp diff --git a/README.md b/README.md index 61367b0..3e28317 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # (+97>)3<3+>+5>+2<2(.>)3 (*.bfe) -An extension of a language that shall not be named +A slight syntactic superset of BF. -Requires: +Development requirements: 1. cxxopts -> v2.2.1 2. antlr4 @@ -12,12 +12,20 @@ Requires: -[-7>+<]>-.-[->+5<]>++.+7..+3.[-3>+<]>-5.--[->+4<]>-.-8.+3.-6.-8. ``` +## Functions + +1. Interpret bfe(and bf) files +2. Convert bf/bfe to bf +3. Convert bf/bfe to C++ (not optimized) + + ## Usage ```sh ./bfc -h #Help ./bfc prog.bfe #Execute -./bfc prog.bfe -t #Translate file to bf +./bfc prog.bfe -a bf #Translate file to bf +./bfc prog.bfe -a cpp # Translate file to cpp ``` ## Syntax diff --git a/include/toBFListener.hpp b/include/toBFListener.hpp index 08ab789..08d5fa9 100644 --- a/include/toBFListener.hpp +++ b/include/toBFListener.hpp @@ -22,4 +22,6 @@ class toBFListener : public bfeBaseListener { void exitLoopStmt(bfeParser::LoopStmtContext *ctx) override; void enterGroupedStmt(bfeParser::GroupedStmtContext *ctx) override; void exitGroupedStmt(bfeParser::GroupedStmtContext *ctx) override; + void enterOutputStmt(bfeParser::OutputStmtContext *ctx) override; + void enterInputStmt(bfeParser::InputStmtContext *ctx) override; }; \ No newline at end of file diff --git a/include/toCPPListener.hpp b/include/toCPPListener.hpp new file mode 100644 index 0000000..7dd6a77 --- /dev/null +++ b/include/toCPPListener.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "bfeLexer.h" +#include "bfeParser.h" +#include "bfeBaseListener.h" + + +class toCPPListener : public bfeBaseListener { + protected: + std::vector printStack; + public: + void enterProgram(bfeParser::ProgramContext *ctx) override; + void exitProgram(bfeParser::ProgramContext *ctx) override ; + void enterPtrIncr(bfeParser::PtrIncrContext *ctx) override; + void enterPtrDecr(bfeParser::PtrDecrContext *ctx) override; + void enterPtrLeft(bfeParser::PtrLeftContext *ctx) override; + void enterPtrRight(bfeParser::PtrRightContext *ctx) override; + void enterNumberedStmt(bfeParser::NumberedStmtContext *ctx) override; + void exitNumberedStmt(bfeParser::NumberedStmtContext *ctx) override; + void enterLoopStmt(bfeParser::LoopStmtContext *ctx) override; + void exitLoopStmt(bfeParser::LoopStmtContext *ctx) override; + void enterGroupedStmt(bfeParser::GroupedStmtContext *ctx) override; + void exitGroupedStmt(bfeParser::GroupedStmtContext *ctx) override; + void enterOutputStmt(bfeParser::OutputStmtContext *ctx) override; + void enterInputStmt(bfeParser::InputStmtContext *ctx) override; +}; \ No newline at end of file diff --git a/samples/test.bfe b/samples/test.bfe new file mode 100644 index 0000000..98e6fff --- /dev/null +++ b/samples/test.bfe @@ -0,0 +1,48 @@ +>,<>>,>,<[->- + >+<><<]+->>[-<<+>>] + <+-><><<<[-+->-<+-<+>]< + [->+<]><>>>>>><>++->>+->> + >>>+[>><>>>[-]<[-<>-+]<<>[- + +-]-++-+-< [-]<><<>[+ + ---+]<><< <<+-<<<<> + -+<><<<> <+-<<[-> + >>>>>>+ >>>>>-+ + >+<<<>< < <><<<<< + <<<<]>[ ->> >>><><> + ><>>+>> >>>>+ <<<<<>< + <<<<+-< <<<]> [->>>>> + >><>+ + >>>>- + +><>> + +<<<< + <<+-< + <<<><<<< -+><] >>-++-+>+-+[<-] <[->> + <>++-<<<]>>>> [-<<< +--+<<<<+>><>>> >>>]> + [-<<-+<<<<<+<>> +->>> >>>]>[-<<<<><<< ><<+> + >>>>>>]>>>>>><>>+ [-<<< <+--+<><+-<<<<< <[->> + +>>+<<<<]+->[->>+>> +-+<< <<]>[-<<+>>]>[- <<+>> + ]+[[<>-]-++>[<-]<+-[ +-->< >><>-<<<]>>-+-> >>+>[ + <-]<+-[- >+>[- <-]<[ >>[-< <-+-> + ]-<<[-> ><- >+->- +-<<< <]]<] + >>-<<< < <+>[> <<-]< [>+-> +[-+<<- >]<<[ <]]>- +-]>> +>>><>> >><>+ ]-<<< >+-<< +<>+>- ++[<- ]<[-+ >>+[< +<<>-> -+]<< [>>>+ [<-+< +<->>] <<<[< ]]]>- ]>>>> +[-]<< <<<<< -+<>< <<<<< +<[-]> >+>+[ <-]<[ ->>+< +><<<] >+>[< -]<[> >[<<- +>]<<[ <]]>- [+>>> >>>>< +++-++ +++++ ++<<< <<<+> ++-[<<> -]<[> >[<<- >]<<[ +<]]>-[ ++>[< -]<[- >>-<< + <]>>-> > +>>+> -[<-] <[<<[ + ->>>+<< ><< ]+->> >>>+> +[<>< + -]<><[-> >+<<< ]<<-< ]<<<< +>[<- + ]<[>>[<<->]<<[<]]>-] >>+++ +++++[ -> +++++ + +<]>[-<<<<+>>>>]>>> >>+>< >-+[<-]<[>> [<<-> + ]<<[<]]>-[++>[<-] <[->> -<<<]>>-<<< <<<<< + +>+[<-]<[->>+<< <]>>> >>>>>+>[<- ]<[>> + [<<->]<<[<]]> -]<<[ -]<<<<<+> [<-]< + [>>[<<-> ]<<[< ]]>-]<< [.<] \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index bac1d72..96ecd4c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "bfeLexer.h" #include "bfeParser.h" #include "toBFListener.hpp" +#include "toCPPListener.hpp" #include "executeBFE.hpp" using namespace antlr4; @@ -16,54 +17,76 @@ int main(int argc, char **argv) cxxopts::Options options(argv[0], "An interpreter/translator for bfe"); options.add_options() - ("t,translate", "Translate to bf", cxxopts::value()->default_value("false")) - ("i,input", "Input(First argument)", cxxopts::value()) - ("h,help", "Print usage"); + ("a,action", "Action (exec,cpp,bf)", cxxopts::value()->default_value("exec")) + ("i,input", "Input (First argument)", cxxopts::value()) + ("h,help", "Print usage"); options.parse_positional({"input"}); - auto results = options.parse(argc, argv); - if (results.count("help")) + // try { - std::cout << options.help() << std::endl; - return 0; - } - if (results.count("input")) - { - // std::cout << results["input"].as()<()); - if (stream.fail()) + auto results = options.parse(argc, argv); + std::string action = results["action"].as(); + if (action.compare("exec") && action.compare("bf") && action.compare("cpp")) { - std::cout << "Could not open" << std::endl; + action = std::string( "exec"); + } + if (results.count("help")) + { + std::cout << options.help() << std::endl; + return 0; + } + if (results.count("input")) + { + // std::cout << results["input"].as()<()); + if (stream.fail()) + { + std::cout << "Could not open" << std::endl; + return 1; + } + ANTLRInputStream input(stream); + bfeLexer lexer(&input); + CommonTokenStream tokens(&lexer); + bfeParser parser(&tokens); + + tree::ParseTree *tree = parser.program(); + if (action.compare("bf")==0) + { + toBFListener listener; + tree::ParseTreeWalker::DEFAULT.walk(&listener, tree); + } + else if (action.compare( "exec")==0) + { + executeBGE *visitor = new executeBGE(); + try + { + visitor->visit(tree); + std::cout << std::endl; + } + catch (std::string e) + { + std::cout << "\nIllegal:" << e << std::endl; + } + } + else + { + //else cpp + toCPPListener listener; + tree::ParseTreeWalker::DEFAULT.walk(&listener, tree); + } + } + else + { + std::cout << "?:Expected file" << std::endl; return 1; } - ANTLRInputStream input(stream); - bfeLexer lexer(&input); - CommonTokenStream tokens(&lexer); - bfeParser parser(&tokens); - - tree::ParseTree *tree = parser.program(); - if(results["translate"].as()){ - toBFListener listener; - tree::ParseTreeWalker::DEFAULT.walk(&listener, tree); - }else{ - executeBGE *visitor = new executeBGE(); - try - { - visitor->visit(tree); - std::cout << std::endl; - } - catch (std::string e) - { - std::cout << "\nIllegal:" << e<2 && ) return 0; diff --git a/src/toBFListener.cpp b/src/toBFListener.cpp index 8b6be9d..79c7a67 100644 --- a/src/toBFListener.cpp +++ b/src/toBFListener.cpp @@ -29,6 +29,12 @@ void toBFListener::enterPtrRight(bfeParser::PtrRightContext *ctx) { printStack.back() += (">"); } +void toBFListener::enterOutputStmt(bfeParser::OutputStmtContext *ctx) { + printStack.back() += ("."); +} +void toBFListener::enterInputStmt(bfeParser::InputStmtContext *ctx) { + printStack.back() += (","); +} void toBFListener::enterNumberedStmt(bfeParser::NumberedStmtContext *ctx) { @@ -44,9 +50,14 @@ void toBFListener::exitNumberedStmt(bfeParser::NumberedStmtContext *ctx) printStack.back() += s; } } + + + void toBFListener::enterLoopStmt(bfeParser::LoopStmtContext *ctx){ printStack.push_back(""); } + + void toBFListener::exitLoopStmt(bfeParser::LoopStmtContext *ctx){ std::string s = printStack.back(); printStack.pop_back(); diff --git a/src/toCPPListener.cpp b/src/toCPPListener.cpp new file mode 100644 index 0000000..6b16703 --- /dev/null +++ b/src/toCPPListener.cpp @@ -0,0 +1,79 @@ +#include "bfeParser.h" +#include "bfeBaseListener.h" +#include "toCPPListener.hpp" +// #include "bfBaseVisitor.h" + +using namespace antlr4; + +void toCPPListener::enterProgram(bfeParser::ProgramContext *ctx) +{ + printStack.push_back("#include\n#include\nusing namespace std;\nint main(){\nvector vec(1000,0);int ptr = 0;\n"); +} +void toCPPListener::exitProgram(bfeParser::ProgramContext *ctx) +{ + std::cout << printStack.front() << "}\n"<< std::endl; +} +void toCPPListener::enterPtrIncr(bfeParser::PtrIncrContext *ctx) +{ + // printStack.back() += "+"; + printStack.back()+= "vec[ptr]++;\n"; +} +void toCPPListener::enterPtrDecr(bfeParser::PtrDecrContext *ctx) +{ + // printStack.back() += ("-"); + printStack.back()+= "vec[ptr]--;\n"; +} +void toCPPListener::enterPtrLeft(bfeParser::PtrLeftContext *ctx) +{ + // printStack.back() += ("<"); + printStack.back() += ("ptr--;\n"); +} +void toCPPListener::enterPtrRight(bfeParser::PtrRightContext *ctx) +{ + + printStack.back() += ("ptr++;\n"); +} + +void toCPPListener::enterNumberedStmt(bfeParser::NumberedStmtContext *ctx) +{ + printStack.push_back(""); +} +void toCPPListener::exitNumberedStmt(bfeParser::NumberedStmtContext *ctx) +{ + std::string s = printStack.back(); + printStack.pop_back(); + int n = stoi(ctx->NUMBER()->getText()); + for (int i = 0; i < n; i++) + { + printStack.back() += s; + } +} +void toCPPListener::enterLoopStmt(bfeParser::LoopStmtContext *ctx){ + printStack.push_back(""); +} +void toCPPListener::exitLoopStmt(bfeParser::LoopStmtContext *ctx){ + std::string s = printStack.back(); + printStack.pop_back(); + printStack.back()+= "while(vec[ptr]){\n"+s+"}\n"; +} + +void toCPPListener::enterOutputStmt(bfeParser::OutputStmtContext *ctx){ + std::string s = printStack.back(); + // printStack.pop_back(); + printStack.back()+= "cout<