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