diff options
-rw-r--r-- | menhir-manual.pdf | bin | 0 -> 348762 bytes | |||
-rw-r--r-- | parser.mli | 53 | ||||
-rw-r--r-- | src/_tags | 3 | ||||
-rw-r--r-- | src/ast.mli | 29 | ||||
-rw-r--r-- | src/lexer.mll (renamed from lexer.mll) | 6 | ||||
-rw-r--r-- | src/main.ml (renamed from main.ml) | 0 | ||||
-rw-r--r-- | src/parser.mly | 191 | ||||
-rw-r--r-- | src/pretty.ml (renamed from pretty.ml) | 0 |
8 files changed, 228 insertions, 54 deletions
diff --git a/menhir-manual.pdf b/menhir-manual.pdf Binary files differnew file mode 100644 index 0000000..8782905 --- /dev/null +++ b/menhir-manual.pdf diff --git a/parser.mli b/parser.mli deleted file mode 100644 index 8309e8a..0000000 --- a/parser.mli +++ /dev/null @@ -1,53 +0,0 @@ - -type token = - (* KEYWORDZ *) - | CLASS - | ELSE - | FALSE - | FOR - | IF - | INT - | NEW - | NULL - | PUBLIC - | RETURN - | THIS - | TRUE - | VIRTUAL - | VOID - | WHILE - (* IDENTZ *) - | IDENT of string - (* OPERATORZ, by precedence *) - | ASSIGN - | LOR - | LAND - | EQ - | NE - | LT - | LE - | GT - | GE - | PLUS - | MINUS - | TIMES - | DIV - | MOD - | NOT - | INCR - | DECR - | REF - (* and also : unary dereference, plus, minus *) - | LPAREN - | RPAREN - | RARROW - | DOT - (* OTHER SYMBOLZ *) - | SEMICOLON - | DOUBLECOLON - | LFLOW - | LBRACE - | RBRACE - (* DATAZ *) - | INTVAL of int - | STRVAL of string diff --git a/src/_tags b/src/_tags new file mode 100644 index 0000000..fe4a756 --- /dev/null +++ b/src/_tags @@ -0,0 +1,3 @@ +true: use_menhir +<*.ml>: debug +<*.byte>: use_unix, debug diff --git a/src/ast.mli b/src/ast.mli new file mode 100644 index 0000000..557b3f6 --- /dev/null +++ b/src/ast.mli @@ -0,0 +1,29 @@ + +(* Syntaxe abstraite pour mini-C++ *) + +(* rien à voir pour l'instant *) + +type ident = string + +type binop = + | Equal | NotEqual + | Lt | Le | Gt | Ge + | Add | Sub | Mul | Div | Modulo + | Land | Lor + +type unop = + | PreIncr | PostIncr | PreDecr | PostDecr + | Ref | Deref + | Not + | Minus | Plus + +type expr = + | EBinop of expr * binop * expr + | EUnary of unop * expr + | EAssign of expr * expr + | EIntConst of int + | EBoolConst of bool + | EThis + | ENull + | EMem of expr * ident + diff --git a/lexer.mll b/src/lexer.mll index 1a643eb..f2f47ef 100644 --- a/lexer.mll +++ b/src/lexer.mll @@ -32,7 +32,10 @@ let h = Hashtbl.create 20 in List.iter (fun (s, t) -> Hashtbl.add h s t) keywordz_l; fun s -> - try Hashtbl.find h s with _ -> IDENT s + try Hashtbl.find h s with _ -> + if Sset.mem (!type_names) s + then TIDENT s + else IDENT s } let digit = ['0'-'9'] @@ -46,6 +49,7 @@ rule token = parse | ident as id { id_or_kwd id } | "//" { short_comment lexbuf; token lexbuf } | "/*" { long_comment lexbuf; token lexbuf } + | "#include <iostream>" { INCLUDE_IOSTREAM } | "0x" (hexa+ as n) { INTVAL(int_of_string("0x" ^ n)) } | ['1'-'9'] digit* as n { INTVAL(int_of_string(n)) } | '0' (octal+ as n) { INTVAL(int_of_string("0o" ^ n)) } diff --git a/src/parser.mly b/src/parser.mly new file mode 100644 index 0000000..98bebaf --- /dev/null +++ b/src/parser.mly @@ -0,0 +1,191 @@ + +%{ + open Ast + + module Sset = Set.Make(String) + + let type_names = ref Sset.empty +%} + +%token <int> INTVAL +%token <string> STRVAL +%token <string> IDENT +%token <string> TIDENT + +/* this is stupid */ +%token INCLUDE_IOSTREAM + +/* keywords */ +%token CLASS ELSE FALSE FOR IF INT NEW NULL PUBLIC RETURN +%token THIS TRUE VIRTUAL VOID WHILE + +/* operators */ +%token ASSIGN LOR LAND EQ NE LT LE GT GE PLUS MINUS +%token TIMES DIV MOD NOT INCR DECR REF +%token LPAREN RPAREN RARROW DOT + +/* other symbols */ +%token SEMICLON COLON DOUBLECOLON LFLOW LBRACE RBRACE + + +/* operator priority */ +%right ASSIGN +%left LOR +%left LAND +%left EQ NE +%left LT LE GT GE +%left PLUS MINUS +%left TIMES DIV MOD +/* opérateurs unaires associatifs à droite */ +%left RARROW DOT LPAREN + +%start prog + +%type <unit> prog + +%% + +prog: + INCLUDE_IOSTREAM? + decls = declaration* + EOF + { () } +; + +declaration: +| d = decl_var + { d } +| d = decl_class + { d } +| p = proto + b = block + { () } +; + +decl_vars: +| t = ty + vars = separated_nonempty_list(COMMA, var) + SEMICOLON +; + +decl_class: +| CLASS i = IDENT + s = supers? + LBRACE + PUBLIC COLON + m = members* + RBRACE SEMICOLON + { () } +; + +supers: +| COLON + s = separated_nonempty_list(COMMA, super_id) + { s } +; + +super_id: +| PUBLIC i = TIDENT + { i } +; + +member: +| d = decl_vars + { () } +| v = VIRTUAL? + p = proto + { () } +; + +proto: +| t = ty + qv = qvar + LPAREN args = separated_list(COMMA, argument) RPAREN + { () } +| qi = TIDENT + LPAREN args = separated_list(COMMA, arg) RPAREN + { () } +| qa = TIDENT DOUBLECOLON + qb = TIDENT + LPAREN args = separated_list(COMMA, arg) RPAREN + { () } +; + +argument: +| t = ty + v = var + { () } +; + +var: +| i = IDENT + { () } +| TIMES v = var + { () } +| REF v = var + { () } +; + +qvar: +| qi = qident + { qi } +| TIMES v = qvar + { () } +| REF v = qvar + { () } +; + +qident: +| i = IDENT + { () } +| i = IDENT DOUBLECOLON j = IDENT + { () } +; + +expression: +| i = INTVAL { EIntConst(i) } +| THIS { EThis } +| FALSE { EBoolConst(false) } +| TRUE { EBoolConst(true) } +| NULL { ENull } +| q = qident { () } +| TIMES expression { EUnary(Deref, e) } +| e1 = expression DOT e2 = IDENT { () } +| e1 = expression RARROW e2 = IDENT { () } +| e1 = expression ASSIGN e2 = expression { () } +| f = expression LPAREN + a = separated_list(COLON, expression) + { () } +| NEW c = IDENT LPAREN + a = separated_list(COLON, expression) + { () } +| INCR e = expression { EUnary(PreIncr, e) } +| DECR e = expression { EUnary(PreDecr, e) } +| e = expression INCR { EUnary(PostIncr, e) } +| e = expression DECR { EUnary(PostDecr, e) } +| REF e = expression { EUnary(Ref, e) } +| NOT e = expression { EUnary(Not, e) } +| MINUS e = expression { EUnary(Minus, e) } +| PLUS e = expression { EUnary(Plus, e) } +| e1 = expression + o = operator + e2 = expression + { EBinop(e1, o, e2) } +| LPAREN e = expression RPAREN { e } +; + +operator: +| EQ { Equal } +| NEQ { NotEqual } +| LT { Lt } +| LE { Le } +| GT { Gt } +| GE { Ge } +| PLUS { Add } +| MINUS { Sub } +| TIMES { Mul } +| DIV { Div } +| MOD { Modulo } +| LAND { Land } +| LOR { Lor } +; diff --git a/pretty.ml b/src/pretty.ml index 87cc383..87cc383 100644 --- a/pretty.ml +++ b/src/pretty.ml |