The "concrete syntax" of a program, in our case of an expression, is the
syntax the programmer use while writing it. The "abstract syntax" is a
representation of what the concrete syntax means. An "abstract syntax tree"
(AST for short) is a tree representation of the abstract syntax. A syntax tree
representation as no more associativity and precedence problems.
So after parsing the string "1*(2+x)*(y-10)" we get the AST:
Ast.Times
(Ast.Times
(Ast.Int 1,
Ast.Plus
(Ast.Int 2,
Ast.Ident "x")),
Ast.Minus
(Ast.Ident "y",
Ast.Int 10))
that is:
*
/ \
/ \
* -
/ \ | \
1 + y 10
/ \
2 x
Having an AST and a mapping from variable names to variable values you can
easily compute the value of an expression with a recursive function.