Skip to content

Instantly share code, notes, and snippets.

@dotmilk
Created June 18, 2018 18:00
Show Gist options
  • Save dotmilk/b3816246b3a30f38018523e90042a0b4 to your computer and use it in GitHub Desktop.
Save dotmilk/b3816246b3a30f38018523e90042a0b4 to your computer and use it in GitHub Desktop.
class Derives {
constructor() {
}
parse(w,l) {
if (l == null) {
l = this
}
if (w == '') {
return nullable(l)
}
let [head, ...tail] = w
return this.parse(tail,this.derive(head,l))
}
derive(char,o = undefined) {
if (o == undefined) {
o = this
}
switch(true) {
case o instanceof Empty:
return new Empty()
case o instanceof Eps:
return new Empty()
case o instanceof Char:
if (o.c == char) {
return new Eps()
} else {
return new Empty()
}
case o instanceof Rep:
return new Cat(o.r.derive(char), o)
case o instanceof Alt:
return new Alt(o.l.derive(char), o.r.derive(char))
case o instanceof Cat:
let leftDerivative = new Cat(o.l.derive(char),o.r)
if (nullable(o.l)) {
return new Alt(leftDerivative, o.r.derive(char))
}
return leftDerivative
}
}
}
class Empty extends Derives {}
class Eps extends Derives {}
class Char extends Derives {
constructor(c) {
super()
this.char = c
}
get c() {
return this.char
}
}
class Cat extends Derives {
constructor(l,r) {
super()
let args = Array.from(arguments).slice(2)
if (args.length > 0) {
this.l = l
let [head, ...tail] = args
this.r = new Cat(r,head,...tail)
} else {
this.l = l
this.r = r
}
}
}
class Alt extends Derives {
constructor(l,r) {
super()
let args = Array.from(arguments).slice(2)
if (args.length > 0) {
this.l = l
let [head, ...tail] = args
this.r = new Alt(r,head,...tail)
} else {
this.l = l
this.r = r
}
}
}
class Rep extends Derives {
constructor(r) {
super()
this.r = r
}
}
function nullable(l) {
switch(true) {
case (l instanceof Empty || l instanceof Char):
return false
case (l instanceof Eps || l instanceof Rep):
return true
case l instanceof Alt:
return nullable(l.l) || nullable(l.r)
case l instanceof Cat:
return nullable(l.l) && nullable(l.r)
}
}
let digit = new Alt(...['1','2','3','4','5','6','7','8','9','0'].map((x)=>{return new Char(x)}))
let floater = new Cat(new Alt(new Eps(), new Alt(new Char("+"), new Char("-"))),
new Rep(digit),
new Char('.'),
digit,
new Rep(digit))
console.log(floater.parse('-2.0'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment