I really want to be able to wrap my head around compilers but I'm not sure what a good "user friendly" resource is that wont stuff lots of fancy compiler buzzwords in my face and become white noise to me.
I would recommend "Compiler Construction" by Niklaus Wirth. This small book (< 200 pages) will teach you the basics and show you how to build a single-pass compiler for a subset of Oberon (a Pascal successor).
For a more comprehensive example, you can have a look at my compiler for the full Oberon language targeting the JVM. It is based on the principles of that book: https://github.com/lboasso/oberonc
Start simple. If you haven't written an interpreter, do that first. Then figure out how to write a similar program that emits code for a virtual machine rather than evaluating the language.
I'm actually trying to write an easy-to-digest compiler and companion reading series. It's for a compilers independent study class. You can track my progress here: https://github.com/tekknolagi/tigress
At this point it's not well-documented, but the layers are numbered in order: l00, l01, l02... Each builds on top of the previous one.
EDIT: I just added a mini evaluator for debugging purposes and so people can see what the language is like.
Is it really that friendly when starting out, though? I found it brilliant, but quite the challenging read. I'd rather just read chapters four and five of SICP [1] and move on to Queinnec as a follow-up on more advanced topics.
[1]: The book is free as well: https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html...
I enjoyed this read because it was a very user-friendly overview. After reading, I knew exactly what major pieces did what and therefore what to search for next on my own terms.
I'm writing my first compiler now, and it's been quite a learning curve. I've also realized how much nicer my language is for writing compilers than the language in which I'm implementing the compiler. That made me realize I could write the compiler in my language and then write an interpreter for my language which would only need to run once--to generate the compiler--after which point my compiler would be self-hosting. :p
I haven't looked at any resources in particular. Basically my compiler has 3 parts--parser -> type checker -> code generation. Parsing was tricky at first, but then I stumbled upon a pattern which is pretty close to parser-combinators. Type checking seemed daunting, but my language happened to be Hindley-Milner compatible, and there's lots of reference information for HM. Code generation is easy in the base case, but I'm still wrapping my mind around template expansion.
I think Wirth's compiler book is more approachable for a beginner. Once you are done with that book you can also read "Project Oberon" from the same author. This way you can understand the implementation of a full graphical OS written from scratch for a custom made RISC processor implemented on a FPGA. The book and source code are available at: http://www-oldurls.inf.ethz.ch/personal/wirth/ProjectOberon/
The book is freely available here: http://people.inf.ethz.ch/wirth/CompilerConstruction/index.h...
For a more comprehensive example, you can have a look at my compiler for the full Oberon language targeting the JVM. It is based on the principles of that book: https://github.com/lboasso/oberonc