Created
November 26, 2014 00:15
-
-
Save gnuvince/9254e2a1d9ad47b8f00f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Lexer *) | |
{ | |
open Parser | |
} | |
let alpha = ['a'-'z' 'A'-'Z' '_'] | |
let digit = ['0'-'9'] | |
let alnum = (alpha | digit) | |
let intlit = digit+ | |
let ident = alpha alnum* | |
rule next_token = parse | |
| intlit as x { T_int (int_of_string x) } | |
| ident as id { T_id id } | |
| '+' { T_plus } | |
| '(' { T_lparen } | |
| ')' { T_rparen } | |
| '[' { T_lbrack } | |
| ']' { T_rbrack } | |
| [' ' '\t' '\n']+ { next_token lexbuf } | |
| eof { T_eof } | |
(* Parser *) | |
%{ | |
open Ast | |
%} | |
%token <int> T_int | |
%token <string> T_id | |
%token T_plus | |
%token T_lparen | |
%token T_rparen | |
%token T_lbrack | |
%token T_rbrack | |
%token T_eof | |
%start <Ast.both> program | |
%left T_plus | |
%% | |
program: | |
| et=expr_or_type T_eof { et } | |
expr_or_type: | |
| e=expr { Expr e } | |
| ty=non_expr_type { Type ty } | |
expr: | |
| n=T_int { ExprInt n } | |
| id=T_id { ExprId id } | |
| e1=expr T_plus e2=expr { ExprAdd (e1, e2) } | |
| T_lparen e=expr T_rparen { e } | |
non_expr_type: | |
| T_lbrack T_rbrack ty=type_ { TypeSlice ty } | |
type_: | |
| id=T_id { TypeId id } | |
| T_lbrack T_rbrack ty=type_ { TypeSlice ty } | |
| T_lparen ty=type_ T_rparen { ty } | |
(* AST *) | |
open Printf | |
type expr = | |
| ExprInt of int | |
| ExprId of string | |
| ExprAdd of expr * expr | |
type typ = | |
| TypeId of string | |
| TypeSlice of typ | |
type both = | |
| Expr of expr | |
| Type of typ | |
let rec both_to_string = function | |
| Expr e -> sprintf "Expr(%s)" (expr_to_string e) | |
| Type t -> sprintf "Type(%s)" (type_to_string t) | |
and expr_to_string = function | |
| ExprInt n -> sprintf "ExprInt(%d)" n | |
| ExprId id -> sprintf "ExprId(%s)" id | |
| ExprAdd (e1, e2) -> sprintf "ExprAdd(%s, %s)" (expr_to_string e1) (expr_to_string e2) | |
and type_to_string = function | |
| TypeId id -> sprintf "TypeId(%s)" id | |
| TypeSlice t -> sprintf "TypeSlice(%s)" (type_to_string t) | |
(* main.ml *) | |
let () = | |
let lexbuf = Lexing.from_channel stdin in | |
let result = Parser.program Lexer.next_token lexbuf in | |
print_endline (Ast.both_to_string result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment