#ifndef TYPES_H #define TYPES_H #include #include #include #include #include using namespace std; /** * Tokens definition */ enum class TokenType { Type, Identifier, Int, Plus, Minus, DoublePlus, DoubleMinus, DoubleEqual, Lt, Gt, Leq, Geq, NotEqual, Not, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese, LCurlyBracket, RCurlyBracket, If, Else }; enum class Type { Int }; using TokenData = variant; struct CodePosition { int line; int column; }; struct Token { TokenType type; TokenData data { }; CodePosition pos; }; /** Grammar: Prog -> Instruction Prog | Instruction Instruction -> Statement | ExprStatement; | Expr; | ; Statement -> | { Prog } | If (Expr) Instruction | If (Expr) Instruction Else Instruction ExprStatement -> | Type ParIdentifier = Expr // AssignedDeclaration | Type ParIdentifier // Declaration Expr -> Comp Comp -> | Sum | Sum == Comp | Sum != Comp | Sum < Comp | Sum > Comp | Sum <= Comp | Sum >= Comp Sum -> | Term | Term + Sum | Term - Sum Term -> | Unary | Unary * Term | Unary / Term | Unary % Term Unary -> | Val | - Unary | + Unary | ! Unary Val -> | Number | ++ParIdentifier | --ParIdentifier | ParIdentifier = Expr // Assignment | ParIdentifier++ | ParIdentifier-- | ParIdentifier // This makes the grammar ambiguous but simpler to parse | (Expr) ParIdentifier -> | Identifier | (ParIdentifier) */ /** * Type de Noeuds */ enum class NodeType { /* On ne créé pas de nouveau noeud -> ; Prog */ Prog, // -> Instruction Prog Epsilon, // -> ; AssignedDeclaration, // -> Type Identifier = Expr Declaration, // -> Type Identifier Plus, // -> T + Expr Minus, // -> T - Expr Mult, // -> F * T Div, // -> F / T Mod, // -> F % T UnaryMinus, // -> -F UnaryPlus, // -> +F Assignment, // -> Identifier = Expr LIncr, // -> ++ParIdentifier RIncr, // -> ParIdentifier++ LDecr, // -> --ParIdentifier RDecr, // -> ParIdentifier-- If, // -> If (Expr) Instruction IfElse, // -> If (Expr) Instruction Else Instruction Bloc // -> { Prog } }; struct InnerNode; /** * InnerNode: noeud interne * Token: feuille */ using Node = variant; /** * Noeud interne */ struct InnerNode { NodeType type; vector children; CodePosition pos; }; // A Leaf is always corresponding to a Token /** * Node: AST * tokens: tokens pas encore parsés */ struct ParseReturn { Node node; vector tokens; }; /** * Interpreter */ using EvalResult = variant; struct Scope { unordered_map vars; int depth; }; #endif