zoukankan      html  css  js  c++  java
  • ANTLR4将BF翻译成CPP

    实验环境

      操作系统:windows 10

      JAVAJDK 1.8

      antlrantlr-4.7.1-complete.jar

      IDE:IntelliJ IDEA 2017.2.7


     实验目的

      实现一种语言的翻译器,将输入的源语言的程序翻译成目标语言程序。

      本次实验中用到了开源的语法分析器——anltr4,由上述的文法设计编译好文法文件,通过antlr处理.g 文件可生成对应的词法分析器和语法分析器的java文件。最终通过java文件的编写实现翻译器。


    实验选题

      源语言:BF(Brainfuck)  忽略这个名字吧...

      目标语言:C++

      测试程序:1、HelloWorld程序

           2、斐波那契数列计算

      C++BF语法对比:

        BF是一种极小化的语言。它的表达能力较C++小很多,所以可以将所有的BF程序翻译为C++程序。对于BF语言的语法:传送门;对于C++的语法,大家就比较熟悉了。


    文法设计

      设计原则:通过代码嵌套进行分层,以代码作用进行模块划分。


     具体实现

    grammar BF;
    
    program
        : statement*
        ;
    
    statement
        : clause  # symbol
        | '[' statement* ']'  # middle
        ;
    
    clause
        : '+'  # plus
        | '-'  # reduce
        | '<'  # less
        | '>'  # great
        | '.'  # point
        | ','  # comma
        ;
    
    WS : [ 	
    
    ]+ -> skip ;
    BF.g4
    import org.antlr.v4.runtime.CharStream;
    import org.antlr.v4.runtime.CharStreams;
    import org.antlr.v4.runtime.CommonTokenStream;
    import org.antlr.v4.runtime.tree.ParseTree;
    import org.antlr.v4.runtime.tree.ParseTreeProperty;
    import org.antlr.v4.runtime.tree.ParseTreeWalker;
    
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.PrintStream;
    
    class translator extends BFBaseListener{
    
        public ParseTreeProperty<String> BF = new ParseTreeProperty<String>();
        String getBF(ParseTree ctx){
            return BF.get(ctx);
        }
        void setBF(ParseTree ctx, String s){
            BF.put(ctx, s);
        }
    
        @Override
        public void exitComma(BFParser.CommaContext ctx) {
            setBF(ctx, "    cin >> array[ptr]; 
    ");
        }
    
        @Override
        public void exitPoint(BFParser.PointContext ctx) {
            setBF(ctx, "    cout << (char)array[ptr]; 
    ");
        }
    
        @Override
        public void exitPlus(BFParser.PlusContext ctx) {
            setBF(ctx, "    array[ptr] = array[ptr] + 1; 
    ");
        }
    
        @Override
        public void exitReduce(BFParser.ReduceContext ctx) {
            setBF(ctx, "    array[ptr] = array[ptr] - 1; 
    ");
        }
    
        @Override
        public void exitGreat(BFParser.GreatContext ctx) {
            setBF(ctx, "    ++ptr; 
    ");
        }
    
        @Override
        public void exitLess(BFParser.LessContext ctx) {
            setBF(ctx, "    --ptr; 
    ");
        }
    
        @Override
        public void exitMiddle(BFParser.MiddleContext ctx) {
            // super.exitMiddle(ctx);
            StringBuffer buf  = new StringBuffer();
            buf.append("    while(array[ptr]){ 
    ");
            for(BFParser.StatementContext vctx : ctx.statement()){
                buf.append("    ");
                buf.append(getBF(vctx));
            }
            buf.append("    }
    ");
            setBF(ctx, buf.toString());
        }
    
        @Override
        public void exitSymbol(BFParser.SymbolContext ctx) {
            //super.exitSymbol(ctx);
            setBF(ctx, getBF(ctx.getChild(0)));
        }
    
        @Override
        public void exitProgram(BFParser.ProgramContext ctx) {
            //super.exitProgram(ctx);
            StringBuffer buf = new StringBuffer();
    
            for(BFParser.StatementContext vctx : ctx.statement()){
                buf.append(getBF(vctx));
            }
            setBF(ctx, buf.toString());
        }
    }
    
    public class BF2cplusplus {
        public static void main(String[] args) throws IOException {
            String path = "F:\IDEA_JAVA\BF2cplusplus\test\fib.bf";
            CharStream inputStream = CharStreams.fromFileName(path);
            BFLexer lexer = new BFLexer(inputStream);
            CommonTokenStream tokenStream = new CommonTokenStream(lexer);
            BFParser parser = new BFParser(tokenStream);
            ParseTreeWalker walker = new ParseTreeWalker();
            translator cpp = new translator();
            ParseTree root = parser.program();
            walker.walk(cpp,root);
    
            System.setOut(new PrintStream(new BufferedOutputStream(
                    new FileOutputStream("F:\IDEA_JAVA\BF2cplusplus\test\fib.cpp")),true));
            System.out.print("#include<bits/stdc++.h>
    
    " +
                    "using namespace std;
    " +
                    "int array[100005];
    
    " +
                    "int main(){
    " +
                    "    int ptr = 0;
    ");
            System.out.print(cpp.BF.get(root));
            System.out.print("    return 0;
    }");
        }
    }
    /*
    注意的是,在一些文法后面用”#”号定义了一个名称,
    就会在用于访问生成的抽象语法树AST的访问器中生成该方法,
    用于访问当这个规约被满足时候的那个树节点。
     */
    BF2cplusplus.java

     效果展示

    斐波那契数列程序:

    HelloWorld程序:

  • 相关阅读:
    jqGrid jqGrid 参数
    jqgrid问题总结
    quartz的配置表达式
    Struts2接收参数的几种方式
    Perl爬虫代码
    PHP官方的PECL扩展有问题
    Perl单URL爬虫
    Perl 多进程进度条
    Perl Tk摸索
    hdu 2058 数学题
  • 原文地址:https://www.cnblogs.com/solvit/p/10176435.html
Copyright © 2011-2022 走看看