logik2021/codego/aussagenlogik/schema/schema.go

176 lines
4.4 KiB
Go

package schema
import (
"errors"
"logik/aussagenlogik/syntaxbaum"
parser "logik/grammars/aussagenlogik"
"strings"
"github.com/antlr/antlr4/runtime/Go/antlr"
)
/* ---------------------------------------------------------------- *
* EXPORTS
* ---------------------------------------------------------------- */
func ParseExpr(u string) (syntaxbaum.SyntaxBaum, error) {
var lexer = createLexer(u)
var tokenStream = lexerToTokenStream(lexer)
var prs = parser.NewaussagenlogikParser(tokenStream)
var t = prs.Start()
tree, err := createSyntaxBaum(t, prs)
return tree, err
}
/* ---------------------------------------------------------------- *
* 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, error) {
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, error) {
var tree syntaxbaum.SyntaxBaum
var err error
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.Expr = subant.getTextContentLeaves()
tree.Kind = subant.getLabel()
tree.Children = [](*syntaxbaum.SyntaxBaum){}
tree.Valence = 0
return tree, nil
}
case "not":
if nChildren == 2 { // Children: [NotSymbol, Teilformel]
subtree, err := subants[1].toSyntaxBaum()
tree = syntaxbaum.SyntaxBaum{}
tree.Expr = subants[0].getTextContent() + " " + subtree.Expr
tree.Kind = label
tree.Children = [](*syntaxbaum.SyntaxBaum){&subtree}
tree.Valence = 1
return tree, err
}
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, err_ := subant.toSyntaxBaum()
if err_ != nil {
err = err_
}
subtrees[i] = &subtree
expr += " " + subtree.Expr + " "
i++
}
isSymb = !isSymb
}
expr = strings.Trim(expr, " ")
var lbrace string = "("
var rbrace string = ")"
// var lbrace string = "( "
// var rbrace string = " )"
// if strings.HasPrefix(expr, "(") {
// lbrace = "("
// }
// if strings.HasSuffix(expr, ")") {
// rbrace = ")"
// }
tree = syntaxbaum.SyntaxBaum{}
tree.Expr = lbrace + expr + rbrace
tree.Kind = label
tree.Children = subtrees
tree.Valence = n
return tree, err
}
}
return tree, errors.New("Could not parse expression")
}