In seguito lungo le linee di Come sono chiaramente una.b[c.d][e].f[g[h[i.j]]] come un albero di oggetti?, come scrivere un algoritmo per generare il JS AST dall'espressione a.b[c.d][e].f[g[h[i.j]]]
? Sto cercando di scrivere un parser per generare una sorta di struttura dell'oggetto da questa espressione (idealmente più intuitivo rispetto JS AST MemberExpression
uno, di conseguenza, che altri questione). Mi piacerebbe vedere come funziona l'algoritmo per costruire il JavaScript MemberExpression
albero.
Attualmente ho questo tipo di algoritmo per generare una sorta di albero (ma sembra non essere corretto, al momento):
const patterns = [
[/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*/, 'name'],
[/^\[/, 'open'],
[/^\]/, 'close'],
[/^\./, 'stem']
]
console.log(parsePath('a.b[c.d][e].f[g[h[i.j]]]'))
function parsePath(str) {
let node
let nest = []
let result = nest
let stack = [nest]
while (str.length) {
nest = stack[stack.length - 1]
p:
for (let pattern of patterns) {
let match = str.match(pattern[0])
if (match) {
if (pattern[1] === 'name') {
node = {
form: `term`,
name: match[0],
link: []
}
nest.push(node)
} else if (pattern[1] === 'stem') {
stack.push(node.link)
} else if (pattern[1] === 'open') {
node = {
form: 'read',
link: []
}
nest.push(node)
stack.push(node.link)
} else if (pattern[1] === 'close') {
stack.pop()
}
str = str.substr(match[0].length)
break p
}
}
}
return result[0]
}
Il risultato desiderato è questo (o meglio, più intuitiva struttura di dati se siete così inclinato per creare una):
{
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "a"
},
"property": {
"type": "Identifier",
"name": "b"
},
"computed": false
},
"property": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "c"
},
"property": {
"type": "Identifier",
"name": "d"
},
"computed": false
},
"computed": true
},
"property": {
"type": "Identifier",
"name": "e"
},
"computed": true
},
"property": {
"type": "Identifier",
"name": "f"
},
"computed": false
},
"property": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "g"
},
"property": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "h"
},
"property": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "i"
},
"property": {
"type": "Identifier",
"name": "j"
},
"computed": false
},
"computed": true
},
"computed": true
},
"computed": true
}
La ragione per cui sto lottando (parzialmente) è che non mi piace questo MemberExpression
struttura ad albero, è indietro di sentimento e non molto intuitivo. Quindi, se si potesse costruire un modo più semplice più semplice struttura di dati che sarebbe l'ideale (che è l'altra questione), ma se poi non solo un algoritmo per costruire questo mi avrebbe intenzione.
Personalmente mi piacerebbe provare a generare questo tipo di struttura, in quanto la trovo più intuitiva:
{
type: 'site',
site: [
{
type: 'term',
term: 'a'
},
{
type: 'term',
term: 'b'
},
{
type: 'sink',
sink: [
{
type: 'term',
term: 'c'
},
{
type: 'term',
term: 'd'
}
]
},
{
type: 'sink',
sink: [
{
type: 'term',
term: 'e'
}
]
},
{
type: 'term',
term: 'f'
},
{
type: 'sink',
sink: [
{
type: 'term',
term: 'g'
},
{
type: 'sink',
sink: [
{
type: 'term',
term: 'h'
},
{
type: 'sink',
sink: [
{
type: 'term',
term: 'i'
},
{
type: 'term',
term: 'j'
}
]
}
]
}
]
}
]
}
Ma funziona per me (o entrambi).
Se ci vai con la seconda, il mio prossimo problema sarà come convertire la struttura di dati in MemberExpression
albero/struttura dei dati :) proverò a fare anche io prima. Quindi è probabilmente meglio per costruire il MemberExpression in questa domanda, quindi posso lavorare fuori che.