This repository contains an implementation of a Recursive Descent Parser (RDB)
for arithmetic expression language using C++17
, along with the construction of Abstract Syntax Trees (AST)
from parsed expressions. The grammar and syntax rules defined here serve as the foundation for parsing mathematical expressions.
![rdb](https://private-user-images.githubusercontent.com/80905157/280667625-b19edb19-c97e-4d5b-82f3-6389e59dc4d2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk5NDEwNzgsIm5iZiI6MTcxOTk0MDc3OCwicGF0aCI6Ii84MDkwNTE1Ny8yODA2Njc2MjUtYjE5ZWRiMTktYzk3ZS00ZDViLTgyZjMtNjM4OWU1OWRjNGQyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MDIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzAyVDE3MTkzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQ4MDY1YmU4NzBlNWZlYjc5ZGJiYzI2Y2Y5Y2FhYTFlNTZjZGZjMDVkNTJhMDA4ODllNjFmYzA2MTU3MmY0NzImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.HZ0s6ZQWRXJKt7uKr15WwW05dZ_PKkWJPaygp6wHGVE)
The grammar of the expression language is defined as follows:
<expression> ::= <term> | <term> "+" <expression> | <term> "-" <expression>
<term> ::= <factor> | <factor> "*" <term> | <factor> "/" <term> | <factor> "%" <term>
<factor> ::= <unary_expression> | <unary_expression> "^" <factor>
<unary_expression> ::= <primary> "!"
<primary> ::= "(" <expression> ")" | <number>
<number> ::= <sign>? <digit> #base case | <digit> <number> // recursive rule
<sign> ::= '+' | '-'
<digit> ::= 0 ... 9
The syntax rules determine the order and associations of the operators and operands:
- LPAR and RPAR: Define the rules for parentheses.
- ! (Factorial): Specifies the rules for the factorial operation.
- DIGIT: Describes the rules for numeric literals.
- Operators: (* / + - % ^) Outline the precedence and associativity of arithmetic operators.
* "(": LPAR
- left : BGN | - | + | * | / | % | DIGIT | ^ | ) | (
- right : DIGIT | (
* ")": RPAR
- left : ) | DIGIT | !
- right : ) | ( | ^ | - | + | * | / | % | ! | DIGIT | END
* "!":
- left : ) | DIGIT
- right : END | ^ | - | + | * | / | % | )
* "DIGIT":
- left : BGIN | ^ | - | + | * | / | % | ( | )
- right : END | ! | ( | ) | ^ | - | + | * | / | %
* "* / + - % ^":
- left : DIGIT | ) | !
- right : ( | DIGIT
The Recursive Descent Parser is implemented through the following functions:
ast* parser();
private:
ast* expression();
ast* term();
ast* factor();
ast* unary_expression();
ast* primary();
These functions handle the recursive descent parsing process, breaking down expressions into their constituent parts and building the corresponding Abstract Syntax Tree.
The AST can be evaluated using the eval
function:
void eval(ast* root);
To build and run the project, follow these steps:
- Compile the project using
make
. - Execute the generated
rdb_exec
executable. - Enter mathematical expressions to be parsed and evaluated.
The command-line interface includes the following features:
- Command interpretation for
"clear"
"reset"
"exit"
. - Integration with the
readline
library for command history.