From ab4cb3ebd920c244251ffb6f012dea7a0bf2004c Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sun, 27 Dec 2020 11:03:49 -0500 Subject: [PATCH] emitx iterate --- go/parser-experiments/two/emit01.bnf | 103 +++++++++++++++++++++++++++ go/parser-experiments/two/emit02.bnf | 96 +++++++++++++++++++++++++ go/parser-experiments/two/temp.bnf | 62 +++------------- go/src/miller/cli/mlrcli_parse.go | 100 +++++++++++++------------- 4 files changed, 261 insertions(+), 100 deletions(-) create mode 100644 go/parser-experiments/two/emit01.bnf create mode 100644 go/parser-experiments/two/emit02.bnf diff --git a/go/parser-experiments/two/emit01.bnf b/go/parser-experiments/two/emit01.bnf new file mode 100644 index 000000000..138b4a530 --- /dev/null +++ b/go/parser-experiments/two/emit01.bnf @@ -0,0 +1,103 @@ +// ================================================================ +// LEXER + +!whitespace : ' ' | '\t' | '\n' | '\r' ; +!comment : '#' {.} '\n' ; + +_letter : 'a'-'z' | 'A'-'Z' ; +_decdig : '0'-'9' ; +_idchar : _letter | _decdig | '_' ; + +emit : 'e' 'm' 'i' 't' ; + +// ================================================================ +// IMPORT + +<< import "miller/dsl" >> + +// ================================================================ +// PARSER + +// ---------------------------------------------------------------- +Root + : EmitStatement + << dsl.NewAST($0) >> +; + +// ---------------------------------------------------------------- +// Examples: +// emit @a +// emit (@a, @b) +// emit @a, "x", "y" +// emit (@a, @b), "x", "y" +// First argument (single or in parentheses) must be non-indexed +// oosvar/localvar/fieldname, so we can use their names as keys in the emitted +// record. These restrictions are enforced in the CST logic, to keep this +// parser/AST logic simpler. +EmitStatement + : emit Rvalue + << dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeEmitStatement) >> + + | emit Rvalue "," EmitArgs + << dsl.NewASTNodeBinary($0, $1, $3, dsl.NodeTypeEmitStatement) >> + + | emit "(" EmitArgs ")" + << dsl.NewASTNodeUnary($0, $2, dsl.NodeTypeEmitStatement) >> + + | emit "(" EmitArgs ")" "," EmitArgs + << dsl.NewASTNodeBinary($0, $2, $5, dsl.NodeTypeEmitStatement) >> +; + +// ---------------------------------------------------------------- +EmitArgs + : Rvalue + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + | Rvalue "," EmitArgs + << dsl.PrependChild( + $2, + $0, + ) >> +; + +// ---------------------------------------------------------------- +FcnArgs + : Rvalue + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + // Allow trailing final comma, especially for multiline statements + | Rvalue "," + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + // Allow trailing final comma, especially for multiline statements + | Rvalue "," FcnArgs + << dsl.PrependChild( + $2, + $0, + ) >> +; + + +// ---------------------------------------------------------------- +Rvalue + : Literal + | "(" Literal ")" +; + +Literal + : "x" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> + | "y" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> + | "z" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> +; diff --git a/go/parser-experiments/two/emit02.bnf b/go/parser-experiments/two/emit02.bnf new file mode 100644 index 000000000..578761409 --- /dev/null +++ b/go/parser-experiments/two/emit02.bnf @@ -0,0 +1,96 @@ +// ================================================================ +// LEXER + +!whitespace : ' ' | '\t' | '\n' | '\r' ; +!comment : '#' {.} '\n' ; + +_letter : 'a'-'z' | 'A'-'Z' ; +_decdig : '0'-'9' ; +_idchar : _letter | _decdig | '_' ; + +emit : 'e' 'm' 'i' 't' ; + +// ================================================================ +// IMPORT + +<< import "miller/dsl" >> + +// ================================================================ +// PARSER + +// ---------------------------------------------------------------- +Root + : EmitStatement + << dsl.NewAST($0) >> +; + +// ---------------------------------------------------------------- +// Examples: +// emit @a +// emit (@a, @b) +// emit @a, "x", "y" +// emit (@a, @b), "x", "y" +// First argument (single or in parentheses) must be non-indexed +// oosvar/localvar/fieldname, so we can use their names as keys in the emitted +// record. These restrictions are enforced in the CST logic, to keep this +// parser/AST logic simpler. +EmitStatement + : emit EmitArgs + << dsl.NewASTNodeBinary($0, $1, $3, dsl.NodeTypeEmitStatement) >> +; + +// ---------------------------------------------------------------- +EmitArgs + : Rvalue + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + | Rvalue "," EmitArgs + << dsl.PrependChild( + $2, + $0, + ) >> +; + +// ---------------------------------------------------------------- +FcnArgs + : Rvalue + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + // Allow trailing final comma, especially for multiline statements + | Rvalue "," + << dsl.NewASTNodeUnary( + nil, + $0, + dsl.NodeTypeFunctionCallsite, + ) >> + + // Allow trailing final comma, especially for multiline statements + | Rvalue "," FcnArgs + << dsl.PrependChild( + $2, + $0, + ) >> +; + + +// ---------------------------------------------------------------- +Rvalue + : Literal + | "(" Literal ")" + | "[" Literal "]" + | "[" Literal "," Literal "]" +; + +Literal + : "x" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> + | "y" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> + | "z" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> +; diff --git a/go/parser-experiments/two/temp.bnf b/go/parser-experiments/two/temp.bnf index 2f8226794..578761409 100644 --- a/go/parser-experiments/two/temp.bnf +++ b/go/parser-experiments/two/temp.bnf @@ -8,9 +8,7 @@ _letter : 'a'-'z' | 'A'-'Z' ; _decdig : '0'-'9' ; _idchar : _letter | _decdig | '_' ; -emit : 'e' 'm' 'i' 't' ; -emitp : 'e' 'm' 'i' 't' 'p' ; -emitf : 'e' 'm' 'i' 't' 'f' ; +emit : 'e' 'm' 'i' 't' ; // ================================================================ // IMPORT @@ -24,10 +22,6 @@ emitf : 'e' 'm' 'i' 't' 'f' ; Root : EmitStatement << dsl.NewAST($0) >> - | EmitPStatement - << dsl.NewAST($0) >> - | EmitFStatement - << dsl.NewAST($0) >> ; // ---------------------------------------------------------------- @@ -41,52 +35,10 @@ Root // record. These restrictions are enforced in the CST logic, to keep this // parser/AST logic simpler. EmitStatement - : emit Rvalue - << dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeEmitStatement) >> - - | emit Rvalue "," EmitArgs + : emit EmitArgs << dsl.NewASTNodeBinary($0, $1, $3, dsl.NodeTypeEmitStatement) >> - - | emit "(" EmitArgs ")" - << dsl.NewASTNodeUnary($0, $2, dsl.NodeTypeEmitStatement) >> - - | emit "(" EmitArgs ")" "," EmitArgs - << dsl.NewASTNodeBinary($0, $2, $5, dsl.NodeTypeEmitStatement) >> ; -// Examples: syntactically identical to emit. -EmitPStatement - : emitp Rvalue - << dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeEmitPStatement) >> - - | emitp Rvalue "," EmitArgs - << dsl.NewASTNodeBinary($0, $1, $3, dsl.NodeTypeEmitPStatement) >> - - | emitp "(" EmitArgs ")" - << dsl.NewASTNodeUnary($0, $2, dsl.NodeTypeEmitPStatement) >> - - | emitp "(" EmitArgs ")" "," EmitArgs - << dsl.NewASTNodeBinary($0, $2, $5, dsl.NodeTypeEmitPStatement) >> -; - -// Examples: -// emitf @a -// emitf @a, b, $c -// Each argument must be a non-indexed oosvar/localvar/fieldname, so we can use -// their names as keys in the emitted record. These restrictions are enforced -// in the CST logic, to keep this parser/AST logic simpler. -EmitFStatement - : emitf EmitArgs - << dsl.AdoptChildren( - dsl.NewASTNodeNestable( - $0, - dsl.NodeTypeEmitFStatement, - ), - $1, - ) >> -; - - // ---------------------------------------------------------------- EmitArgs : Rvalue @@ -96,7 +48,6 @@ EmitArgs dsl.NodeTypeFunctionCallsite, ) >> - // Allow trailing final comma, especially for multiline statements | Rvalue "," EmitArgs << dsl.PrependChild( $2, @@ -132,7 +83,14 @@ FcnArgs // ---------------------------------------------------------------- Rvalue + : Literal + | "(" Literal ")" + | "[" Literal "]" + | "[" Literal "," Literal "]" +; + +Literal : "x" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> | "y" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> | "z" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >> - ; +; diff --git a/go/src/miller/cli/mlrcli_parse.go b/go/src/miller/cli/mlrcli_parse.go index 424b3ac90..04cefb440 100644 --- a/go/src/miller/cli/mlrcli_parse.go +++ b/go/src/miller/cli/mlrcli_parse.go @@ -336,56 +336,60 @@ func parseTerminalUsage(args []string, argc int, argi int) bool { func loadMlrrcOrDie( options *clitypes.TOptions, ) { - // TODO: finish porting -// char* env_mlrrc = getenv("MLRRC"); -// if (env_mlrrc != nil) { -// if env_mlrrc == "__none__" { -// return; -// } -// if (tryLoadMlrrc(popts, env_mlrrc)) { -// return; -// } -// } -// -// char* env_home = getenv("HOME"); -// if (env_home != nil) { -// char* path = mlr_paste_2_strings(env_home, "/.mlrrc"); -// (void)tryLoadMlrrc(popts, path); -// free(path); -// } -// -// (void)tryLoadMlrrc(popts, "./.mlrrc"); + env_mlrrc := os.Getenv("MLRRC") + + if env_mlrrc != "" { + if env_mlrrc == "__none__" { + return + } + if tryLoadMlrrc(options, env_mlrrc) { + return + } + } + + env_home := os.Getenv("HOME") + if env_home != "" { + path := env_home + "/.mlrrc" + tryLoadMlrrc(options, path) + } + + tryLoadMlrrc(options, "./.mlrrc") } -//static int tryLoadMlrrc(cli_opts_t* popts, char* path) { -// FILE* fp = fopen(path, "r"); -// if (fp == nil) { -// return false; -// } -// -// char* line = nil; -// size_t linecap = 0; -// int rc; -// int lineno = 0; -// -// while ((rc = getline(&line, &linecap, fp)) != -1) { -// lineno++; -// char* line_to_destroy = strdup(line); -// if (!handle_mlrrc_line_1(popts, line_to_destroy)) { -// fmt.Fprintf(os.Stderr, "Parse error at file \"%s\" line %d: %s\n", -// path, lineno, line); -// os.Exit(1); -// } -// free(line_to_destroy); -// } -// -// fclose(fp); -// if (line != nil) { -// free(line); -// } -// -// return true; -//} +func tryLoadMlrrc( + options *clitypes.TOptions, + path string, +) bool { + + // TODO: finish porting + // FILE* fp = fopen(path, "r"); + // if (fp == nil) { + return false + // } + // + // char* line = nil; + // size_t linecap = 0; + // int rc; + // int lineno = 0; + // + // while ((rc = getline(&line, &linecap, fp)) != -1) { + // lineno++; + // char* line_to_destroy = strdup(line); + // if (!handle_mlrrc_line_1(popts, line_to_destroy)) { + // fmt.Fprintf(os.Stderr, "Parse error at file \"%s\" line %d: %s\n", + // path, lineno, line); + // os.Exit(1); + // } + // free(line_to_destroy); + // } + // + // fclose(fp); + // if (line != nil) { + // free(line); + // } + // + // return true; +} // Chomps trailing CR, LF, or CR/LF; comment-strips; left-right trims.