<p>Is it possible to write a compiler for a new programming language with Go?</p>
<p>Parsing is trivial, but then could you use Go generators to generate and compile the code or is there a better way without having to learn LLVM?</p>
<hr/>**评论:**<br/><br/>iku_19: <pre><p>You can write a new programming language in any language, for go specifically look at <a href="https://golang.org/cmd/yacc/" rel="nofollow">https://golang.org/cmd/yacc/</a> and <a href="https://github.com/golang-samples/yacc" rel="nofollow">https://github.com/golang-samples/yacc</a>, also look at <a href="https://golang.org/src/text/template/parse/lex.go" rel="nofollow">https://golang.org/src/text/template/parse/lex.go</a>, <a href="http://golang.org/pkg/go/ast/" rel="nofollow">http://golang.org/pkg/go/ast/</a> and <a href="https://golang.org/pkg/go/parser/" rel="nofollow">https://golang.org/pkg/go/parser/</a> if you're on the 1.5+ branch you can look at the package files for source.</p>
<p>there is also <a href="https://godoc.org/golang.org/x/exp/ebnf" rel="nofollow">https://godoc.org/golang.org/x/exp/ebnf</a></p>
<p>read <a href="http://www.amazon.com/dp/0321486811/" rel="nofollow">http://www.amazon.com/dp/0321486811/</a> and research everything relating to <a href="http://dinosaur.compilertools.net/" rel="nofollow">http://dinosaur.compilertools.net/</a></p></pre>everdev: <pre><p>Thanks for the links and insight, super helpful.</p></pre>010a: <pre><p>Those lex and ast packages you linked are the lexer and ast for the Go language itself, not a general package for the construction of any language. </p>
<p><code>go tool yacc</code> is very good, however. </p>
<p><a href="http://www-cs-students.stanford.edu/%7Eblynn/nex/" rel="nofollow">Nex</a> is a good choice for a lexical analyzer. </p>
<p>I've written a very simple JS interpreter in Go and in C. With garbage collection turned off it is 3-5 times slower in Go than in C (and if the GC decides to kick in while running, woah baby). But that's kind of expected considering how many years we've been optimizing bison, lex, and the rest.</p>
<p>Its a fun exercise for learning but it would take a lot of optimizing and a deep understanding of the Go language to make it worth writing a serious compiler in (both things the Go team has) (and neither things I have). </p></pre>iku_19: <pre><p>They are, but it's useful to learn from them.</p></pre>Ainar-G: <pre><p>Go is written in Go, so I guess you know the answer to your question.</p></pre>minusSeven: <pre><p>umm how is that even possible ? I mean how did the original go come into existence ?</p></pre>saltycynicism: <pre><p>It's called bootstrapping. Think about C. Did you think that aliens somehow left a C compiler binary for us to find? :)</p>
<p>At first, there was only assembly (and assembly is directly mapped to binary machine code). So someone sat down and wrote a basic (and completely unoptimized) C compiler by hand in assembler. But at that point, we suddenly had a compiler (not a very good one) and we could start writing a compiler for C in C, compiled by our "first" compiler.</p>
<p>We actually still do something like this today if you install a stage 1 Gentoo for instance. It includes a binary of GCC, optimized for a generic architecture. You then proceed to compile your own GCC for your specific architecture and then use THAT compiler to compile it once again (so your optimized compiler compiled the compiler you're using now).</p></pre>Ainar-G: <pre><p>The Go compiler was initially written in C. Then, as the language matured, more and more parts of the compiler were rewritten in Go.</p></pre>brokedown: <pre><p>That's a strong statement that is only mostly true. 1.6 or so should be a better time to make that claim.</p></pre>Ainar-G: <pre><p>Why? Simple <code>ls **/*.c</code> from the Go source code tree root shows that almost all C files left are there for cgo and testing. Or do you mean the assembly?</p></pre>brokedown: <pre><p>Go 1.5 is technically Go, but its largely machine translation of the C version. It's a huge step forward, but I wouldn't use it as an example a compiler being written in go when it's literally translated from C. This will obviously improve and we're seeing benefits already. </p>
<p><a href="https://docs.google.com/document/d/1P3BLR31VA8cvLJLfMibSuTdwTuF7WWLux71CYD0eeD8/edit" rel="nofollow">We're somewhere between phase 2 and phase 3 on the overhaul.</a></p></pre>dominikh: <pre><p>Actually you're just making an argument for why "Can I write a programming language in $X" can be answered without knowing the value of $X. </p></pre>brokedown: <pre><p>Sure, and that's why I said its mostly true.</p></pre>iku_19: <pre><p>1.5 dropped C files, but yes, Go is written in Go now, and every major programming language is written in their own language, it's a sign of maturity.</p></pre>iends: <pre><p>...javascript?</p></pre>iku_19: <pre><p>there are multiple reasons why i wouldn't call JavaScript a mature language, considering it's a loose implementation of the ECMAScript specification that has several different vendors who all implemented it differently as a result causing very minor inconsistent issues causing for a uniformly chaotic language.</p></pre>iends: <pre><p>When these things are resolved would you still expect javascript to be written in JavaScript?</p></pre>iku_19: <pre><p>Well, technically if you tried hard enough you can write V8 natively in Node/io.js, JS preprocessors things like CoffeeScript, LiveScript, and TypeScript are all written in their own languages.</p></pre>iku_19: <pre><p>oh, and there's also <a href="https://github.com/mozilla/narcissus/" rel="nofollow">Narcissus</a> proving that it is possible.</p></pre>pinpinbo: <pre><p>I've seen a few dynamic languages, and of course Lisp, written in Go.</p>
<p>It is definitely possible to write lexer, ast, and parser in Go.</p></pre>aboukirev: <pre><p>You can write the entire compiler in Go (I've done that in Pascal in the past) including optimizer, code emitter (not having bit set fields you may need to do some logical and bit shifting operations to construct instructions) and even linker. It is a lot of work though. Especially if you delve into optimization at the intermediate representation or peephole optimization at assembler level.</p></pre>jerf: <pre><p>What, <em>exactly</em>, is your goal here? Learning? If learning, what are you interested in learning, exactly? Producing a language for a specific task? Writing The Next Great Programming Language? Are you really <em>compiling</em> something all the way from source code down to a fully-independent machine language, or are you really <em>interpreting</em>, or something in between, or you don't know what yet? The more detailed you can be, the better the answer can be.</p>
<p>In the abstract, I'd consider Go a mediocre choice of language to write a compiler in. (Please be sure you know what "mediocre" means before replying or voting.) If you have some other good reason to write it in Go it's not "terrible", but it is missing an awful lot of things that are helpful for compilers and it is not a core use case of the language. For instance, on the OO side, compilers are one of the very short list of places where I consider inheritance useful, and on the FP side, missing sum types really hurts. (As the url and my username suggest, yes, I do know <a href="http://www.jerf.org/iri/post/2917" rel="nofollow">about this article</a>.) On the library front, there's not a huge array of parsing technologies, tutorials on how to write compilers in X, and a generally-strong ecosystem for that sort of thing.</p>
<p>But Go does seem to have what it <em>needs</em> to have in its ecosystem, and it's certainly possible.</p></pre>everdev: <pre><p>Yes, for educational purposes and fun. My thought is to parse a text file (written in the new language) and basically translate it into Go code. From there, I could compile the Go code into a binary.</p>
<p>For example:
console.out("Hello World")</p>
<p>would translate to:
package main</p>
<p>import "fmt"</p>
<p>main() {
fmt.Println("Hello World)
}</p>
<p>I was thinking of using generators to build these translations from the new language to Go.</p></pre>010a: <pre><p>An odd way of doing things but certainly not impossible.</p>
<p>An easier task might be to just write an interpreter. When your interpreter sees a <code>console.out("")</code> in your language the Go interpreter just takes the string in there and executes <code>fmt.Printf("")</code>. Or whatever.</p></pre>jerf: <pre><p>Well, on a technical level you're on the right track then.</p>
<p>However, from an education perspective, you run the risk of just implementing Go in Go, leaning on the fact that you're in Go, and ending up writing something that is secretly just an overcomplicated string search-and-replace that isn't really doing anything interesting, and fooling yourself into thinking you understand more than you do. If you're going to go with this approach, I extremely strongly recommend implementing a language that is in a completely different paradigm than Go. Lisp would be particularly easy, lots of discussion out there that's easy to find, and be sure to implement some form of macro to help make sure you're really doing some compiler-type work.</p></pre>gchain: <pre><p><a href="https://github.com/ark-lang/ark" rel="nofollow">https://github.com/ark-lang/ark</a></p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传