Skip to content

Instantly share code, notes, and snippets.

@gnuvince
Created November 26, 2014 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnuvince/9254e2a1d9ad47b8f00f to your computer and use it in GitHub Desktop.
Save gnuvince/9254e2a1d9ad47b8f00f to your computer and use it in GitHub Desktop.
(* 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