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") }