diff options
| Commit | 01e91bc3caf59f23c28ee0630c3d9b65363fe753 (patch) | |
|---|---|---|
| Author | 2023-04-13 14:21:19 +0300 | |
| Committer | 2023-04-13 14:21:19 +0300 | |
| Files | 640690776545ce2b4f53d709074896a6b9b88984 | |
| syndamia.com-01e91bc3caf59f23c28ee0630c3d9b65363fe753.tar syndamia.com-01e91bc3caf59f23c28ee0630c3d9b65363fe753.tar.gz syndamia.com-01e91bc3caf59f23c28ee0630c3d9b65363fe753.zip | ||
| Parent | 087af3f9d69618d3a9ab070347e13c52870c3da9 (diff) | |
[blog/seoc] Finalized contents and wrote a bit
1 files changed, 10 insertions, 9 deletions
| -rw-r--r-- | src/blog/sane-explanation-of-compilers/part-1.md | 19 |
diff --git a/src/blog/sane-explanation-of-compilers/part-1.md b/src/blog/sane-explanation-of-compilers/part-1.md index 250d9d2..24c87fd 100644 --- a/src/blog/sane-explanation-of-compilers/part-1.md +++ b/src/blog/sane-explanation-of-compilers/part-1.md @@ -9,15 +9,17 @@ 2. [Grammars](#grammars) 2. [Lexers and parsers](#lexers-and-parsers) 1. [Implementational difficulties with grammars](#implementational-difficulties-with-grammars) - 2. [Usage in the real world](#usage-in-the-real-world) + 2. [Practical usage](#practical-usage) 3. [Parsing algorithms](#parsing-algorithms) 1. [LL](#ll) 2. [LR](#lr) 3. [LR's family](#lrs-family) + 4. [More info](#more-info) 4. [Abstract syntax tree](#abstract-syntax-tree) 3. [Implementing a front-end](#implementing-a-front-end) 1. [lex](#lex) 2. [yacc](#yacc) + 3. [Using them together](#using-them-together) Recently I signed up for a small university course about compilers. As I found out, most materials on the topic are either so surface level you barely learn anything, or so specific you need to already know the subject. @@ -317,7 +319,7 @@ E 🡆 E * E 🡆 E + E * n 🡆 n + n * n How exactly we deal with these problems comes later, for now the takeaway is that we have to try and use regular expressions wherever we can, and leave grammars as a bit of a last resort. -#### Usage in the real world +#### Practical usage Let's think a bit more about grammars: they're really good at handling structure, especially recursive structure, so it's best if we use them only for that. Our math expression grammar (from [here](#grammars)) shouldn't really care if we're trying to sum integers or floats or chars[^static-typing], it's important how everything is layed out and that our operations are done with numbers. @@ -650,7 +652,7 @@ Let's draw out[^nomnoml] this relationship, where the left arrow connects to the  Hey, that looks an awful lot like a [tree](https://en.wikipedia.org/wiki/Tree_%28data_structure%29)! -Trees are nodes, some sort of elements, where there is a connection from one element to some other elements, with the only rule being that cycles aren't allowed: +Trees are nodes, some sort of elements, where there is a connection from one element to some other elements, with the only rule being that cycles **aren't** allowed:  @@ -680,7 +682,7 @@ Or alteratively we could have a virtual method "evaluate" which changes ### Implementing a front-end -If you want, you could implement your own lexer and parser manually, but as a start, it's better to try and use already created stuff. +If you want, you could implement your own lexer and parser manually, but as a start, it's worthwhile to try and use already created stuff. [Compiler-compilers](https://en.wikipedia.org/wiki/Compiler-compiler) are tools that create parsers (and more) from their normal formal definition. The two popular ones from the old days are lex and yacc. @@ -804,7 +806,7 @@ John said <span class="num">10</span> times <span class="str">"2 + 2 = 5"</span> ``` You've probably already noticed that the number inside the strings aren't matched, because the string rule results in a longer match. -In programming languages this is fine, since strings are quite often "self-contained" objects, there isn't anything in them that you would need to match. +In certain programming languages, that don't have [string interpolation](https://en.wikipedia.org/wiki/String_interpolation) this is fine, but for the others our regexes have to be a lot more complicated. #### yacc @@ -830,11 +832,10 @@ A yacc file looks very similar to a lex one: however rather than definitions you have settings, and the rules are in a completely different format (because they're grammars). -## II. Virtual machines +#### Using them together -Let's skip over the middle layer for a second, and talk about machine instructions. -It should come as no surprise that transforming an AST to specific instructions isn't very fast or simple. -Additionally, there are thousands upon thousands of different +Let's now make our own "proper" front-end. +The lexer will need to return (emit) it's token to the [^how-did-we-get-here]: Though it's obvious, I would like to point out that modern compilers are most often written in languages that are themselves compiled. You might ask yourself "where did the first compiler come from?" The answer is simple: it was written with "numbers", with direct instructions to the processor, from the time when computers were simple enough that *all* programming was done with CPU instructions. |