În urma de-a lungul liniilor de Cum se reprezintă în mod clar o.b[c.d][e].f[g[h[i.j]]] ca un obiect copac?, cum ai scrie un algoritm pentru a genera JS AST de exprimare a.b[c.d][e].f[g[h[i.j]]]
? Încerc să scriu un parser pentru a genera un fel de obiect structura din această expresie (în mod ideal, mai intuitiv decât JS AST MemberExpression
unul, prin urmare, că altă întrebare). Aș vrea să văd cum functioneaza algoritmul pentru a construi JavaScript MemberExpression
copac.
În prezent, am avea acest tip de algoritm pentru a genera un fel de copac (dar se pare a fi incorectă în prezent):
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]
}
Rezultatul dorit este aceasta (sau o mai bună, mai intuitiv structura de date, dacă sunteți atât de înclinat pentru a crea unul):
{
"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
}
Motivul pentru care eu sunt luptă (parțial) e nu-mi place asta MemberExpression
structură arborescentă, e înapoi sentiment și nu foarte intuitivă. Deci, dacă ai putea construi un simplu mult mai simplă structură de date care ar fi ideal (care a fost de altă cauză), dar dacă nu, atunci un algoritm pentru a construi acest lucru ar fi să mă duc.
Personal, aș încerca mai degrabă să genereze această structură, ca mi se pare mai intuitiv:
{
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'
}
]
}
]
}
]
}
]
}
Dar nici unul lucrează pentru mine (sau ambele).
Dacă vom merge cu cel de-al doilea, urmatoarea mea problema va fi cum de a converti care structura de date în MemberExpression
copac/structura de date :) Dar voi încerca să fac și eu asta în primul rând. Deci, este, probabil, mai bine pentru a construi MemberExpression în această întrebare, atunci nu pot lucra.