Ejemplo n.º 1
0
func LL1_to_AST(root ast.Node) ast.Node {

	var Expr func(ast.Node) ast.Node
	var Expr_ func(ast.Node) (bool, ast.Node, ast.Node)
	var Term func(ast.Node) ast.Node
	var Term_ func(ast.Node) (bool, ast.Node, ast.Node)
	var Factor func(ast.Node) ast.Node

	Expr = func(node ast.Node) ast.Node {
		left := Term(node.GetKid(0))
		if empty, op, right := Expr_(node.GetKid(1)); empty {
			return left
		} else {
			return op.AddKid(left).AddKid(right)
		}
		panic("unreachable")
	}

	Expr_ = func(node ast.Node) (bool, ast.Node, ast.Node) {
		if node.GetKid(0).Label().Equals(ast.Type("e")) {
			return true, nil, nil
		}
		myop := ast.New(node.GetKid(0).Label())
		left := Term(node.GetKid(1))
		if empty, op, right := Expr_(node.GetKid(2)); empty {
			return false, myop, left
		} else {
			return false, myop, op.AddKid(left).AddKid(right)
		}
		panic("unreachable")
	}

	Term = func(node ast.Node) ast.Node {
		left := Factor(node.GetKid(0))
		if empty, op, right := Term_(node.GetKid(1)); empty {
			return left
		} else {
			return op.AddKid(left).AddKid(right)
		}
		panic("unreachable")
	}

	Term_ = func(node ast.Node) (bool, ast.Node, ast.Node) {
		if node.GetKid(0).Label().Equals(ast.Type("e")) {
			return true, nil, nil
		}
		myop := ast.New(node.GetKid(0).Label())
		left := Factor(node.GetKid(1))
		if empty, op, right := Term_(node.GetKid(2)); empty {
			return false, myop, left
		} else {
			return false, myop, op.AddKid(left).AddKid(right)
		}
		panic("unreachable")
	}

	Factor = func(node ast.Node) ast.Node {
		if node.GetKid(0).Label().Equals(ast.Type("(")) {
			return Expr(node.GetKid(1))
		} else if node.GetKid(0).Label().Equals(ast.Type("-")) {
			return ast.New(lexer.Int(int(node.GetKid(1).Label().(lexer.Int)) * -1))
		}
		return ast.New(node.GetKid(0).Label())
	}

	return Expr(root)
}
Ejemplo n.º 2
0
func Recursive(text []byte) (Errors, ast.Node) {
	success, tokens := lex.Lex(lexer.Patterns, text)

	type production func() (bool, ast.Node)
	var Expr production
	var Expr_ production
	var Term production
	var Term_ production
	var Factor production

	errors := make(Errors, 0)

	var _top lex.Token
	peak := func() (tok lex.Token, closed bool) {
		if _top == nil {
			if token, ok := <-tokens; !ok {
				return nil, true
			} else {
				_top = token
			}
		}
		return _top, false
	}

	consume := func() {
		_top = nil
	}

	Expr = func() (bool, ast.Node) {
		// Expr : Term Expr_
		n := ast.New(ast.Type("Expr"))
		ok1, r0 := Term()  // Expr : Term . Expr_
		ok2, r1 := Expr_() // Expr : Term Expr_ .
		return ok1 && ok2, n.AddKid(r0).AddKid(r1)
	}

	Expr_ = func() (bool, ast.Node) {
		/* Expr_ : PLUS Term Expr_
		 * Expr_ : DASH Term Expr_
		 * Expr_ : e (the empty string) */
		n := ast.New(ast.Type("Expr_"))
		token, closed := peak()
		if closed { // Expr_ : e .
			return true, n.AddKid(ast.New(ast.Type("e")))
		}
		a := token.ID()
		if a == lexer.Tokens["PLUS"] { // Expr_ : PLUS . Term Expr_
			consume()
			n.AddKid(ast.New(ast.Type("+")))
		} else if a == lexer.Tokens["DASH"] { // Expr_ : DASH . Term Expr_
			consume()
			n.AddKid(ast.New(ast.Type("-")))
		} else {
			return true, n.AddKid(ast.New(ast.Type("e"))) // Expr_ : e .
		}
		ok1, r0 := Term()  // Expr_ : (PLUS|DASH) Term . Expr_
		ok2, r1 := Expr_() // Expr_ : (PLUS|DASH) Term Expr_ .
		return ok1 && ok2, n.AddKid(r0).AddKid(r1)
	}

	Term = func() (bool, ast.Node) {
		// Term : Factor Term_
		n := ast.New(ast.Type("Term"))
		ok1, r0 := Factor() // Term : Factor . Term_
		ok2, r1 := Term_()  // Term : Facttor Term_ .
		return ok1 && ok2, n.AddKid(r0).AddKid(r1)
	}

	Term_ = func() (bool, ast.Node) {
		/* Term_ : STAR Factor Term_
		 * Term_ : SLASH Factor Term_
		 * Term_ : e (the empty string) */
		n := ast.New(ast.Type("Term_"))
		token, closed := peak()
		if closed { // Term_ : e .
			return true, n.AddKid(ast.New(ast.Type("e")))
		}
		a := token.ID()
		if a == lexer.Tokens["STAR"] { // Term_ : STAR . Factor Term_
			consume()
			n.AddKid(ast.New(ast.Type("*")))
		} else if a == lexer.Tokens["SLASH"] { // Term_ : SLASH . Factor Term_
			consume()
			n.AddKid(ast.New(ast.Type("/")))
		} else {
			return true, n.AddKid(ast.New(ast.Type("e"))) // Term_ : e .
		}
		ok1, r0 := Factor() // Term_ : (STAR|SLASH) Factor . Term_
		ok2, r1 := Term_()  // Term_ : (STAR|SLASH) Factor Term_ .
		return ok1 && ok2, n.AddKid(r0).AddKid(r1)
	}

	Factor = func() (bool, ast.Node) {
		/* Factor : NUMBER
		 * Factor : DASH NUMBER
		 * Factor : LPAREN Expr RPAREN */
		n := ast.New(ast.Type("Factor"))
		token, closed := peak()
		if closed {
			errors = append(errors, "Expected a (NUMBER|DASH|LPAREN) got EOF")
			return false, ast.New(ast.Type("end of input"))
		}
		a := token.ID()
		if a == lexer.Tokens["NUMBER"] { // Factor : NUMBER .
			consume()
			label := token.Attribute().Value().(ast.EquaCompare)
			n.AddKid(ast.New(label))
		} else if a == lexer.Tokens["DASH"] { // Factor : DASH . NUMBER
			consume()
			token, closed := peak()
			if closed {
				errors = append(errors, "expected a NUMBER got EOF")
				return false, ast.New(ast.Type("end of input"))
			} else if token.ID() == lexer.Tokens["NUMBER"] { // Factor : DASH NUMBER .
				consume()
				label := token.Attribute().Value().(ast.EquaCompare)
				n.AddKid(ast.New(ast.Type("-")))
				n.AddKid(ast.New(label))
			} else {
				errors = append(errors, "Expected a NUMBER")
				return false, n
			}
		} else if a == lexer.Tokens["LPAREN"] { // Factor : LPAREN . Expr RPAREN
			consume()
			ok, r0 := Expr() // Factor : LPAREN Expr . RPAREN
			if !ok {
				return false, n
			}
			token, closed := peak()
			if closed {
				errors = append(errors, "Expected an RPAREN found EOF")
				return false, n
			} else if token.ID() == lexer.Tokens["RPAREN"] { // Factor : LPAREN Expr RPAREN .
				consume()
				n.AddKid(ast.New(ast.Type("("))).AddKid(r0).AddKid(ast.New(ast.Type(")")))
			} else {
				errors = append(errors, "Expected an RPAREN")
				return false, n
			}
		} else {
			errors = append(errors, "Expected a (NUMBER|DASH|LPAREN)")
			return false, n
		}
		return true, n
	}

	ok, root := Expr()
	if _, closed := peak(); !closed {
		errors = append(errors, "unconsumed input")
		for _ = range tokens {
		}
		ok = false
	}
	if !(<-success) {
		errors = append(errors, "lexing error (unconsumed input in the lexer)")
		ok = false
	}
	if !ok {
		return errors, nil
	}

	return nil, root
}