sbrk is emulated via mmap today on MacOS and others, this is an abstraction (for bump allocation), not just a function
you may implement custom sbrk via mmap easily
HN user
Software engineer interested in learning and education. Sometimes blog on topics of programming languages theory, compilers, and ECMAScript.
sbrk is emulated via mmap today on MacOS and others, this is an abstraction (for bump allocation), not just a function
you may implement custom sbrk via mmap easily
Thanks for the feedback, and glad to see more engineers interested in deeper topics!
That's a great point and I have the https://github.com/DmitrySoshnikov/syntax/issues/99 to add support for IELR in Syntax.
Yes, in fact for building a language the parsing stage should be skipped altogether (start with interpreter or bytecode). We do this in the interpreters class. And once you have a fully working VM, _now_ it is a good time to shift to parsing and design a good syntax.
For recursive descent we have a separate class "Building a Recursive descent parser from scratch" which is purely practical coding class for those interested mainly in practice.
Yes, backtracking still might be an option although has its known limitations in terms of parallel paths. We describe backtracking in this class too.
The LL in the the view of manual Recursive descent is the most used on practice along with combinators and LALR(1).
Yeah, this makes sense, thanks.
Professor Aiken is a great teacher and I love his compilers course. However as for the parsering stage, that course goes as maximum as to SLR(1) which is pretty "toy" parsing mode. That's the problem with a combined "compilers class" -- one simply can't put everything, and everything is becoming slightly superficial. That's why I have Parsers and Garbage Collectors class as separate and fully specialized course.
Thank you for the feedback, glad you liked it, and glad to see more people interested in deeper CS topics!
Yes, I recommend "Parsing Techniques" book.
See this small summary doc on different techniques for error recovery: https://gist.github.com/DmitrySoshnikov/feee52cbfb03b7b69110...
Great details, thanks!
A benefit of a syntax with indentation-defined block structure is that you don't need to rely on balanced grouping tokens like { ... }
In fact from the lexer perspective there is no big difference, the matching indent-dedent is the same token type as would be { and }
Yes, this is called "parse error recovery" and there are multiple techniques for this. In fact, most of the production parsers support this mode. E.g. when you try executing a C++ or Java file, it shows you all the errors at once instead of failing on first parse error. The way it's achieved is by constructing a "dummy" AST node (caught up to some delimiter, e.g. semicolon in statements) and continue the parsing process as there would be no any error.
Absolutely! S-expression (used in Scheme, Lisp, etc) is a great AST-based syntax to start building an interpreter right away. But for fully ergonomic language you would need a parser for a more complex syntax.
Yes, in the "Essentials of Interpretation" class (aka "Building an Interpreter from scratch" we focus exactly on runtime semantics, and evaluating the language. The S-expression allows greatly simplifying, focus on runtime specifics themselves, skipping parsing stage altogether.
In "Essentials of Parsing" class (aka "Parsing Algorithms") we shift exactly to the syntax, and understanding the parsing process from within -- this in general may have nothing to do with runtime -- for the same exact syntax you may have different interpreters or VMs (even with different semantics).
Should be up by now; seems auto-DDOS'ed, lol
Yes, if you need to parse that input string to generates an appropriate SQL query, you would need to have a small DSL (domain-specific language) for that "string", whatever it contains. If the string contains SQL-like syntax, e.g. "SELECT name from users", then yes, it would be easy to build a grammar for this.
Yes, to some degree -- Syntax tool normally support lexer states, and the same "while" token may mean a keyword or the property/field name of a struct. You can find more details of the lexer states in the docs.
Yes, we use LALR(1) parsing mode to build the actual parser, and it exactly supports Left recursive grammars (which are much more elegant than LL). We also don't focus much on scanner (tokenizer) since this is a topic of Regular expressions and Finite automata which we discuss in detail in the separate class "Building a RegExp machine".
Yeah, this class is specifically on parsing pipeline and syntactic analysis.
For runtime semantics (Interpreters and Virtual Machines) you can address "Essentials of Interpretation" aka "Building an Interpreter from scratch".
Yes, GLL is a good algorithm and I potentially going to publish it separately as a single public video.
Congrats, and hope this makes building of your parser easy and fun!
This course covers a lot of parsing theory as well, and if you're interested in pure practical (manual) parser, there will be also "Building a Recursive descent parser from scratch", which is mainly coding class and is an extension for the "Parsing Algorithms".
Thanks for the feedback, glad you like it. For production I use combination of software: Keynote, Notability, Good notes, Camtasia, and live editing on iPad.
Great point on combinators, PEG, and GLL -- this potentially would be covered in 201 as suggested, since it's good having a foundation of the LL/LR, and then gradually moving to combinators if needed. LALR(1) covers a pretty wide range of the most practical languages.
the Voodoo magic is in the scheduling and code generation
Yes, for the code generation one needs to well understand semantics of the target language. And when it's a low-level language (Assembly), the "voodoo magic" mainly relates to generic understanding of the lower-level architectures. However, there might be compilation to another high-level language (in case of a transpiler), and by itself code generation at this stage is not that hard, simply because a target language is more understood in this case.
Instruction selection topic, and where to place the data -- on the stack, or into registers (and how a register allocator works) also mainly relates to the lower-level.
until you get into the backend
Yes, and that's why I think it should be a separate class, specifically for higher-level compilation, and a low-level compilation.
We'll be covering this in "Essentials of Compilation".
Indeed, TypeScript is also a good choice for this.
Thanks for your feedback, appreciated! And glad the Garbage Collectors class is interesting. Yes, I'll consider shortening the intro in the future classes. Initially each lecture was a self-contained, and potentially with no related context to previous lectures, however when combined in a class, yes, it makes sense to make the intro shorter. In the Interpreters class I shortened it to ~5 secs only.
Yes, good point on pattern matching and algebraic data types (initially I was actually considering Rust for implementation, but not OCaml). The visitor pattern is a classic though, and is transferable knowledge further, to process different kinds of graphs, trees, etc. BTW, JavaScript will likely be getting pattern matching soon as well.
Yes, I agree, the topic is becoming pretty hot these days, and this reflects the era of transpilers, WebAssembly, coming into play with its nested bytecode format, and other related topics. More people are getting interested in how things work under the hood, instead of just "using" a language.
Thanks! Yes, we use JavaScript as the most popular language, however the code should be easily portable to any other language.
The multi-paradigm nature of JS, with its first-class functions, closures, static scope semantics, class-based and prototype-based inheritance fits the best to study semantics of programming languages -- and all these concepts we implement in the course.
For low-level bytecode interpreter there will be a C++ implementation.
Garbage collection IRL is very important as well ;)