Skip to content

Commit

Permalink
wip symbolic graph
Browse files Browse the repository at this point in the history
  • Loading branch information
winitzki committed Jul 22, 2024
1 parent 98398de commit 344c332
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 39 deletions.
51 changes: 21 additions & 30 deletions nano-dhall/src/main/scala/io/chymyst/nanodhall/SymbolicGraph.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,35 @@ package io.chymyst.nanodhall
import sourcecode.{File, Line, Name}

object SymbolicGraph {
sealed trait Rule

final case class LiteralMatch(text: String) extends Rule

final class GrammarSymbol(name: String, rule: => RuleDef) extends Rule

implicit class SymbolicGraphOps(r: => Rule) {
def ~(next: => Rule)
final case class RuleDef(val name: String, rule: () => GrammarRule) {
override def equals(obj: Any): Boolean = obj match {
case r: RuleDef => name == r.name
case _ => false
}
}

def chars(x : String) = ???
sealed trait GrammarRule

sealed trait RuleDef {
def name: String = "undefined"
// def ~(next: => RuleDef)(implicit file: File, line: Line, varName: Name): RuleDef =
// new And(varName.value, Seq(this, next))
//
// def |(next: => RuleDef)(implicit file: File, line: Line, varName: Name): RuleDef =
// new Or(varName.value, Seq(this, next))
final case class LiteralMatch(text: String) extends GrammarRule

def print: String
}
final case class GrammarSymbol(val name: String, rule: () => RuleDef) extends GrammarRule {
override def equals(obj: Any): Boolean = obj match {
case s: GrammarSymbol => name == s.name
case _ => false
}

final case class Literal(matcher: LiteralMatch)(implicit file: File, line: Line, varName: Name) extends RuleDef {
val name: String = varName.value
def print: String = s""
}
//
// final class RuleX(val name: String, definition: => RuleDef) extends RuleDef {
// def print: String = s"$name := ${definition.print}"
// }

final class And( rules: Seq[Rule ]) extends RuleDef {
implicit class SymbolicGraphOps(r: => RuleDef) {
def ~(next: => RuleDef)(implicit file: File, line: Line, varName: Name): RuleDef =
new RuleDef(name = varName.value, rule = () => And(r.rule(), next.rule()))

def print: String = s""
def |(next: => RuleDef)(implicit file: File, line: Line, varName: Name): RuleDef = new RuleDef(name = varName.value, rule = () => Or(r.rule(), next.rule()))
}

final class Or( rules: Seq[Rule]) extends RuleDef {
def print: String = s""
}
def lit(s: String)(implicit file: File, line: Line, varName: Name): RuleDef = new RuleDef(name = varName.value, rule = () => LiteralMatch(s))

final case class And(rule1: GrammarRule, rule2: GrammarRule) extends GrammarRule

final case class Or(rule1: GrammarRule, rule2: GrammarRule) extends GrammarRule
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,36 @@ class SymbolicGraphTest extends FunSuite {

test("circular dependencies do not create an infinite loop 1") {

def a: RuleDef = chars("x")
def a: RuleDef = lit("x")

def b: RuleDef = chars("y") ~ b | chars("z")
def b: RuleDef = lit("y") ~ b | lit("z")

expect(a.name == "a")
expect(b.name == "b")

expect(a == RuleDef(name = "a", defs = LiteralMatch("x")))
expect(b == RuleDef(name = "b", defs = Or(And(LiteralMatch("y"), Rule("b", b)), LiteralMatch("z"))))
expect(a == new RuleDef(name = "a", rule = () => LiteralMatch("x")))
expect(b == new RuleDef(name = "b", rule = () => Or(And(LiteralMatch("y"), new GrammarSymbol("b", () => b)), LiteralMatch("z"))))
}

test("circular dependencies do not create an infinite loop 2") {

def a: RuleDef = b ~ c

def b: RuleDef = chars("x") ~ a ~ b | chars("y")
def b: RuleDef = lit("x") ~ a ~ b | lit("y")

def c: RuleDef = chars("z") ~ a
def c: RuleDef = lit("z") ~ a

expect(a.name == "a")
expect(b.name == "b")
expect(c.name == "c")

expect(a == RuleDef(name = "a", defs = And(Rule("b", b), Rule("c", c))))
expect(b == RuleDef(name = "b", defs = Or(And(LiteralMatch("x"), Rule("a", a), Rule("b", b)), LiteralMatch("y"))))
expect(c == RuleDef(name = "c", defs = And(LiteralMatch("z"), Rule("a", a))))
expect(a == new RuleDef(name = "a", rule = () => And(new GrammarSymbol("b", () => b), new GrammarSymbol("c", () => c))))
expect(
b == new RuleDef(
name = "b",
rule = () => Or(And(And(LiteralMatch("x"), new GrammarSymbol("a", () => a)), new GrammarSymbol("b", () => b)), LiteralMatch("y")),
)
)
expect(c == new RuleDef(name = "c", rule = () => And(LiteralMatch("z"), new GrammarSymbol("a", () => a))))
}
}

0 comments on commit 344c332

Please sign in to comment.