Reworked parser to be macro based.

This commit is contained in:
Joshua Bemenderfer
2022-11-15 17:10:17 -05:00
parent 4405f4857d
commit 296056ce16
3 changed files with 188 additions and 266 deletions

View File

@@ -1,83 +1,80 @@
import { parse } from './core.js'
import { SYMBOLS, parse, isScope, isMacro, getTail, getText, getUnmatched, isCollection } from './core.js'
const schemaTCE = `
types
section object, text as content, tail as pos
content string
pos number
macros
primitive match number string
section
pos number tail
content string unmatched
position number
options object
options
parameter1 number
parameter2 string
literal unmatched string
unmatched primitive
root object
root
title string
options options
options2 options
options options collection
subsection section
collate collection
list array
- string
collection collection
section section
list
- string array
collection
section collection
collection2
unmatched collection
`
const schema = {
types: {
section: {
type: 'object',
text: 'content',
tail: 'pos',
values: {
content: 'string',
pos: 'number',
position: {
type: 'number'
}
}
macros: {
string({ tail }) {
return tail.toString()
},
options: {
type: 'object',
values: {
parameter1: 'number',
parameter2: 'string'
}
number({ tail }) {
const num = +tail
if (isNaN(num) || tail === '') return
return num
},
primitive({ macros }) {
const num = macros.number(args)
return num !== undefined ? num : macros.string(args)
},
scope({ addScope, head, tail, line }, definition) {
return addScope({ definition, head, tail, line })
},
section: isScope({
[SYMBOLS.TAIL]: getTail('pos', isMacro('number')),
[SYMBOLS.UNMATCHED]: getText('content', isMacro('string')),
position: isMacro('number')
}),
options: isScope({
parameter1: isMacro('number'),
parameter2: isMacro('string'),
unmatched: isMacro('string'),
[SYMBOLS.UNMATCHED]: getUnmatched(isMacro('any')),
}),
any(args) {
const macro = args.macros[args.head]
if (macro) return macro(args)
const numResult = args.macros.number(args)
if (numResult !== undefined) return numResult
args.tail = args.line
return args.macros.string(args)
},
advList: {
type: 'array',
values: {
section: 'section'
}
}
},
root: {
type: 'object',
values: {
title: 'string',
options: 'options',
options2: 'options',
subsection: {
type: 'section',
// Allows a particular repeated key to collect itself under a multi-value root as an array.
collate: 'collection'
},
list: {
// Defines an array where all entries must conform to specific types. No other keys are permitted.
// Ex: [ value, value ]
type: 'array',
values: {
'-': 'string'
}
},
collection: {
// Defines an array where all entries must conform to specific types. They will be segregated by key. No other keys are permitted.
// Ex: [ {key: value }, { key: value }]
type: 'collection',
values: {
section: 'section'
}
}
}
title: isMacro('string'),
options: isMacro('options'),
subsection: isMacro('section'),
list: isScope({
'-': isMacro('string')
}),
collection: isScope({
section: isCollection(isMacro('section'))
}),
collection2: isScope({
[SYMBOLS.UNMATCHED]: getUnmatched(isMacro('any'))
})
}
}
@@ -87,7 +84,7 @@ const lines = [
`options`,
` parameter1 30`,
` parameter2 Enim eu id anim minim reprehenderit nostrud eu amet deserunt ea ut do cupidatat ea.`,
`options2`,
`options`,
` parameter1 0`,
` parameter2 Esse incididunt et est adipisicing eiusmod aliqua enim ea aliqua id enim.`,
`subsection`,
@@ -104,11 +101,18 @@ const lines = [
` section`,
` lorem ipsum 1`,
` section`,
` lorem ipsum 2`
` lorem ipsum 2`,
`collection2`,
` section`,
` position 3`,
` Laborum aute anim occaecat occaecat pariatur tempor proident magna sit magna non non.`,
` list`,
` 1`,
` 2`
]
async function main() {
console.log(await parse(lines, schema))
console.dir(await parse(lines, schema), { depth: null })
}
main()
main()