mirror of
https://github.com/LucasVbr/croissant.git
synced 2026-05-13 17:12:10 +00:00
feat: Support basic expression
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
(* lib/ast.ml *)
|
||||
|
||||
type binary_operator = Add | Substract | Multiply | Divide
|
||||
|
||||
type expression =
|
||||
| IntegerLiteral of int
|
||||
| BinaryExpression of binary_operator * expression * expression
|
||||
|
||||
type statement = ExpressionStatement of expression
|
||||
type source_file = SourceFile of statement list
|
||||
|
||||
(* Print AST *)
|
||||
|
||||
let string_of_binary_operator = function
|
||||
| Add -> "Add"
|
||||
| Substract -> "Substract"
|
||||
| Multiply -> "Multiply"
|
||||
| Divide -> "Divide"
|
||||
|
||||
let rec string_of_expression = function
|
||||
| IntegerLiteral i -> "IntegerLiteral(" ^ string_of_int i ^ ")"
|
||||
| BinaryExpression (op, e1, e2) ->
|
||||
"BinaryExpression("
|
||||
^ string_of_binary_operator op
|
||||
^ ", " ^ string_of_expression e1 ^ ", " ^ string_of_expression e2 ^ ")"
|
||||
|
||||
let string_of_statement = function
|
||||
| ExpressionStatement e ->
|
||||
"ExpressionStatement(" ^ string_of_expression e ^ ")"
|
||||
|
||||
let string_of_source_file = function
|
||||
| SourceFile stmts ->
|
||||
let stmt_strings = List.map string_of_statement stmts in
|
||||
"SourceFile([" ^ String.concat ", " stmt_strings ^ "])"
|
||||
@@ -1,2 +1,21 @@
|
||||
;lib/dune
|
||||
|
||||
(library
|
||||
(name croissant))
|
||||
(name lexer)
|
||||
(modules lexer)
|
||||
(libraries parser))
|
||||
|
||||
(library
|
||||
(name parser)
|
||||
(modules parser)
|
||||
(libraries ast))
|
||||
|
||||
(library
|
||||
(name ast)
|
||||
(modules ast))
|
||||
|
||||
(menhir
|
||||
(modules parser))
|
||||
|
||||
(ocamllex
|
||||
(modules lexer))
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
(* lib/lexer.mll *)
|
||||
{
|
||||
open Parser
|
||||
exception Error of char
|
||||
}
|
||||
|
||||
let line_comment = "//" [^ '\n']*
|
||||
|
||||
let digit = ['0'-'9']
|
||||
let integer = digit+
|
||||
|
||||
rule token = parse
|
||||
| [' ' '\t'] | line_comment { token lexbuf }
|
||||
| ['\n'] { Lexing.new_line lexbuf; token lexbuf }
|
||||
|
||||
| '+' { PLUS }
|
||||
| '-' { MINUS }
|
||||
| '*' { TIMES }
|
||||
| '/' { DIVIDE }
|
||||
| ';' { SEMICOLON }
|
||||
|
||||
| integer as lxm { INT(int_of_string lxm) }
|
||||
|
||||
| '(' { LPAREN }
|
||||
| ')' { RPAREN }
|
||||
|
||||
| eof { EOF }
|
||||
| _ as c { raise (Error c) }
|
||||
@@ -0,0 +1,51 @@
|
||||
/* lib/parser.mly */
|
||||
%{
|
||||
open Ast
|
||||
%}
|
||||
|
||||
%token <int> INT
|
||||
|
||||
%token PLUS "+"
|
||||
%token MINUS "-"
|
||||
%token TIMES "*"
|
||||
%token DIVIDE "/"
|
||||
|
||||
%token LPAREN "("
|
||||
%token RPAREN ")"
|
||||
|
||||
%token SEMICOLON ";"
|
||||
|
||||
%token EOF
|
||||
|
||||
%left "+" "-"
|
||||
%left "*" "/"
|
||||
//%nonassoc UMINUS
|
||||
|
||||
%start main
|
||||
%type <source_file> main
|
||||
|
||||
%%
|
||||
|
||||
main:
|
||||
| statements EOF { SourceFile($1) }
|
||||
|
||||
statements:
|
||||
| statement ";" { [$1] }
|
||||
| statement ";" statements { $1 :: $3 }
|
||||
|
||||
statement:
|
||||
| expression { ExpressionStatement($1) }
|
||||
|
||||
expression:
|
||||
| literal { $1 }
|
||||
| binary_expression { $1 }
|
||||
| "(" expression ")" { $2 }
|
||||
|
||||
literal:
|
||||
| INT { IntegerLiteral($1) }
|
||||
|
||||
binary_expression:
|
||||
| e1=expression PLUS e2=expression { BinaryExpression(Add, e1, e2) }
|
||||
| e1=expression MINUS e2=expression { BinaryExpression(Substract, e1, e2) }
|
||||
| e1=expression TIMES e2=expression { BinaryExpression(Multiply, e1, e2) }
|
||||
| e1=expression DIVIDE e2=expression { BinaryExpression(Divide, e1, e2) }
|
||||
Reference in New Issue
Block a user