Guest User

Untitled

a guest
Jul 20th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 6.30 KB | None | 0 0
  1. module Parser
  2.    
  3.     // Définition de type
  4.  
  5.     // Définition d'un jeu d'instruction
  6.     module Types =
  7.         type token =
  8.             | None
  9.             | Operator of int
  10.             | Memory of int
  11.             | IO of bool
  12.             | Loop of tokens
  13.             // Types optimisés
  14.             | ToZero
  15.             | ToZeroByLeft
  16.  
  17.         and tokens = list<token>
  18.  
  19.         type parsedTokens<'a> = 'a * tokens
  20.  
  21.         // Exceptions pour le parsing
  22.         exception LoopStagnation of string
  23.  
  24.     // Définition du parser
  25.     module Exec =
  26.         // Défini la valeur du constructeur prenant un entier en fonction d'un booléen
  27.         let calcul (x : bool) : int = if x then 1 else -1
  28.         // Analyse formelle et groupée du code
  29.         let parsing (code : string) : Types.tokens =
  30.             let rec parse (code : list<char>) (acc : Types.tokens) (lastOp : Types.token) : Types.parsedTokens<list<char>> =
  31.                 match code with
  32.                 | ('+'|'-') as operation :: tail ->
  33.                     let currOp = Types.Operator (calcul (operation = '+'))
  34.                     match (currOp, lastOp) with
  35.                     | (Types.Operator x, Types.Operator y) ->
  36.                         parse tail acc (Types.Operator (x + y))
  37.                     | (Types.Operator x, Types.None) ->
  38.                         parse tail acc (Types.Operator x)
  39.                     | _ -> parse tail (lastOp :: acc) currOp
  40.                 | ('>'|'<') as memory :: tail ->
  41.                     let currOp = Types.Memory (calcul (memory = '>'))
  42.                     match (currOp, lastOp) with
  43.                     | (Types.Memory x, Types.Memory y) ->
  44.                         parse tail acc (Types.Memory (x + y))
  45.                     | (Types.Operator x, Types.None) ->
  46.                         parse tail acc (Types.Memory x)
  47.                     | _ -> parse tail (lastOp :: acc) currOp
  48.                 | ('.'|',') as io :: tail ->
  49.                     match lastOp with
  50.                     | Types.None -> parse tail ((Types.IO (io = '.')) :: acc) Types.None
  51.                     | _ -> parse tail ((Types.IO (io = '.')) :: lastOp :: acc) Types.None
  52.                 | '[' :: tail ->
  53.                     let (returned, eval) = parse tail [] Types.None
  54.                     parse returned (Types.Loop eval :: lastOp :: acc) Types.None
  55.                 | ']' :: tail ->
  56.                     match lastOp with
  57.                     | Types.None -> (tail, List.rev acc)
  58.                     | _ -> (tail, List.rev (lastOp :: acc))
  59.                 | [] ->
  60.                     match lastOp with
  61.                     | Types.None -> ([], List.rev acc)
  62.                     | _ -> ([], List.rev (lastOp :: acc))
  63.                 | _ :: tail -> parse tail acc lastOp
  64.             let codeList = List.ofArray (code.ToCharArray())
  65.             let (nil, parsed) = parse codeList [] Types.None
  66.             parsed
  67.  
  68.         // Purge du code et des opérateurs/mémoires vides
  69.         let purge (code : Types.tokens) : Types.parsedTokens<bool> =
  70.             let rec purge code (acc : Types.tokens) (flag : bool) =
  71.                 match code with
  72.                 | (Types.Operator 0 | Types.Memory 0 | Types.None) :: tail -> purge tail acc true
  73.                 | (Types.Loop [] | Types.Loop [Types.Operator 0] | Types.Loop [Types.Memory 0]) :: tail ->
  74.                     raise (Types.LoopStagnation "Infinite Loop")
  75.                 | Types.Loop codeLoop :: tail ->
  76.                     let (flagLoop, eval) = purge codeLoop [] false
  77.                     purge tail (Types.Loop eval :: acc) (if flagLoop then true else flag)
  78.                 |  xs :: tail -> purge tail (xs :: acc) flag
  79.                 | [] -> (flag, List.rev acc)
  80.             purge code [] false
  81.  
  82.         // factorisation du code déjà parsé
  83.         let factorize (code : Types.tokens) : Types.tokens =
  84.             let rec factorize code (acc : Types.tokens) (lastOp : Types.token) =
  85.                 match (code, lastOp) with
  86.                 | (Types.Loop [Types.None] :: tail, _) -> raise (Types.LoopStagnation "Infinite Loop")
  87.                 | (Types.Loop [] :: tail, _) -> raise (Types.LoopStagnation "Infinite Loop")
  88.                 | (Types.Loop xs :: tail, Types.None) ->
  89.                     let eval = factorize xs [] Types.None
  90.                     factorize tail (Types.Loop eval :: acc) Types.None
  91.                 | (Types.IO flag :: tail, Types.None) -> factorize tail acc (Types.IO flag)
  92.                 | (Types.IO flag :: tail, (_ as currOp)) -> factorize tail (currOp :: acc) (Types.IO flag)
  93.                 | ((_ as currOp) :: tail, Types.None) -> factorize tail acc currOp
  94.                 | (Types.Operator x :: tail, Types.Operator y) -> factorize tail acc (Types.Operator (x+y))
  95.                 | (Types.Memory x :: tail, Types.Memory y) -> factorize tail acc (Types.Memory (x+y))
  96.                 | (op :: tail, last) -> factorize tail (last :: acc) op
  97.                 | ([], Types.None) -> List.rev acc
  98.                 | ([], (_ as currOp)) -> List.rev (currOp :: acc)
  99.             factorize code [] Types.None
  100.  
  101.         // Purification d'une séquence Brainfuck
  102.         let rec purify (code : Types.tokens) : Types.tokens =
  103.             let (flag, newCode) = purge code
  104.             if(flag) then purify (factorize newCode) else newCode
  105.  
  106.         // Optimisation d'une séquence
  107.         let optimize (code : Types.tokens) : Types.tokens =
  108.             let rec optimize code (acc : Types.tokens) =
  109.                 match code with
  110.                 | Types.Loop [Types.Operator xs] :: tail when xs = -1 ->
  111.                     optimize tail (Types.ToZero :: acc)
  112.                 | Types.Loop [Types.Memory(1); Types.Operator(1);Types.Memory(-1);Types.Operator(-1)] :: tail ->
  113.                     optimize tail (Types.ToZeroByLeft :: acc)
  114.                 | Types.Loop xs :: tail ->
  115.                     let eval = optimize xs []
  116.                     optimize tail (Types.Loop eval :: acc)
  117.                 | head :: tail -> optimize tail (head :: acc)
  118.                 | [] -> List.rev acc
  119.             optimize code []
  120.            
  121.         // Routine principale
  122.         let parse (code : string) : Types.tokens =
  123.             let parsedCode = parsing code
  124.             let pureCode = purify parsedCode
  125.             let optimization = optimize pureCode
  126.             optimization
Add Comment
Please, Sign In to add comment