ยังต้องเขียนตัวกระจายคำที่สร้างจาวาสคริปต์ AST MemberExpression สำหรับการแสดงบี[c.d][อี].f[g[h[ผมก็ไม่ต่างกันหรอกเจ]]]?

0

คำถาม

ตามเส้นทางขอ งเห็นได้ชัดว่าเป็นตัวแทนขอเป็น.บี[c.d][อี].f[g[h[ผมก็ไม่ต่างกันหรอกเจ]]]เหมือนกับวัตถุอย่างนึต้นไม้คริสมาสต์เหรอ?, ยังไงคุณเขียนอัลกอริธึมต้องสร้างนั่น JS AST จากการแสดง a.b[c.d][e].f[g[h[i.j]]]? ฉันกำลังพยายามเขียนตัวกระจายคำที่จะสร้างบางอย่างของวัตถุงโครงสร้างจากสำนวน(เข้าท่าดีนิเราจะทำทุกอย่างที่เราทำมากก intuitive ว่า JS AST MemberExpression หนึ่งจึงนั้นอีกคำถาม). ฉันอยากจะเห็นว่าอัลกอริธึมทำงานเพื่อสร้างจาวาสคริปต์ MemberExpression ต้นไม้

ตอนนี้ฉันมีเรื่องแบบอัลกอริธึมต้องสร้าง บางอย่าง ต้นไม้(แต่มันดูเหมือนจะไม่ถูกต้องปัจจุบัน):

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]
}

ที่ต้องการผลลัพธ์นี้คือ(หรือดีกว่านี้มากก intuitive ข้อมูลของโครงสร้างถ้าคุณช่างมีแนวโน้มที่จะสร้างหนึ่ง):

{
  "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
}

เหตุผลที่ฉันต้องดิ้นรน(บางส่วนของ)ฉันไม่ชอบแบบนี้ MemberExpression ต้นไม้ของโครงสร้างมันย้อนกลับรู้สึกและไม่ใช่หัวไวจริงๆ ดังนั้นถ้าคุณสามารถสร้ายที่ง่ายกว่ามากกว่าตรงไปตรงมาข้อมูลของโครงสร้างนั่นคงจะเพ้อฝันไปหน่อย(นั่นเป็นอีกคำถาม),แต่ถ้าไม่งั้นก็เป็นอัลกอริธึมต้องสร้างมันจะพาฉันไป

ส่วนตัวแล้วฉันจะค่อนข้าพยายามที่จะสร้างเรื่องโครงสร้างอย่างที่ฉันเจอมันอีก intuitive:

{
  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'
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

แต่ทั้งหนึ่งทำงานสำหรับฉันหรือทั้งสอง).

ถ้าเราไปด้วยกันที่สองหนึ่งของฉันต่อไปปัญหาจะเป็นวิธีที่แปลงเป็นข้อมูลของโครงสร้างของเข้า MemberExpression ต้นไม้/ข้อมูลของโครงสร้าง:)แต่ผมจะพยายามทำอย่างนั้นตัวเองก่อน ดังนั้นมันอาจจะดีกว่าเพื่อสร้างค MemberExpression อยู่ในคำถามงั้นฉันสามารถทำงานจากนั้น

1

คำตอบที่ดีที่สุด

1
  1. แยกข้อความเข้าไปในกลุ่มของค้าและคุณสมบัติของระดับแรกอย่าง

    [
        "a",
        "b",
        "[c.d]",
        "[e]",
        "f",
        "[g[h[i.j]]]"
    ]
    
  2. เอาวัตถุ

    1. ไปยังรายการท้ายสุดเท่าที่บ้าน
    2. โปรดตรวจสอบว่าทรัพย์สิเริ่มด้วยวงเล็บปิดแล้วตั้ง computed ต้อง true และถอดเสื้อผ้าทรัพย์สินจากคนรอบตัวเล็บ
    3. กลับไปเป็นวัตถุกับ
      • type: "MemberExpression" ,
      • object กับวัตถุ(2.),
      • property กับผลของโทรเรียกฟังก์ชันหลัก getAST (1.),
      • computed.

function getAST(string) {

    function getObject(parts) {
        if (parts.length === 1) return { type: "Identifier", name: parts[0] };

        let property = parts.pop(),
            computed = false;

        if (property.startsWith('[')) {
            computed = true;
            property = property.slice(1, -1);
        }

        return {
            type: "MemberExpression",
            object: getObject(parts),
            property: getAST(property),
            computed
        };
    }

    let i = 0,
        dot,
        bracket,
        parts = [];

    while (i < string.length) {
        dot = string.indexOf('.', i);
        bracket = string.indexOf('[', i);

        if (dot !== -1 && (bracket === -1 || dot < bracket)) {
            const temp = string.slice(i, dot);
            if (temp) parts.push(temp);
            i = dot + 1;
            continue;
        }

        if (bracket !== -1 && (dot === -1 || bracket < dot)) {
            const temp = string.slice(i, bracket);
            if (temp) parts.push(temp);
            i = bracket;

            let open = 1,
                j = i;

            while (++j < string.length) {
                if (string[j] === '[') open++;
                if (string[j] === ']') open--;
                if (!open) break;
            }

            j++;
            parts.push(string.slice(i, j));

            i = j;
            continue;
        }
        parts.push(string.slice(i));
        break;
    }

    return getObject(parts);
}

console.log(getAST('a.b[c.d][e].f[g[h[i.j]]]'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

2021-11-24 07:30:42

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่