All Downloads are FREE. Search and download functionalities are using the official Maven repository.

miksilo.modularLanguages.deltas.trivia.TriviaInsideNode.scala Maven / Gradle / Ivy

The newest version!
package miksilo.modularLanguages.deltas.trivia

import miksilo.modularLanguages.core.bigrammar.{BiGrammar, GrammarPath, GrammarReference, RootGrammar}
import miksilo.modularLanguages.core.bigrammar.grammars.{BiChoice, BiFailure, BiSequence, WithTrivia}
import miksilo.modularLanguages.core.deltas.grammars.LanguageGrammars
import miksilo.modularLanguages.core.deltas.{Contract, DeltaWithGrammar}
import miksilo.languageServer.core.language.Language
import miksilo.modularLanguages.core.node.NodeGrammar

//noinspection ZeroIndexToHead
object TriviaInsideNode extends DeltaWithGrammar {

  override def description: String = "Moves trivia grammars left of a node to the inside of the node"

  override def transformGrammars(_grammars: LanguageGrammars, language: Language): Unit = {
    val grammars = _grammars
    import grammars._
    var visited = Set.empty[BiGrammar]
    val descendants = root.descendants
    for(path <- descendants)
    {
      path.value match {
        case trivia: WithTrivia =>
          if (!visited.contains(path.value)) {
            visited += path.value

            val grammar = trivia.inner
            if (hasLeftNode(new RootGrammar(grammar))) {
              path.set(trivia.inner)
              injectTrivia(grammars, path, trivia.horizontal)
            }
          }
        case _ =>
      }
    }
  }

  private def hasLeftNode(path: GrammarPath) = {
    val leftChildren = path.value.getLeftChildren
    leftChildren.exists(p => p.isInstanceOf[NodeGrammar])
  }

  def injectTrivia(grammars: LanguageGrammars, grammar: GrammarReference, horizontal: Boolean): Unit = {
    if (grammar.value.isInstanceOf[WithTrivia])
      return //TODO if we consider the grammars as a graph and only move WithTrivia's from all incoming edges at once, then we wouldn't need this hack.

    grammar.value match {
      case sequence: BiSequence =>
        val left = sequence.getLeftChildren.drop(1).head
        val child = grammar.children.find(ref => ref.value == left).get
        injectTrivia(grammars, child, horizontal)
      case _:NodeGrammar =>
        if (!grammar.children.head.value.isLeftRecursive) {
          placeTrivia(grammars, grammar.children.head, horizontal)
        }
      case _: BiChoice =>
        injectTrivia(grammars, grammar.children(0), horizontal)
        injectTrivia(grammars, grammar.children(1), horizontal)
      case _: BiFailure =>
      case _ =>
        if (grammar.children.length == 1)
          injectTrivia(grammars, grammar.children.head, horizontal)
        else placeTrivia(grammars, grammar, horizontal)
    }
  }

  def placeTrivia(grammars: LanguageGrammars, grammar: GrammarReference, horizontal: Boolean): Unit = {
    if (!grammar.value.isInstanceOf[WithTrivia] && grammar.value.containsParser()) {
      grammar.set(new WithTrivia(grammar.value, grammars.trivia, horizontal))
    }
  }

  override def dependencies: Set[Contract] = Set.empty
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy