Následující podél linií , Jak jasně představují.b[c.d][e].f[g[h[já.j]]] jako objekt strom?, jak by se vám napsat algoritmus pro generování, které JS AST z výrazu a.b[c.d][e].f[g[h[i.j]]]
? Snažím se napsat parser generovat nějaký objekt struktury z tohoto vyjádření (v ideálním případě více intuitivní než JS AST MemberExpression
jeden, proto, že další otázka). Chtěl bych vidět, jak algoritmus pracuje postavit JavaScript MemberExpression
strom.
V současné době mám tento druh algoritmu pro generování nějakého stromu (ale to se zdá být nesprávné v současné době):
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žadovaný výsledek je tento (nebo lepší, více intuitivní struktura dat, pokud jste tak nakloněn vytvořit):
{
"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
}
Důvod, proč jsem bojovat (částečně) je, že jsem se to nelíbí MemberExpression
stromovou strukturu, je to zpětně pocit, a ne příliš intuitivní. Takže pokud jste mohl postavit jednodušší, přímočařejší struktura dat, která by bylo ideální (to byla jiná otázka), ale pokud ne, pak jen algoritmus pro konstrukci to by se mi děje.
Osobně bych se spíše snažit vytvořit tuto strukturu, protože mi připadá více intuitivní:
{
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 buď jeden pracuje pro mě (nebo obojí).
Pokud půjdeme s druhým, můj další problém bude, jak to převést datové struktury do MemberExpression
strom/struktura dat :) Ale budu se snažit a dělat, že jsem první. Takže je asi lepší postavit MemberExpression v této otázce, pak mohu pracovat.