define basic Partial CST for JSON
This commit is contained in:
parent
ef1d81f597
commit
57f666118a
4 changed files with 121 additions and 4 deletions
18
QESTIONS.md
Normal file
18
QESTIONS.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
# tokens in Partial Concrete Syntax
|
||||
What sort of tokens should I track in the syntax?
|
||||
- delimiters like e.g. in `[a, b, c]`?
|
||||
- more significant separators like the `:` in `{ "foo" : a }`?
|
||||
- What about groupin symbols like `{ ... }`?
|
||||
- What about keywords? e.g. `fn` or `for` or `while`?
|
||||
|
||||
Can these questions be answered universally, or is this application dependent?
|
||||
- For example, maybe when building a compiler, we don't need to track so much stuff.
|
||||
- But for formatter, we probably need to track a bit more.
|
||||
- But what about something like a library in a IDE that handles various transformations of the code?
|
||||
|
||||
# delimiter confusion
|
||||
I just realized that I've been misunderstanding the word `delimiter`.
|
||||
I thought that a delimiter was like the `,` in `[ a, b, c]`. But that's called properly called a separator! Or item-separator.
|
||||
I thought separator and delimiter where synonyms. But it seems like a `delimiter` is actually the grouping symbols like `[` or `]`.
|
||||
|
||||
4
src/languages/json/parse_errors.ts
Normal file
4
src/languages/json/parse_errors.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import type { CodePoint, CodePointSpan } from 'source-region';
|
||||
|
||||
export type ParseError =
|
||||
| {} // TODO
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import type { CodePointSpan } from 'source-region';
|
||||
import type { ParseError } from './parse_errors.ts';
|
||||
|
||||
export type ConcreteInfo = { span: CodePointSpan };
|
||||
|
||||
export type ConcreteError = ConcreteErrorNode[] // Convention: can't be empty.
|
||||
export type ConcreteErrorNode = {
|
||||
span: CodePointSpan,
|
||||
error: ParseError,
|
||||
panickedOver?: CodePointSpan,
|
||||
}
|
||||
|
||||
export namespace ConcreteError {
|
||||
export function single(node: ConcreteErrorNode): ConcreteError {
|
||||
return [node];
|
||||
}
|
||||
}
|
||||
|
||||
export type DelimiterToken =
|
||||
| { tag: "open-brace", span: CodePointSpan }
|
||||
| { tag: "close-brace", span: CodePointSpan }
|
||||
| { tag: "open-bracket", span: CodePointSpan }
|
||||
| { tag: "close-bracket", span: CodePointSpan }
|
||||
|
||||
export type Program<Info, Error> = {
|
||||
tag: "program",
|
||||
expressions: JsonValue<Info, Error>[],
|
||||
error?: Error,
|
||||
} & Info
|
||||
|
||||
export type JsonValue<Info, Error> =
|
||||
| JsonObject<Info, Error>
|
||||
| JsonArray<Info, Error>
|
||||
| JsonScalar<Info, Error>
|
||||
| { tag: "error-expression", error: Error } & Info
|
||||
|
||||
export type JsonObject<Info, Error> = {
|
||||
tag: "object",
|
||||
open: DelimiterToken,
|
||||
members: MemberItem<Info, Error>[],
|
||||
close?: DelimiterToken,
|
||||
error?: Error
|
||||
} & Info
|
||||
|
||||
export type MemberItem<Info, Error> =
|
||||
| { tag: "member" } & Member<Info, Error>
|
||||
| { tag: "error-object-separator", error: Error } & Info
|
||||
|
||||
export type Member<Info, Error> = {
|
||||
key: StringLiteral<Info, Error>,
|
||||
colon?: { tag: "colon", span: CodePointSpan },
|
||||
value: JsonValue<Info, Error>,
|
||||
error?: Error
|
||||
} & Info
|
||||
|
||||
export type JsonArray<Info, Error> = {
|
||||
tag: "array",
|
||||
open: DelimiterToken,
|
||||
items: ArrayItem<Info, Error>[],
|
||||
close?: DelimiterToken,
|
||||
error?: Error
|
||||
} & Info
|
||||
|
||||
export type ArrayItem<Info, Error> =
|
||||
| JsonValue<Info, Error>
|
||||
| { tag: "error-array-separator", error: Error } & Info
|
||||
|
||||
export type StringLiteral<Info, Error> =
|
||||
| {
|
||||
tag: "string",
|
||||
// TODO: There are various possibilities of storing the actual literal value. But I don't care about this right now.
|
||||
value: string,
|
||||
error?: Error,
|
||||
} & Info
|
||||
| { tag: "error-string", error: Error } & Info
|
||||
|
||||
export type NumberLiteral<Info, Error> =
|
||||
| {
|
||||
tag: "number",
|
||||
// TODO: There are various possibilities of storing the actual literal value. But I don't care about this right now.
|
||||
value: number,
|
||||
error?: Error,
|
||||
} & Info
|
||||
| { tag: "error-number", error: Error } & Info
|
||||
|
||||
export type JsonScalar<Info, Error> =
|
||||
// === number ===
|
||||
| NumberLiteral<Info, Error>
|
||||
// === string ===
|
||||
| StringLiteral<Info, Error>
|
||||
// === constants ===
|
||||
| { tag: "null", error?: Error } & Info
|
||||
| { tag: "true", error?: Error } & Info
|
||||
| { tag: "false", error?: Error } & Info
|
||||
|
||||
|
|
@ -17,10 +17,10 @@ export namespace ConcreteError {
|
|||
}
|
||||
|
||||
export type DelimiterToken =
|
||||
| { tag: "open-paren"; span: CodePointSpan }
|
||||
| { tag: "close-paren"; span: CodePointSpan }
|
||||
| { tag: "open-bracket"; span: CodePointSpan }
|
||||
| { tag: "close-bracket"; span: CodePointSpan };
|
||||
| { tag: "open-paren", span: CodePointSpan }
|
||||
| { tag: "close-paren", span: CodePointSpan }
|
||||
| { tag: "open-bracket", span: CodePointSpan }
|
||||
| { tag: "close-bracket", span: CodePointSpan }
|
||||
|
||||
export namespace DelimiterToken {
|
||||
export function openParen(span: CodePointSpan): DelimiterToken {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue