162 lines
4.1 KiB
Go
162 lines
4.1 KiB
Go
package schema
|
|
|
|
import (
|
|
"logik/aussagenlogik/syntaxbaum"
|
|
parser "logik/grammars/aussagenlogik"
|
|
"strings"
|
|
|
|
"github.com/antlr/antlr4/runtime/Go/antlr"
|
|
)
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* EXPORTS
|
|
* ---------------------------------------------------------------- */
|
|
|
|
func ParseExpr(u string) syntaxbaum.SyntaxBaum {
|
|
var lexer = createLexer(u)
|
|
var tokenStream = lexerToTokenStream(lexer)
|
|
var prs = parser.NewaussagenlogikParser(tokenStream)
|
|
var t = prs.Start()
|
|
tree := createSyntaxBaum(t, prs)
|
|
return tree
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* PRIVATE
|
|
* ---------------------------------------------------------------- */
|
|
|
|
func exprToStream(u string) *antlr.InputStream {
|
|
return antlr.NewInputStream(u)
|
|
}
|
|
|
|
func lexerToTokenStream(lexer antlr.Lexer) antlr.TokenStream {
|
|
return antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
|
}
|
|
|
|
func createLexer(u string) antlr.Lexer {
|
|
stream := exprToStream(u)
|
|
return parser.NewaussagenlogikLexer(stream)
|
|
}
|
|
|
|
func createSyntaxBaum(tree antlr.Tree, parser antlr.Parser) syntaxbaum.SyntaxBaum {
|
|
var ant = antlrTree{tree: tree, parser: &parser}
|
|
return ant.toSyntaxBaum()
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* Struct: antlrTree + Methods
|
|
* ---------------------------------------------------------------- */
|
|
|
|
type antlrTree struct {
|
|
tree antlr.Tree
|
|
parser *antlr.Parser
|
|
}
|
|
|
|
func (ant antlrTree) getChildren() []antlrTree {
|
|
var nodes = ant.tree.GetChildren()
|
|
var subants = make([]antlrTree, len(nodes))
|
|
for i, node := range nodes {
|
|
subants[i] = antlrTree{tree: node, parser: ant.parser}
|
|
}
|
|
return subants
|
|
}
|
|
|
|
func (ant antlrTree) getLabel() string {
|
|
return antlr.TreesGetNodeText(ant.tree, []string{}, *ant.parser)
|
|
}
|
|
|
|
func (ant antlrTree) getTextContent() string {
|
|
var expr string = ant.getLabel()
|
|
for _, subant := range ant.getChildren() {
|
|
expr += subant.getTextContent()
|
|
}
|
|
return expr
|
|
}
|
|
|
|
func (ant antlrTree) getTextContentLeaves() string {
|
|
var expr string = ""
|
|
var subants = ant.getChildren()
|
|
if len(subants) == 0 {
|
|
expr = ant.getLabel()
|
|
} else {
|
|
for _, subant := range subants {
|
|
expr += subant.getTextContent()
|
|
}
|
|
}
|
|
return expr
|
|
}
|
|
|
|
func (ant antlrTree) toSyntaxBaum() syntaxbaum.SyntaxBaum {
|
|
var tree syntaxbaum.SyntaxBaum
|
|
var label string = ant.getLabel()
|
|
var subants = ant.getChildren()
|
|
var nChildren = len(subants)
|
|
|
|
switch label {
|
|
case "start":
|
|
if nChildren == 1 {
|
|
return subants[0].toSyntaxBaum()
|
|
}
|
|
case "open":
|
|
if nChildren == 1 {
|
|
return subants[0].toSyntaxBaum()
|
|
}
|
|
case "closed":
|
|
switch nChildren {
|
|
case 1:
|
|
return subants[0].toSyntaxBaum()
|
|
case 3:
|
|
return subants[1].toSyntaxBaum()
|
|
}
|
|
case "atomic":
|
|
if nChildren == 1 {
|
|
subant := subants[0]
|
|
tree = syntaxbaum.SyntaxBaum{}
|
|
tree.SetKind(subant.getLabel())
|
|
tree.SetExpr(subant.getTextContentLeaves())
|
|
tree.SetChildren([](*syntaxbaum.SyntaxBaum){})
|
|
return tree
|
|
}
|
|
case "not":
|
|
if nChildren == 2 {
|
|
// NOTE: Children = [NotSymbol, Teilformel]
|
|
subtree := subants[1].toSyntaxBaum()
|
|
tree = syntaxbaum.SyntaxBaum{}
|
|
tree.SetKind(label)
|
|
tree.SetExpr(subants[0].getTextContent() + " " + subtree.GetExpr())
|
|
tree.SetChildren([](*syntaxbaum.SyntaxBaum){&subtree})
|
|
return tree
|
|
}
|
|
case "and2", "and", "or2", "or", "implies":
|
|
var n int = int((len(subants) + 1) / 2)
|
|
if nChildren == 2*n-1 && n >= 2 {
|
|
var isSymb bool = false
|
|
var subtrees = make([](*syntaxbaum.SyntaxBaum), n)
|
|
var i int = 0
|
|
var expr string = ""
|
|
for _, subant := range subants {
|
|
if isSymb {
|
|
expr += " " + subant.getTextContent()
|
|
} else {
|
|
subtree := subant.toSyntaxBaum()
|
|
subtrees[i] = &subtree
|
|
expr += " " + subtree.GetExpr()
|
|
i++
|
|
}
|
|
// NOTE: infix notation: alternatives between expression and symbol
|
|
isSymb = !isSymb
|
|
}
|
|
expr = strings.Trim(expr, " ")
|
|
var lbrace string = "("
|
|
var rbrace string = ")"
|
|
tree = syntaxbaum.SyntaxBaum{}
|
|
tree.SetKind(label)
|
|
tree.SetExpr(lbrace + expr + rbrace)
|
|
tree.SetChildren(subtrees)
|
|
return tree
|
|
}
|
|
}
|
|
|
|
panic("Could not parse expression")
|
|
}
|