Chisel
Extending Chisel
Writing your own language on the chisel foundation
This page sketches how to build a small language using chisel primitives. The Notch parser itself is the canonical worked example; this is an outline.
1. Configure a tokenizer
Compose token types into a Tokenizer:
Tokenizer T = new Tokenizer()
.withTokenType(WHITESPACE)
.withTokenType(BOOL)
.withTokenType(MY_KEYWORD)
.withTokenType(IDENT)
.withTokenType(INT)
.withTokenType(STR)
.withTokenTypes(TokenTypePunct.common());
TokenTypePunct.common() returns the common punctuation tokens. You can add your own TokenType implementations by subclassing or composing.
2. Write a parser
Extend BasicParser:
public class MyParser extends BasicParser {
public MyParser(String fileId, String src) {
this(T.tokenize(fileId, src));
}
public MyExpression parseExpression() {
// recursive descent here
}
}
The base class provides:
location(),take(),peek()- position-tracking primitives.ignoreTypes(TokenType...)- skip tokens of the listed types when scanning (typical use: whitespace and comments).temporaryEndTokens(TokenType[], () -> T)- run a sub-parser that treats the listed tokens as end-of-stream. Useful when parsing a list element that should stop at,or]without consuming them.
3. Add coercions
If your language uses JVM types, register coercions so type mismatches at method-call sites get bridged automatically. See src/main/java/edu/montana/notch/types/coercions/Coercion.java for the abstract base.
4. Render errors with spans
Throw ParseException from your parser. Catch at the entry point and use the Spanned interface to render a file:line:column caret message.
See also
- Overview for the chisel API surface.
- The Notch source itself:
src/main/java/edu/montana/notch/NotchParser.javaextendsBasicParser;Notch.javaconfigures the tokenizer.