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 =
|
export type DelimiterToken =
|
||||||
| { tag: "open-paren"; span: CodePointSpan }
|
| { tag: "open-paren", span: CodePointSpan }
|
||||||
| { tag: "close-paren"; span: CodePointSpan }
|
| { tag: "close-paren", span: CodePointSpan }
|
||||||
| { tag: "open-bracket"; span: CodePointSpan }
|
| { tag: "open-bracket", span: CodePointSpan }
|
||||||
| { tag: "close-bracket"; span: CodePointSpan };
|
| { tag: "close-bracket", span: CodePointSpan }
|
||||||
|
|
||||||
export namespace DelimiterToken {
|
export namespace DelimiterToken {
|
||||||
export function openParen(span: CodePointSpan): DelimiterToken {
|
export function openParen(span: CodePointSpan): DelimiterToken {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue