wip: parser setup, doesn't do much yet

This commit is contained in:
Glen Whitney 2023-09-03 10:55:32 -07:00
parent 8186038efb
commit 01041536b6

View File

@ -1,6 +1,7 @@
moo from ../deps/moo.js
import type {Lexer, Token} from ../deps/moo.d.ts
type Tree = {[key:string]: string | Tree}
type Tree = {[key:string]: (string | Tree)[]}
lexer := moo.compile
comment: /#.*?$/
@ -20,27 +21,66 @@ lexer := moo.compile
oparen: '('
cparen: ')'
export function tree97(vrml1: string): Tree
tree: Tree := {}
for tok, index of lexer.reset vrml1
if tok.type and tok.type !== 'whitespace' and tok.type !== 'comment'
tree[`${index}`] = {tok.type, tok.value}
export function tree97(vrml1: string)
parse lexer.reset vrml1
// separatorIgnore :=
// 'TextureCoordinate Normal Coordinate Texture Material'.split(' ')
function filtered(stream: Lexer): Token | undefined
result .= stream.next()
while result and (result.type === 'whitespace' or result.type === 'comment')
result = stream.next()
result
function parse(stream: Lexer, tree: Tree = {}): Tree
deferred: Token[] := []
held .= filtered stream // for lookahead
while next := filtered stream
unless held break
switch data :=
{nt: next.type, nv: next.value, ht: held.type, hv: held.value}
{ht: 'word', nt: 'obrace'}
switch held.value
/(?:Transform)?Separator/
{children, ...context} := tree
subTree := parse(stream, context)
// separatorIgnore.map((prop) => subTree.delete prop) // unneeded?
if newKids := subTree.children
if 'children' not in tree then tree.children = []
tree.children.push(`
Transform { children [
${renderList newKids}
] }`)
/Group|Switch|WWWAnchor/
{children, ...context} := tree
subTree := parse(stream, context)
if newKids := subTree.children
if 'children' not in tree then tree.children = []
tree.children.push(`
Group { children [
${renderList newKids}
] }`)
held = filtered stream
{ht: 'word', hv: 'vertexOrdering', nt: 'word', nv: 'COUNTERCLOCKWISE'}
tree.vertexOrdering = ['ccw']
held = filtered stream
else
console.log 'How did I end up with held', held, 'and next', next
unless held and held.type === 'cbrace'
console.log 'Oddly ended up with held', held
tree
function render(t: string | Tree): string
if typeof t is 'string'
return t
result .= ''
for item of Object.values t
if typeof item is 'string' then result += item + ' '
else
typ := item.type
result += render(typ)
if typeof typ === 'string' and
['cbrace', 'cbracket', 'cparen'].includes(typ)
result += "\n"
else result += ' '
result
return .= ''
for prop in t
return.value += ` ${prop}: ${renderList t[prop]}\n`
function renderList(l: (string | Tree)[]): string
l.map(render).join(' ')
export function convert(vrml1: string): string
render tree97 vrml1