From 2ef40b4278dd51c4053731283dc8971dda821230 Mon Sep 17 00:00:00 2001 From: Eivind Jahren Date: Mon, 2 Dec 2024 12:32:24 +0100 Subject: [PATCH] Make it possible to have multiline statements in config --- docs/ert/reference/configuration/index.rst | 1 + docs/ert/reference/configuration/syntax.rst | 31 +++++++++++++++++++ src/ert/config/parsing/lark_parser.py | 5 ++- test-data/ert/flow_example/flow.ert | 6 +++- test-data/ert/snake_oil/snake_oil.ert | 26 +++++++++++++--- .../config/parsing/test_lark_parser.py | 24 +++++++++++++- 6 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 docs/ert/reference/configuration/syntax.rst diff --git a/docs/ert/reference/configuration/index.rst b/docs/ert/reference/configuration/index.rst index 5b8f4885476..de85f7332b6 100644 --- a/docs/ert/reference/configuration/index.rst +++ b/docs/ert/reference/configuration/index.rst @@ -19,6 +19,7 @@ This chapter sets out everything you need to know to configure ERT. .. toctree:: :maxdepth: 2 + syntax data_types forward_model observations diff --git a/docs/ert/reference/configuration/syntax.rst b/docs/ert/reference/configuration/syntax.rst new file mode 100644 index 00000000000..4e82400799b --- /dev/null +++ b/docs/ert/reference/configuration/syntax.rst @@ -0,0 +1,31 @@ +The ert configuration file format +================================= + +The ert config file, workflows, workflow job configuration files and forward +model configuration files all share the same syntax. These are lines starting +with one keyword followed by arguments separated by whitespace. e.g. + +:: + + QUEUE_SYSTEM LOCAL + NUM_REALIZATIONS 12 + -- A comment + FORWARD_MODEL DELETE_FILE(="file1 file-- file3") + + FORWARD_MODEL TEMPLATE_RENDER( \ + =parameters.json, \ + =/resources/SPE1.DATA.jinja2, \ + =SPE1.DATA \ + ) + +So for example :code:`QUEUE_SYSTEM` is a keyword and :code:`LOCAL` is an +argument. A comment is started with :code:`--`. :code:`FORWARD_MODEL` is a +special keyword that starts an installed forward model step (e.g. +:code:`DELETE_FILE`) with named forward model arguments inside parenthesis, +(e.g. :code:`` is set to :code:`file1 file-- file3`. Note that arguments +can be surrounded by quotes (:code:`"`) to make spaces and :code:`--` part of +the argument. + +As can be seen, you can have multi-line statements by escaping the newline with +:code:`\\` (like with bash). NB: the newline has to follow directly after +:code:`\\` without any spaces, tabs or other trailing whitespace. diff --git a/src/ert/config/parsing/lark_parser.py b/src/ert/config/parsing/lark_parser.py index 3e3811f2ff2..9dc15a4608a 100644 --- a/src/ert/config/parsing/lark_parser.py +++ b/src/ert/config/parsing/lark_parser.py @@ -15,13 +15,12 @@ from .types import Defines, FileContextToken, Instruction, MaybeWithContext grammar = r""" -WHITESPACE: (" "|"\t")+ -%ignore WHITESPACE - %import common.CNAME %import common.SIGNED_NUMBER -> NUMBER %import common.NEWLINE -> NEWLINE +WHITESPACE: (" "|"\t"|"\\"NEWLINE)+ +%ignore WHITESPACE _STRING_INNER: /.+?/ _STRING_ESC_INNER: _STRING_INNER /(?=parameters.json, =/resources/SPE1.DATA.jinja2, =SPE1.DATA) +FORWARD_MODEL TEMPLATE_RENDER( \ + =parameters.json, \ + =/resources/SPE1.DATA.jinja2, \ + =SPE1.DATA \ +) FORWARD_MODEL FLOW diff --git a/test-data/ert/snake_oil/snake_oil.ert b/test-data/ert/snake_oil/snake_oil.ert index dd2b13d842b..d871bf1ad62 100644 --- a/test-data/ert/snake_oil/snake_oil.ert +++ b/test-data/ert/snake_oil/snake_oil.ert @@ -30,8 +30,24 @@ FORWARD_MODEL SNAKE_OIL_NPV FORWARD_MODEL SNAKE_OIL_DIFF RUN_TEMPLATE templates/seed_template.txt seed.txt -GEN_KW SNAKE_OIL_PARAM templates/snake_oil_template.txt snake_oil_params.txt parameters/snake_oil_parameters.txt - -GEN_DATA SNAKE_OIL_OPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_opr_diff_%d.txt REPORT_STEPS:199 -GEN_DATA SNAKE_OIL_WPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_wpr_diff_%d.txt REPORT_STEPS:199 -GEN_DATA SNAKE_OIL_GPR_DIFF INPUT_FORMAT:ASCII RESULT_FILE:snake_oil_gpr_diff_%d.txt REPORT_STEPS:199 +GEN_KW \ + SNAKE_OIL_PARAM \ + templates/snake_oil_template.txt \ + snake_oil_params.txt \ + parameters/snake_oil_parameters.txt + +GEN_DATA \ + SNAKE_OIL_OPR_DIFF \ + INPUT_FORMAT:ASCII \ + RESULT_FILE:snake_oil_opr_diff_%d.txt \ + REPORT_STEPS:199 +GEN_DATA \ + SNAKE_OIL_WPR_DIFF \ + INPUT_FORMAT:ASCII \ + RESULT_FILE:snake_oil_wpr_diff_%d.txt \ + REPORT_STEPS:199 +GEN_DATA \ + SNAKE_OIL_GPR_DIFF \ + INPUT_FORMAT:ASCII \ + RESULT_FILE:snake_oil_gpr_diff_%d.txt \ + REPORT_STEPS:199 diff --git a/tests/ert/unit_tests/config/parsing/test_lark_parser.py b/tests/ert/unit_tests/config/parsing/test_lark_parser.py index 085b6ce179b..f97deafb488 100644 --- a/tests/ert/unit_tests/config/parsing/test_lark_parser.py +++ b/tests/ert/unit_tests/config/parsing/test_lark_parser.py @@ -68,6 +68,22 @@ def test_that_realisation_is_a_alias_of_realization(): assert config["NUM_REALIZATIONS"] == 1 +@pytest.mark.usefixtures("use_tmpdir") +def test_that_new_line_can_be_escaped(): + with open("config.ert", mode="w", encoding="utf-8") as fh: + fh.write( + dedent( + """ + NUM_REALIZATIONS \ + 1 + """ + ) + ) + + config = parse("config.ert", schema=init_user_config_schema()) + assert config["NUM_REALIZATIONS"] == 1 + + @pytest.mark.filterwarnings( "ignore:.*Using DEFINE with substitution strings that are not of the form ''.*:ert.config.ConfigWarning" ) @@ -79,7 +95,13 @@ def test_that_redefines_are_applied_correctly_as_forward_model_args(): NUM_REALIZATIONS 1 DEFINE 2 DEFINE 5 - FORWARD_MODEL MAKE_SYMLINK(=, =, =, R=Hello, =R) + FORWARD_MODEL MAKE_SYMLINK( \\ + =, \\ + =, \\ + =, \\ + R=Hello, \\ + =R \\ + ) DEFINE 10 DEFINE B DEFINE D