Postępując zgodnie z instrukcjami wyświetlanymi o tym, jak jasno przedstawić a.b[c.d][e].f[g[h[i.j]]] w postaci drzewa obiektów?, jak byś napisał algorytm do generowania tego JS AST z wyrażenia a.b[c.d][e].f[g[h[i.j]]]
? Próbuję napisać parser do tworzenia jakiejkolwiek struktury obiektu z tej wypowiedzi (najlepiej bardziej intuicyjnego niż JS AST MemberExpression
jeden, stąd inna kwestia). Chciałbym zobaczyć, jak działa algorytm wyznaczania JavaScript MemberExpression
drzewo.
Obecnie mam taki algorytm do tworzenia jakiegoś drzewa (ale obecnie wydaje się błędna).:
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]
}
Pożądany wynik taki (lub lepsza, bardziej intuicyjna struktura danych, jeśli jesteś tak skłonny ją tworzyć).:
{
"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
}
Powodem, dla którego walczę (częściowo), w tym, że nie podoba mi się to MemberExpression
struktura drzewa, to отсталое uczucie i nie bardzo intuicyjne. Tak więc, jeśli można zbudować bardziej prostą i czytelną strukturę danych, która byłaby idealnym (był to inna kwestia), ale jeśli nie, to po prostu łódź aby ją zbudować kazał mi iść dalej.
Osobiście wolałbym spróbować stworzyć tę strukturę, ponieważ uważam że to jest bardziej intuicyjny:
{
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'
}
]
}
]
}
]
}
]
}
Ale albo jeden z nich działa na mnie (lub oba).
Jeśli przejdziemy do drugiego, mój następny problem będzie w tym, jak przekształcić tę strukturę danych w MemberExpression
drewna/struktura danych :) Ale najpierw spróbuję zrobić to sam. Więc chyba lepiej zbudować wyrażenie MemberExpression w tej kwestii, to będę to odpracować.