mirror of
https://github.com/LucasVbr/croissant.git
synced 2026-05-16 09:06:17 +00:00
refactor: Syntax with unit tests
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
(library
|
||||
(name Analyzer)
|
||||
(modules lexer parser)
|
||||
(libraries Syntax))
|
||||
|
||||
(menhir
|
||||
(modules parser))
|
||||
|
||||
(ocamllex
|
||||
(modules lexer))
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
open Parser
|
||||
exception Error of char
|
||||
|
||||
let buffer = Buffer.create 256
|
||||
}
|
||||
|
||||
let white_space = [' ' '\t' '\n']
|
||||
|
||||
let letter = ['a'-'z' 'A'-'Z']
|
||||
let digit = ['0'-'9']
|
||||
let alphanum = letter | digit
|
||||
let non_digit = '_'
|
||||
|
||||
let identifier = letter (alphanum | non_digit)*
|
||||
let interger = digit+
|
||||
let float = digit+ '.' digit+
|
||||
|
||||
rule token = parse
|
||||
| white_space { token lexbuf }
|
||||
| '\n' { Lexing.new_line lexbuf; token lexbuf }
|
||||
|
||||
(* Comments *)
|
||||
| "//" { line_comment lexbuf }
|
||||
| "/*" { block_comment lexbuf }
|
||||
|
||||
(* Delimiters *)
|
||||
| '(' { LPAREN }
|
||||
| ')' { RPAREN }
|
||||
| ';' { SEMICOLON }
|
||||
|
||||
(* Operators *)
|
||||
| '+' { PLUS }
|
||||
| '-' { MINUS }
|
||||
| '*' { TIMES }
|
||||
| '/' { DIV }
|
||||
|
||||
(* Keywords *)
|
||||
(* ... *)
|
||||
|
||||
(* Literals *)
|
||||
| interger as i { INT (int_of_string i) }
|
||||
(* | float as f { FLOAT (float_of_string f) } *)
|
||||
|
||||
(* Identifiers *)
|
||||
(* ... *)
|
||||
|
||||
| eof { EOF }
|
||||
| _ as c { raise (Error c) }
|
||||
|
||||
and string = parse
|
||||
| '"' { token lexbuf }
|
||||
| '\\' { Buffer.add_char buffer '\\'; string lexbuf }
|
||||
| '\n' { Buffer.add_char buffer '\n'; string lexbuf }
|
||||
| eof { raise (Error '"') }
|
||||
| _ { Buffer.add_char buffer (Lexing.lexeme_char lexbuf 0); string lexbuf }
|
||||
|
||||
and line_comment = parse
|
||||
| '\n' { Lexing.new_line lexbuf; token lexbuf }
|
||||
| eof { EOF }
|
||||
| _ { line_comment lexbuf }
|
||||
|
||||
and block_comment = parse
|
||||
| "*/" { token lexbuf }
|
||||
| '\n' { Lexing.new_line lexbuf; block_comment lexbuf }
|
||||
| eof { EOF }
|
||||
| _ { block_comment lexbuf }
|
||||
@@ -0,0 +1,53 @@
|
||||
%{
|
||||
open Syntax
|
||||
%}
|
||||
|
||||
%token <int> INT
|
||||
%token PLUS "+"
|
||||
%token MINUS "-"
|
||||
%token TIMES "*"
|
||||
%token DIV "/"
|
||||
|
||||
%token SEMICOLON ";"
|
||||
|
||||
%token LPAREN "("
|
||||
%token RPAREN ")"
|
||||
|
||||
%token EOF
|
||||
|
||||
%left PLUS MINUS
|
||||
%left TIMES DIV
|
||||
|
||||
%nonassoc UMINUS
|
||||
|
||||
%start <SourceFiles.source_files> main
|
||||
|
||||
%%
|
||||
|
||||
main:
|
||||
| statements EOF { SourceFiles.SourceFile $1 }
|
||||
|
||||
statements:
|
||||
| statement ";" { $1 }
|
||||
| statement ";" statements { Statements.SequenceStatement ($1, $3) }
|
||||
|
||||
statement:
|
||||
| expression { Statements.ExpressionStatement($1) }
|
||||
|
||||
expression:
|
||||
| literal { Expressions.Literal($1) }
|
||||
| unary_expression { $1 }
|
||||
| binary_expression { $1 }
|
||||
| "(" expression ")" { $2 }
|
||||
|
||||
literal:
|
||||
| INT { Literals.Integer($1) }
|
||||
|
||||
unary_expression:
|
||||
| "-" expression %prec UMINUS { Expressions.UnaryExpression(UnaryOperators.ArithmeticNegation, $2) }
|
||||
|
||||
binary_expression:
|
||||
| expression "+" expression { Expressions.BinaryExpression (BinaryOperators.Add, $1, $3) }
|
||||
| expression "-" expression { Expressions.BinaryExpression (BinaryOperators.Subtract, $1, $3) }
|
||||
| expression "*" expression { Expressions.BinaryExpression (BinaryOperators.Multiply, $1, $3) }
|
||||
| expression "/" expression { Expressions.BinaryExpression (BinaryOperators.Divide, $1, $3) }
|
||||
@@ -0,0 +1 @@
|
||||
type environment = { variables : (string * _type) list }
|
||||
Reference in New Issue
Block a user