diff --git a/parser/parser.go b/parser/parser.go
new file mode 100644
index 0000000..c7be53b
--- /dev/null
+++ b/parser/parser.go
@@ -0,0 +1,125 @@
+package parser
+
+import (
+	"fmt"
+	"matheval/ast"
+	"matheval/token"
+	"strconv"
+)
+
+// Parse converts a slice of tokens into an AST.
+// Returns an error for malformed expressions.
+func Parse(tokens []token.Token) (ast.Node, error) {
+	p := &parser{tokens: tokens}
+	node, err := p.expr()
+	if err != nil {
+		return nil, err
+	}
+	// Ensure all tokens have been consumed (only EOF remains).
+	if p.current().Type != token.EOF {
+		tok := p.current()
+		return nil, fmt.Errorf("unexpected token %v at position %d", tok.Type, tok.Pos)
+	}
+	return node, nil
+}
+
+// parser holds the state for a single parse operation.
+type parser struct {
+	tokens []token.Token
+	pos    int
+}
+
+// current returns the token at the current position.
+func (p *parser) current() token.Token {
+	if p.pos >= len(p.tokens) {
+		return token.Token{Type: token.EOF}
+	}
+	return p.tokens[p.pos]
+}
+
+// advance moves to the next token and returns the previous one.
+func (p *parser) advance() token.Token {
+	tok := p.current()
+	p.pos++
+	return tok
+}
+
+// expect consumes a token of the given type or returns an error.
+func (p *parser) expect(typ token.Type) (token.Token, error) {
+	tok := p.current()
+	if tok.Type != typ {
+		return tok, fmt.Errorf("expected %v but got %v at position %d", typ, tok.Type, tok.Pos)
+	}
+	p.advance()
+	return tok, nil
+}
+
+// expr → term (('+' | '-') term)*
+func (p *parser) expr() (ast.Node, error) {
+	left, err := p.term()
+	if err != nil {
+		return nil, err
+	}
+	for p.current().Type == token.Plus || p.current().Type == token.Minus {
+		op := p.advance()
+		right, err := p.term()
+		if err != nil {
+			return nil, err
+		}
+		left = &ast.BinaryExpr{
+			Op:    op.Type,
+			Left:  left,
+			Right: right,
+		}
+	}
+	return left, nil
+}
+
+// term → factor (('*' | '/') factor)*
+func (p *parser) term() (ast.Node, error) {
+	left, err := p.factor()
+	if err != nil {
+		return nil, err
+	}
+	for p.current().Type == token.Star || p.current().Type == token.Slash {
+		op := p.advance()
+		right, err := p.factor()
+		if err != nil {
+			return nil, err
+		}
+		left = &ast.BinaryExpr{
+			Op:    op.Type,
+			Left:  left,
+			Right: right,
+		}
+	}
+	return left, nil
+}
+
+// factor → NUMBER | '(' expr ')'
+func (p *parser) factor() (ast.Node, error) {
+	tok := p.current()
+	switch tok.Type {
+	case token.Number:
+		p.advance()
+		val, err := strconv.ParseFloat(tok.Literal, 64)
+		if err != nil {
+			return nil, fmt.Errorf("invalid number %q at position %d: %w", tok.Literal, tok.Pos, err)
+		}
+		return &ast.NumberLit{Value: val}, nil
+
+	case token.LParen:
+		p.advance() // consume '('
+		node, err := p.expr()
+		if err != nil {
+			return nil, err
+		}
+		if _, err := p.expect(token.RParen); err != nil {
+			return nil, fmt.Errorf("missing closing parenthesis at position %d", p.current().Pos)
+		}
+		return node, nil
+
+	default:
+		return nil, fmt.Errorf("unexpected token %v at position %d", tok.Type, tok.Pos)
+	}
+}
diff --git a/parser/parser_test.go b/parser/parser_test.go
new file mode 100644
index 0000000..521455b
--- /dev/null
+++ b/parser/parser_test.go
@@ -0,0 +1,473 @@
+package parser
+
+import (
+	"matheval/ast"
+	"matheval/token"
+	"testing"
+)
+
+// helper: tokenize inline for concise tests
+func tokens(toks ...token.Token) []token.Token {
+	return toks
+}
+
+func tok(typ token.Type, lit string, pos int) token.Token {
+	return token.Token{Type: typ, Literal: lit, Pos: pos}
+}
+
+// --- Success cases ---
+
+func TestParseSingleNumber(t *testing.T) {
+	toks := tokens(
+		tok(token.Number, "42", 0),
+		tok(token.EOF, "", 2),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	num, ok := node.(*ast.NumberLit)
+	if !ok {
+		t.Fatalf("expected *ast.NumberLit, got %T", node)
+	}
+	if num.Value != 42 {
+		t.Fatalf("expected 42, got %f", num.Value)
+	}
+}
+
+func TestParseDecimalNumber(t *testing.T) {
+	toks := tokens(
+		tok(token.Number, "3.14", 0),
+		tok(token.EOF, "", 4),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	num, ok := node.(*ast.NumberLit)
+	if !ok {
+		t.Fatalf("expected *ast.NumberLit, got %T", node)
+	}
+	if num.Value != 3.14 {
+		t.Fatalf("expected 3.14, got %f", num.Value)
+	}
+}
+
+func TestParseAddition(t *testing.T) {
+	// 1 + 2
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Plus, "+", 2),
+		tok(token.Number, "2", 4),
+		tok(token.EOF, "", 5),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Plus {
+		t.Fatalf("expected Plus, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 1)
+	assertNumber(t, expr.Right, 2)
+}
+
+func TestParseSubtraction(t *testing.T) {
+	// 5 - 3
+	toks := tokens(
+		tok(token.Number, "5", 0),
+		tok(token.Minus, "-", 2),
+		tok(token.Number, "3", 4),
+		tok(token.EOF, "", 5),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Minus {
+		t.Fatalf("expected Minus, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 5)
+	assertNumber(t, expr.Right, 3)
+}
+
+func TestParseMultiplication(t *testing.T) {
+	// 2 * 3
+	toks := tokens(
+		tok(token.Number, "2", 0),
+		tok(token.Star, "*", 2),
+		tok(token.Number, "3", 4),
+		tok(token.EOF, "", 5),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Star {
+		t.Fatalf("expected Star, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 2)
+	assertNumber(t, expr.Right, 3)
+}
+
+func TestParseDivision(t *testing.T) {
+	// 6 / 2
+	toks := tokens(
+		tok(token.Number, "6", 0),
+		tok(token.Slash, "/", 2),
+		tok(token.Number, "2", 4),
+		tok(token.EOF, "", 5),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Slash {
+		t.Fatalf("expected Slash, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 6)
+	assertNumber(t, expr.Right, 2)
+}
+
+func TestParsePrecedence(t *testing.T) {
+	// 1 + 2 * 3  →  1 + (2 * 3)
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Plus, "+", 2),
+		tok(token.Number, "2", 4),
+		tok(token.Star, "*", 6),
+		tok(token.Number, "3", 8),
+		tok(token.EOF, "", 9),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	// Root should be Plus
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Plus {
+		t.Fatalf("expected Plus at root, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 1)
+	// Right should be Star
+	right, ok := expr.Right.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected right to be *ast.BinaryExpr, got %T", expr.Right)
+	}
+	if right.Op != token.Star {
+		t.Fatalf("expected Star, got %v", right.Op)
+	}
+	assertNumber(t, right.Left, 2)
+	assertNumber(t, right.Right, 3)
+}
+
+func TestParsePrecedenceMulFirst(t *testing.T) {
+	// 2 * 3 + 1  →  (2 * 3) + 1
+	toks := tokens(
+		tok(token.Number, "2", 0),
+		tok(token.Star, "*", 2),
+		tok(token.Number, "3", 4),
+		tok(token.Plus, "+", 6),
+		tok(token.Number, "1", 8),
+		tok(token.EOF, "", 9),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Plus {
+		t.Fatalf("expected Plus at root, got %v", expr.Op)
+	}
+	left, ok := expr.Left.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
+	}
+	if left.Op != token.Star {
+		t.Fatalf("expected Star, got %v", left.Op)
+	}
+	assertNumber(t, left.Left, 2)
+	assertNumber(t, left.Right, 3)
+	assertNumber(t, expr.Right, 1)
+}
+
+func TestParseLeftAssociativity(t *testing.T) {
+	// 1 - 2 - 3  →  (1 - 2) - 3
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Minus, "-", 2),
+		tok(token.Number, "2", 4),
+		tok(token.Minus, "-", 6),
+		tok(token.Number, "3", 8),
+		tok(token.EOF, "", 9),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	// Root: (1 - 2) - 3
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Minus {
+		t.Fatalf("expected Minus at root, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Right, 3)
+	left, ok := expr.Left.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
+	}
+	if left.Op != token.Minus {
+		t.Fatalf("expected Minus, got %v", left.Op)
+	}
+	assertNumber(t, left.Left, 1)
+	assertNumber(t, left.Right, 2)
+}
+
+func TestParseParentheses(t *testing.T) {
+	// (1 + 2) * 3
+	toks := tokens(
+		tok(token.LParen, "(", 0),
+		tok(token.Number, "1", 1),
+		tok(token.Plus, "+", 3),
+		tok(token.Number, "2", 5),
+		tok(token.RParen, ")", 6),
+		tok(token.Star, "*", 8),
+		tok(token.Number, "3", 10),
+		tok(token.EOF, "", 11),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Star {
+		t.Fatalf("expected Star at root, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Right, 3)
+	left, ok := expr.Left.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", expr.Left)
+	}
+	if left.Op != token.Plus {
+		t.Fatalf("expected Plus, got %v", left.Op)
+	}
+	assertNumber(t, left.Left, 1)
+	assertNumber(t, left.Right, 2)
+}
+
+func TestParseNestedParentheses(t *testing.T) {
+	// ((1 + 2))
+	toks := tokens(
+		tok(token.LParen, "(", 0),
+		tok(token.LParen, "(", 1),
+		tok(token.Number, "1", 2),
+		tok(token.Plus, "+", 4),
+		tok(token.Number, "2", 6),
+		tok(token.RParen, ")", 7),
+		tok(token.RParen, ")", 8),
+		tok(token.EOF, "", 9),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	expr, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if expr.Op != token.Plus {
+		t.Fatalf("expected Plus, got %v", expr.Op)
+	}
+	assertNumber(t, expr.Left, 1)
+	assertNumber(t, expr.Right, 2)
+}
+
+func TestParseComplexExpression(t *testing.T) {
+	// 1 + 2 * 3 - 4 / 2  →  (1 + (2*3)) - (4/2)
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Plus, "+", 2),
+		tok(token.Number, "2", 4),
+		tok(token.Star, "*", 5),
+		tok(token.Number, "3", 6),
+		tok(token.Minus, "-", 8),
+		tok(token.Number, "4", 10),
+		tok(token.Slash, "/", 11),
+		tok(token.Number, "2", 12),
+		tok(token.EOF, "", 13),
+	)
+	node, err := Parse(toks)
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	// Root: (1 + (2*3)) - (4/2)
+	root, ok := node.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", node)
+	}
+	if root.Op != token.Minus {
+		t.Fatalf("expected Minus at root, got %v", root.Op)
+	}
+	// Left: 1 + (2*3)
+	left, ok := root.Left.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected left to be *ast.BinaryExpr, got %T", root.Left)
+	}
+	if left.Op != token.Plus {
+		t.Fatalf("expected Plus, got %v", left.Op)
+	}
+	assertNumber(t, left.Left, 1)
+	mul, ok := left.Right.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected *ast.BinaryExpr, got %T", left.Right)
+	}
+	if mul.Op != token.Star {
+		t.Fatalf("expected Star, got %v", mul.Op)
+	}
+	assertNumber(t, mul.Left, 2)
+	assertNumber(t, mul.Right, 3)
+	// Right: 4/2
+	div, ok := root.Right.(*ast.BinaryExpr)
+	if !ok {
+		t.Fatalf("expected right to be *ast.BinaryExpr, got %T", root.Right)
+	}
+	if div.Op != token.Slash {
+		t.Fatalf("expected Slash, got %v", div.Op)
+	}
+	assertNumber(t, div.Left, 4)
+	assertNumber(t, div.Right, 2)
+}
+
+// --- Error cases ---
+
+func TestParseEmptyInput(t *testing.T) {
+	toks := tokens(
+		tok(token.EOF, "", 0),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for empty input")
+	}
+}
+
+func TestParseMissingRParen(t *testing.T) {
+	// (1 + 2
+	toks := tokens(
+		tok(token.LParen, "(", 0),
+		tok(token.Number, "1", 1),
+		tok(token.Plus, "+", 3),
+		tok(token.Number, "2", 5),
+		tok(token.EOF, "", 6),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for missing right paren")
+	}
+}
+
+func TestParseUnexpectedRParen(t *testing.T) {
+	// ) 1
+	toks := tokens(
+		tok(token.RParen, ")", 0),
+		tok(token.Number, "1", 2),
+		tok(token.EOF, "", 3),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for unexpected right paren")
+	}
+}
+
+func TestParseTrailingOperator(t *testing.T) {
+	// 1 +
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Plus, "+", 2),
+		tok(token.EOF, "", 3),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for trailing operator")
+	}
+}
+
+func TestParseTrailingTokens(t *testing.T) {
+	// 1 2
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Number, "2", 2),
+		tok(token.EOF, "", 3),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for trailing tokens")
+	}
+}
+
+func TestParseConsecutiveOperators(t *testing.T) {
+	// 1 + * 2
+	toks := tokens(
+		tok(token.Number, "1", 0),
+		tok(token.Plus, "+", 2),
+		tok(token.Star, "*", 4),
+		tok(token.Number, "2", 6),
+		tok(token.EOF, "", 7),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for consecutive operators")
+	}
+}
+
+func TestParseEmptyParens(t *testing.T) {
+	// ()
+	toks := tokens(
+		tok(token.LParen, "(", 0),
+		tok(token.RParen, ")", 1),
+		tok(token.EOF, "", 2),
+	)
+	_, err := Parse(toks)
+	if err == nil {
+		t.Fatal("expected error for empty parentheses")
+	}
+}
+
+// --- Helper ---
+
+func assertNumber(t *testing.T, node ast.Node, expected float64) {
+	t.Helper()
+	num, ok := node.(*ast.NumberLit)
+	if !ok {
+		t.Fatalf("expected *ast.NumberLit, got %T", node)
+	}
+	if num.Value != expected {
+		t.Fatalf("expected %f, got %f", expected, num.Value)
+	}
+}
