I am looking to create a parser in Typescript that can handle symbols specific to language grammars.
Initially, I attempted to parameterize the Sym
type for symbols that vary depending on the language grammar. However, I encountered a type checking error in the first line of Parser.js:
Type
Sym
does not meet the constraintstring | number | symbol
.
I tried various ways to adjust the definition of GrammarRules<Sym>
to fix this issue, but each solution led to additional problems downstream, some of which were difficult to resolve – a comprehensive solution eluded me.
How can I redefine the symbol type, Sym
, for each parser language and handle it generically in Parser.js? I am open to making substantial changes to the declarations and code for a cleaner overall solution.
Parser.ts
export type GrammarRules<Sym> = Record<Sym, GrammarRule<Sym>>
export type GrammarRule<Sym> = { lhs: Sym /* further uses of Sym type */ }
export class Parser<Sym> {
rules: GrammarRules<Sym>
private str: string
/* Various other datastructure declarations with types dependent on Sym */
constructor(rules: GrammarRules<Sym>) {
this.rules = rules
}
parse(startSym: Sym, str: string) {
this.str = str
console.log(this.rules[startSym].lhs)
// ...
}
}
ParserLangABC.ts
import { Parser, GrammarRules } from "./Parser"
type Sym = 'A' | 'B' | 'C'
const rulesABC: GrammarRules<Sym> = {
A: { lhs: 'A' /* rhs with further data of type Sym */ },
B: { lhs: 'B' /* rhs with further data of type Sym */ },
C: { lhs: 'C' /* rhs with further data of type Sym */ }
}
class ParserLangABC<Sym> extends Parser<Sym> {
static parse(str: string) {
const parser = new Parser(rulesABC)
parser.parse('A', str)
}
// Other supporting methods parameterized to Sym
}
ParserLangDEF.ts
import { Parser, GrammarRules } from "./Parser"
type Sym = 'D' | 'E' | 'F'
const rulesDEF: GrammarRules<Sym> = {
D: { lhs: 'D' /* rhs with further data of type Sym */ },
E: { lhs: 'E' /* rhs with further data of type Sym */ },
F: { lhs: 'F' /* rhs with further data of type Sym */ }
}
class ParserLangDEF<Sym> extends Parser<Sym> {
static parse(str: string) {
const parser = new Parser(rulesDEF)
parser.parse('D', str)
}
// Other supporting methods parameterized to Sym
}