@renatorib/

parser-v1

Nodejs

No description

fork
loading
Files
  • index.js

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.8579841012094866","path":"index.js","file":{"path":"index.js","content":{"asEncoding":{"base64":"Y29uc3QgbGV4ZXIgPSBpbnB1dCA9PiB7CiAgbGV0IHRva2VucyA9IFtdCiAgbGV0IGN1cnJlbnQgPSAwCiAgCiAgd2hpbGUgKGN1cnJlbnQgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGxldCBjaGFyID0gaW5wdXRbY3VycmVudF0KICAgIAogICAgaWYgKGNoYXIgPT09ICIgIikgewogICAgICBjdXJyZW50KysKICAgICAgY29udGludWUKICAgIH0KCiAgICBpZiAoY2hhciA9PT0gIisiKSB7CiAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogIlBsdXMiIH0pCiAgICAgIGN1cnJlbnQrKwogICAgICBjb250aW51ZQogICAgfQoKICAgIGlmIChjaGFyID09PSAiLSIpIHsKICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiAiTWludXMiIH0pCiAgICAgIGN1cnJlbnQrKwogICAgICBjb250aW51ZQogICAgfQoKICAgIGlmIChjaGFyID09PSAiKiIpIHsKICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiAiU3RhciIgfSkKICAgICAgY3VycmVudCsrCiAgICAgIGNvbnRpbnVlCiAgICB9CgogICAgaWYgKGNoYXIgPT09ICIvIikgewogICAgICB0b2tlbnMucHVzaCh7IHR5cGU6ICJTbGFzaCIgfSkKICAgICAgY3VycmVudCsrCiAgICAgIGNvbnRpbnVlCiAgICB9CiAgICAKICAgIGlmIChjaGFyID09PSAiKCIpIHsKICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiAiTGVmdFBhcmVuIiB9KQogICAgICBjdXJyZW50KysKICAgICAgY29udGludWUKICAgIH0KCiAgICBpZiAoY2hhciA9PT0gIikiKSB7CiAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogIlJpZ2h0UGFyZW4iIH0pCiAgICAgIGN1cnJlbnQrKwogICAgICBjb250aW51ZQogICAgfQoKICAgIGlmICgvWzAtOV0vLnRlc3QoY2hhcikpIHsKICAgICAgbGV0IHZhbHVlID0gJycKCiAgICAgIHdoaWxlICgvWzAtOV0vLnRlc3QoY2hhcikpIHsKICAgICAgICB2YWx1ZSArPSBjaGFyCiAgICAgICAgY3VycmVudCsrCiAgICAgICAgY2hhciA9IGlucHV0W2N1cnJlbnRdCiAgICAgIH0KICAgICAgCiAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogIk51bWJlciIsIHZhbHVlOiBwYXJzZUludCh2YWx1ZSwgMTApIH0pCiAgICAgIAogICAgICBjb250aW51ZQogICAgfQoKICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBjaGFyICR7Y2hhcn1gKQogIH0KCiAgdG9rZW5zLnB1c2goeyB0eXBlOiAiRW5kIiB9KQoKICByZXR1cm4gdG9rZW5zCn0gIAoKY29uc3QgcGFyc2VyID0gdG9rZW5zID0+IHsKICBsZXQgY3VycmVudCA9IDAKCiAgY29uc3QgcGVlayA9ICgpID0+IHRva2Vuc1tjdXJyZW50XQogIGNvbnN0IHByZXYgPSAoKSA9PiB0b2tlbnNbY3VycmVudCAtIDFdCiAgY29uc3QgbWF0Y2ggPSB0eXBlID0+IHsKICAgIGlmIChwZWVrKCkudHlwZSA9PT0gdHlwZSkgewogICAgICBjdXJyZW50KysKICAgICAgcmV0dXJuIHRydWUKICAgIH0KICAgIHJldHVybiBmYWxzZQogIH0KCiAgY29uc3QgZXhwciA9ICgpID0+IHsKICAgIHJldHVybiBhZGQoKQogIH0KCiAgY29uc3QgYWRkID0gKCkgPT4gewogICAgbGV0IHJlc3VsdCA9IG11bCgpCgogICAgd2hpbGUgKG1hdGNoKCdQbHVzJykpIHsKICAgICAgcmVzdWx0ID0gcmVzdWx0ICsgbXVsKCkKICAgIH0KCiAgICByZXR1cm4gcmVzdWx0CiAgfQoKICBjb25zdCBtdWwgPSAoKSA9PiB7CiAgICBsZXQgcmVzdWx0ID0gbnVtKCkKCiAgICB3aGlsZSAobWF0Y2goJ1N0YXInKSkgewogICAgICByZXN1bHQgPSByZXN1bHQgKiBudW0oKQogICAgfSAgICAKCiAgICByZXR1cm4gcmVzdWx0CiAgfQoKICBjb25zdCBudW0gPSAoKSA9PiB7CiAgICBpZiAobWF0Y2goJ051bWJlcicpKSB7CiAgICAgIHJldHVybiBwcmV2KCkudmFsdWUKICAgIH0KCiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgJHtwZWVrKCkudHlwZX0gdG9rZW5gKQogIH0KCiAgcmV0dXJuIGV4cHIoKQp9Cgpjb25zb2xlLmxvZygnNCArIDMgKiAyID0nLCBwYXJzZXIobGV4ZXIoJzQgKyAzICogMicpKSkKY29uc29sZS5sb2coJzQgKiAzICsgMiA9JywgcGFyc2VyKGxleGVyKCc0ICogMyArIDInKSkp"},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const lexer = input => {
  let tokens = []
  let current = 0
  
  while (current < input.length) {
    let char = input[current]
    
    if (char === " ") {
      current++
      continue
    }

    if (char === "+") {
      tokens.push({ type: "Plus" })
      current++
      continue
    }

    if (char === "-") {
      tokens.push({ type: "Minus" })
      current++
      continue
    }

    if (char === "*") {
      tokens.push({ type: "Star" })
      current++
      continue
    }

    if (char === "/") {
      tokens.push({ type: "Slash" })
      current++
      continue
    }
    
    if (char === "(") {
      tokens.push({ type: "LeftParen" })
      current++
      continue
    }

    if (char === ")") {
      tokens.push({ type: "RightParen" })
      current++
      continue
    }

    if (/[0-9]/.test(char)) {
      let value = ''

      while (/[0-9]/.test(char)) {
        value += char
        current++
        char = input[current]
      }
      
      tokens.push({ type: "Number", value: parseInt(value, 10) })
      
      continue
    }

    throw new Error(`Unexpected char ${char}`)
  }

  tokens.push({ type: "End" })

  return tokens
}  

const parser = tokens => {
  let current = 0

  const peek = () => tokens[current]
  const prev = () => tokens[current - 1]
  const match = type => {
    if (peek().type === type) {
      current++
      return true
    }
    return false
  }

  const expr = () => {
    return add()
  }

  const add = () => {
    let result = mul()

    while (match('Plus')) {
      result = result + mul()
    }

    return result
  }

  const mul = () => {
    let result = num()

    while (match('Star')) {
      result = result * num()
    }    

    return result
  }

  const num = () => {
    if (match('Number')) {
      return prev().value
    }

    throw new Error(`Unexpected ${peek().type} token`)
  }

  return expr()
}

console.log('4 + 3 * 2 =', parser(lexer('4 + 3 * 2')))
console.log('4 * 3 + 2 =', parser(lexer('4 * 3 + 2')))
node v10.16.0