Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

7 Commits

Repository files navigation

Lexer, parser and interpreter for simple arithmetic expressions

The code is represented by examples of a lexer (based on the finite-state machine), parser (based on the shunting-yard algorithm) and interpreter (based on the interpreter design pattern). It can be used for educational purposes.

The grammar of supported arithmetic expressions (in the extended Backus–Naur form)

expression= [ whitespace ] , expression , [ whitespace ] |"(" , expression , ")"|expression , binop , expression|unop , expression|expression , "!"|function|number ;
binop="+"|"-"|"/"|"*"|"%"|"**"|"&&"|"||"|"^"|"&"|"|" ;
unop="+"|"-"|"!"|"~" ;
function=functionname , [ whitespace ] , "(" , functionarguments , ")" ;
functionname="log"|"ln"|"lg"|"exp"|"sqrt"|"sin"|"cos"|"rand" ;
functionarguments= [ expression ] , { "," , expression } ;
number= ( integer , [ "." ] , [ integer ] |"." , integer ) , [ ( "e"|"E" ) , [ ( "-"|"+" ) ] , integer ] ;
integer=digit , { digit } ;
digit="0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" ;
whitespace=? any non-empty sequence of white space charachters ? ;

The associativity and precedence of supported operations:

OperatorAssociativityPrecedence
! (factorial)left10
**right9
-(unary) +(unary) ~right8
!right7
* / %left6
- +left5
&left4
^left3
|left2
&&left1
||left0

The basic usage

$expression = '2 * (5 - 3) ** ((1 + -4) / (2 + 7))';
$iterator = newCharacterIterator($expression);
$lexer = newLexer($iterator);
$parser = newParser($lexer);
$ast = $parser->parse(); // $ast is an abstract syntax tree (AST) of an expression$value = $ast->evaluate(); // $value will contain 1.5874010519682

You can also try to evaluate different expressions using the script examples/try.php.

About

Lexer, parser and interpreter for simple arithmetic expressions.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages