Before I start: yes I do need(/want) a DSL (even if it's just for the experience), there's no other format that expresses what I'm trying to do in a not-terribly-verbose, type-safe way.
I want to create a DSL-compiler for my project (TypeScript), and since the language shares a lot of syntax and concepts with TypeScript itself (I designed it that way) I thought of re-using parts of the TypeScript compiler to avoid re-inventing the wheel. I'm mostly interested in scanner
, parser
and binder
. The other semantics and the emitting parts of my DLS differ so much from TypeScript that I'm pretty sure it'll be more efficient to write it from scratch.
I found this site which explains how the compiler actually works (although I'm pretty sure it's a little out of date), and so far I can understand everything pretty well. As far as I can see there are no reasons why I should reinvent the wheel if I can extend the TypeScript compiler.
The first part is of course the scanner
.
I tried to scan a file in my language to see what happens, turns out that everything tsc doesn't know about gets classified (SyntaxKind
) as an Identifier
(which makes sense). To implement my DLS I would have to add keywords and syntax types to this scanner to be sent to the parser
for building an AST. I'll have to extend the parser
as well of course, but that's not my concern right now.
My first instinct was to just clone the TypeScript respository and add the required logic. That way I could use the same API as on the aforementioned site, but with my added keywords/syntax/AST-nodes. I would then write the semantic checks and actually emitting the generated output from scratch, and all would be good.
Unfortunately that didn't really work (hence this question). The first roadblock was just being overwhelmed by the size and structure of the repository, I just didn't where I should look.
I tried to create a little program that used the local source instead of the built one, but that didn't work either (probably due to some complicated pipeline tsc goes through before it's in any usable state).
I did find the compiler.ts
, parser.ts
, etc. files, but without a way to use my custom version they weren't of much use.
I tried to copy only the files I thought I'd need into my own project, but that caused all kinds of typing errors and missing functions and I have no idea how (and if) I should fix them. To make it even worse: certain files had actual compilation errors when I tried to compile them in my own environment (relaxing tsconfig.json
settings didn't help).
I have three questions:
scanner
, parser
and binder
components.)After fiddling around a little longer I gave up on trying to extend the Typescript compiler. I ended up using chevrotain as a compiler-'generator', and so far it has been working ok.
The main disadvantage of this library is that it (in my experience) doesn't integrate very well with Typescript because there's a lot of "magic" stuff that was obviously designed to be used in the highly dynamic environment that is JavaScript (although the library itself is written in TS).
Overall I had a pretty pleasant experience with it. The documentation is very good, and there are a lot of possibilities. I can highly recommend it to anyone wanting to build a DSL in Typescript.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With