From ef6302502b904e33dd4cc686d71142fb1a87bbbd Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Tue, 10 Sep 2019 13:18:25 -0400 Subject: [PATCH 1/2] Change to make atdgen work --- ocaml/ast.ml | 133 ++++++++++++++++++++++++++++++++++---------------- ocaml/ast.mli | 36 +++++++------- 2 files changed, 108 insertions(+), 61 deletions(-) diff --git a/ocaml/ast.ml b/ocaml/ast.ml index 9e62b02..ad7a0cc 100644 --- a/ocaml/ast.ml +++ b/ocaml/ast.ml @@ -1,51 +1,98 @@ type linno = int +(* type t = + * | Command of linno * assign list * args * redirection list (\* assign, args, redir *\) + * | Pipe of bool * t list (\* background?, commands *\) + * | Redir of linno * t * redirection list + * | Background of linno * t * redirection list + * | Subshell of linno * t * redirection list + * | And of t * t + * | Or of t * t + * | Not of t + * | Semi of t * t + * | If of t * t * t (\* cond, then, else *\) + * | While of t * t (\* test, body *\) (\* until encoded as a While . Not *\) + * | For of linno * arg * t * string (\* args, body, var *\) + * | Case of linno * arg * case list + * | Defun of linno * string * t (\* name, body *\) + * and assign = string * arg + * and redirection = + * | File of redir_type * int * arg + * | Dup of dup_type * int * arg + * | Heredoc of heredoc_type * int * arg + * and redir_type = To | Clobber | From | FromTo | Append + * and dup_type = ToFD | FromFD + * and heredoc_type = Here | XHere (\* for when in a quote... not sure when this comes up *\) + * and args = arg list + * and arg = arg_char list + * and arg_char = + * | C of char + * | E of char (\* escape... necessary for expansion *\) + * | T of string option (\* tilde *\) + * | A of arg (\* arith *\) + * | V of var_type * bool (\* VSNUL? *\) * string * arg + * | Q of arg (\* quoted *\) + * | B of t (\* backquote *\) + * and var_type = + * | Normal + * | Minus + * | Plus + * | Question + * | Assign + * | TrimR + * | TrimRMax + * | TrimL + * | TrimLMax + * | Length + * and case = { cpattern : arg list; cbody : t } *) + type t = - | Command of linno * assign list * args * redirection list (* assign, args, redir *) - | Pipe of bool * t list (* background?, commands *) - | Redir of linno * t * redirection list - | Background of linno * t * redirection list - | Subshell of linno * t * redirection list - | And of t * t - | Or of t * t + Command of (linno * assign list * args * redirection list) + | Pipe of (bool * t list) + | Redir of (linno * t * redirection list) + | Background of (linno * t * redirection list) + | Subshell of (linno * t * redirection list) + | And of (t * t) + | Or of (t * t) | Not of t - | Semi of t * t - | If of t * t * t (* cond, then, else *) - | While of t * t (* test, body *) (* until encoded as a While . Not *) - | For of linno * arg * t * string (* args, body, var *) - | Case of linno * arg * case list - | Defun of linno * string * t (* name, body *) - and assign = string * arg - and redirection = - | File of redir_type * int * arg - | Dup of dup_type * int * arg - | Heredoc of heredoc_type * int * arg - and redir_type = To | Clobber | From | FromTo | Append - and dup_type = ToFD | FromFD - and heredoc_type = Here | XHere (* for when in a quote... not sure when this comes up *) - and args = arg list - and arg = arg_char list - and arg_char = - | C of char - | E of char (* escape... necessary for expansion *) - | T of string option (* tilde *) - | A of arg (* arith *) - | V of var_type * bool (* VSNUL? *) * string * arg - | Q of arg (* quoted *) - | B of t (* backquote *) - and var_type = - | Normal - | Minus - | Plus - | Question - | Assign - | TrimR - | TrimRMax - | TrimL - | TrimLMax - | Length - and case = { cpattern : arg list; cbody : t } + | Semi of (t * t) + | If of (t * t * t) + | While of (t * t) + | For of (linno * arg * t * string) + | Case of (linno * arg * case list) + | Defun of (linno * string * t) +and assign = (string * arg) +and redirection = + File of (redir_type * int * arg) + | Dup of (dup_type * int * arg) + | Heredoc of (heredoc_type * int * arg) +and redir_type = To | Clobber | From | FromTo | Append +and dup_type = ToFD | FromFD +and heredoc_type = Here | XHere +and args = arg list +and arg = arg_char list +and arg_char = + C of char + | E of char + | T of string option + | A of arg + | V of (var_type * bool * string * arg) + | Q of arg + | B of t +and var_type = + Normal + | Minus + | Plus + | Question + | Assign + | TrimR + | TrimRMax + | TrimL + | TrimLMax + | Length +and case = { cpattern : arg list; cbody : t; } + let var_type = function | 0x0 -> (* VSNORMAL ${var} *) Normal | 0x2 -> (* VSMINUS ${var-text} *) Minus diff --git a/ocaml/ast.mli b/ocaml/ast.mli index bbb765b..f6977c1 100644 --- a/ocaml/ast.mli +++ b/ocaml/ast.mli @@ -1,25 +1,25 @@ type linno = int type t = - Command of linno * assign list * args * redirection list - | Pipe of bool * t list - | Redir of linno * t * redirection list - | Background of linno * t * redirection list - | Subshell of linno * t * redirection list - | And of t * t - | Or of t * t + Command of (linno * assign list * args * redirection list) + | Pipe of (bool * t list) + | Redir of (linno * t * redirection list) + | Background of (linno * t * redirection list) + | Subshell of (linno * t * redirection list) + | And of (t * t) + | Or of (t * t) | Not of t - | Semi of t * t - | If of t * t * t - | While of t * t - | For of linno * arg * t * string - | Case of linno * arg * case list - | Defun of linno * string * t -and assign = string * arg + | Semi of (t * t) + | If of (t * t * t) + | While of (t * t) + | For of (linno * arg * t * string) + | Case of (linno * arg * case list) + | Defun of (linno * string * t) +and assign = (string * arg) and redirection = - File of redir_type * int * arg - | Dup of dup_type * int * arg - | Heredoc of heredoc_type * int * arg + File of (redir_type * int * arg) + | Dup of (dup_type * int * arg) + | Heredoc of (heredoc_type * int * arg) and redir_type = To | Clobber | From | FromTo | Append and dup_type = ToFD | FromFD and heredoc_type = Here | XHere @@ -30,7 +30,7 @@ and arg_char = | E of char | T of string option | A of arg - | V of var_type * bool * string * arg + | V of (var_type * bool * string * arg) | Q of arg | B of t and var_type = From ac328aac56f0c48b00b30afca35b950eedd1f9bd Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Thu, 31 Dec 2020 10:40:59 -0800 Subject: [PATCH 2/2] better printing of compound commands --- ocaml/ast.ml | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/ocaml/ast.ml b/ocaml/ast.ml index ad7a0cc..d6810b5 100644 --- a/ocaml/ast.ml +++ b/ocaml/ast.ml @@ -377,14 +377,23 @@ let show_unless expected actual = else string_of_int actual let background s = "{ " ^ s ^ " & }" - + +let is_compound = function + | Command _ -> false + | _ -> true + +let is_bg = function + | Pipe (bg,_) -> bg + | Background _ -> true + | _ -> false + let rec to_string = function | Command (_,assigns,cmds,redirs) -> separated string_of_assign assigns ^ (if List.length assigns = 0 || List.length cmds = 0 then "" else " ") ^ separated string_of_arg cmds ^ string_of_redirs redirs | Pipe (bg,ps) -> - let p = intercalate " | " (List.map to_string ps) in + let p = intercalate " | " (List.map inner ps) in if bg then background p else p | Redir (_,a,redirs) -> to_string a ^ string_of_redirs redirs @@ -401,13 +410,13 @@ let rec to_string = function backgrounded?" so the braces resolve the issue. testing indicates that they're semantically equivalent. *) - background (to_string a ^ string_of_redirs redirs) + background (inner a ^ string_of_redirs redirs) | Subshell (_,a,redirs) -> parens (to_string a ^ string_of_redirs redirs) - | And (a1,a2) -> to_string a1 ^ " && " ^ to_string a2 - | Or (a1,a2) -> to_string a1 ^ " || " ^ to_string a2 - | Not a -> "! " ^ braces (to_string a) - | Semi (a1,a2) -> to_string a1 ^ " ; " ^ to_string a2 + | And (a1,a2) -> inner a1 ^ " && " ^ inner a2 + | Or (a1,a2) -> inner a1 ^ " || " ^ inner a2 + | Not a -> "! " ^ braces (inner a) + | Semi (a1,a2) -> inner a1 ^ " ; " ^ to_string a2 | If (c,t,e) -> string_of_if c t e | While (Not t,b) -> "until " ^ to_string t ^ "; do " ^ to_string b ^ "; done " @@ -420,6 +429,12 @@ let rec to_string = function "case " ^ string_of_arg a ^ " in " ^ separated string_of_case cs ^ " esac" | Defun (_,name,body) -> name ^ "() {\n" ^ to_string body ^ "\n}" + +and inner a = + let bg = is_bg a in + if is_compound a + then "{ " ^ to_string a ^ " " ^ (if bg then "&" else ";") ^ " }" + else to_string a ^ (if bg then " &" else "") and string_of_if c t e = "if " ^ to_string c ^