福州 福马路 网站建设,wordpress文章缩略,济南网站建设哪里好,做网站开发用哪门语言起因《25行JavaScript语句实现一个简单的编译器》实现的是一个简单到不能再简单的玩具的玩具#xff0c;他的魔法是函数式编程简化了js代码。java 8提供了函数式编程的支持#xff0c;昨晚脑子抽风突然兴趣java也可以实现一个如此简单的编译器#xff01;java和js语言差异ja…起因《25行JavaScript语句实现一个简单的编译器》实现的是一个简单到不能再简单的玩具的玩具他的魔法是函数式编程简化了js代码。java 8提供了函数式编程的支持昨晚脑子抽风突然兴趣java也可以实现一个如此简单的编译器java和js语言差异java相对js这类胶水语言来说还是相对啰嗦的一些动态语言的特性在java里并不具备。《25行JavaScript语句实现一个简单的编译器》的作者是个js高手js用得溜溜的下面说说他用到js里有而java没有的功能。js 字符串模板他在Transpiler中使用ES2015新增的模板字符串功能。 (${ast.expr.map(transpileNode).join( opMap[ast.val] )});js内置 map和简单的赋值语法 const node { val: consume(), type: Op, expr: [] };其他胶水语言的话对应的是tuplejava要实现的话还真啰嗦不少。模式匹配(实际这是js的map啊啊啊) const opAcMap {sum: args args.reduce((a, b) a b, 0),sub: args args.reduce((a, b) a - b),div: args args.reduce((a, b) a / b),mul: args args.reduce((a, b) a * b, 1)};java还木有模式匹配。没有这几个js功能但我们还是可以通过各种方法绕一下的。怎么绕请看下文java实现废话不啰嗦上代码代码风格学他的也紧促点凑合着看吧static final int OP 0, NUM 1;private static List lexer(String input){return Stream.of(input.split( )).map(String::trim).filter(s - s.length() 0).collect(Collectors.toList());}private static class Parser {Iterator lex;String nextnull;public Parser(List lex) { this.lexlex.iterator(); }private Node parseOp(String str) {Node n new Node(str, OP);while (lex.hasNext())n.addLast(parse());return n;}public Node parse() { return (nextlex.next()).matches(\\d) ? new Node(Integer.parseInt(next), NUM) : parseOp(next); }}final static Map opMap new HashMap(4) {{ put(sum, ); put(sub, -); put(div, /); put(mul, *);}};private static String codeGenerator (Node ast) { return ast.type NUM ? String.valueOf(ast.val) : genOp(ast); }private static String genOp(Node node) { return ( node.stream().map(n - codeGenerator(n)) .collect(Collectors.joining( opMap.get(node.val) )) ); }private static class Node extends ArrayDeque{Object val;int type;public Node(Object val, int type) {super();this.val val;this.type type;}}private static int eval(Node ast) { return (int) (ast.type NUM ? ast.val : ast.stream().reduce(evalOps.get(ast.val)).get().val); }final static Map evalOpsnew HashMap(4) {{put(sum, (a, b) - new Node(eval(a) eval(b), NUM)); put(sub, (a, b) - new Node(eval(a) - eval(b), NUM));put(div, (a, b) - new Node(eval(a) / eval(b), NUM)); put(mul, (a, b) - new Node(eval(a) * eval(b), NUM));}};js实现lex和transpile用了23行代码。没有tuple java实现node多花了9行代码加起来用了25行。不过他加eval功能的代码行(33行)比我这(29行)可是多的。代码行数多少是其次函数式编程写代码还真精简不少写的爽看得也不累。写在后最后还是想说这个玩具的玩具。之所以说这个是玩具呢。首先他定的语法规则是非常简单的。其次表面是一个乘除加减语言但是没有算术优先级。最后这跟什么编译器没啥多大的关联(词法分析器用空格直接分割也只能是玩泥沙)如果想写个简单解析器之类的可以参考我的《练手写了个SQLite解析器》和《一个android sqlite CRUD代码生成小工具》本文源码下载移步github《tiny-compiler-java》