From f5435c32f62fb629168c7f88e7a93c3af4f485c5 Mon Sep 17 00:00:00 2001 From: Arieh Schneier <15041913+AriehSchneier@users.noreply.github.com> Date: Tue, 4 Jun 2024 10:15:20 +1000 Subject: [PATCH] Support proto files with adjacent string literals (#922) --- .../bundles/assets/import_proto_cli.arraiz | Bin 38469 -> 38595 bytes pkg/importer/proto/proto_parser.arrai | 19 +++++++++++++++--- pkg/importer/proto/proto_parser_test.arrai | 7 ++++--- pkg/importer/proto/tests/proto2.proto | 2 ++ pkg/importer/proto/tests/proto2.sysl | 2 +- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/internal/bundles/assets/import_proto_cli.arraiz b/internal/bundles/assets/import_proto_cli.arraiz index b73b9d6221a5502977e7e04edcf550a84ba51fda..faf942bd21822ac91193d9bcb26e161126f43718 100644 GIT binary patch delta 4436 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 delta 4320 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 OlaH1z2I-Fg0002BZ%C~G diff --git a/pkg/importer/proto/proto_parser.arrai b/pkg/importer/proto/proto_parser.arrai index 4c2d17ea..8c9aba93 100644 --- a/pkg/importer/proto/proto_parser.arrai +++ b/pkg/importer/proto/proto_parser.arrai @@ -86,7 +86,7 @@ floatLit -> /{\d+(?:\.\d+?)? (?:e[-+]?\d+)? | \. \d+ (?:e[-+]?\d+)? | inf boolLit -> /{true | false}; -strLit -> ('"' [^"]*:'""' '"' | "'" [^']*:"''" "'"); //'; +strLit -> ('"' s=([^"]*:'""') '"' | "'" s=([^']*:"''") "'"):\s; //'; object -> "{" (c* objectField comma? c*)* "}"; objectField -> objectKey ":"? objectValue; @@ -133,9 +133,22 @@ let evalType = \currentPackage \parsed let evalLabel = \parsed parsed.'' rank (:.@) ; +let concatStrLit = \strLit + //seq.concat(//seq.concat( + (strLit.s >> .'') => \i ( + @:i.@, + @item: i.@item >> \v + let s=(v rank (:.@)); + cond strLit.@choice(i.@) { + 0: cond s {'""':'"', _:s}, + 1: cond s {"''":"'", _:s}, + } + ) + )); + let rec evalConstant = \parsed cond parsed { - (:strLit, ...): (s: //re.compile(`\\\\`).sub(`\`, strLit.''(1) rank (:.@))), + (:strLit, ...): (s: //re.compile(`\\\\`).sub(`\`, concatStrLit(strLit))), (:intLit, ...): evalConstant(intLit), (:decimalLit, ...): (d: //eval.value(decimalLit.'' rank (:.@))), (:octalLit, ...): (o: //eval.value(octalLit.'' rank (:.@))), @@ -248,7 +261,7 @@ let evalExtend = \currentPackage \parsed let evalStmt = \(?:currentPackage:'', ...) \parsed cond parsed { (:import, ...): - (import: {import.strLit.''(1) rank (:.@): () +> (cond import.modifier?:{} {('':mod, ...): (modifier: mod rank (:.@))} || ())}), + (import: {concatStrLit(import.strLit): () +> (cond import.modifier?:{} {('':mod, ...): (modifier: mod rank (:.@))} || ())}), (:package, ...): (package: {evalFullIdent(package.fullIdent): () +> evalComments(package)}), (:option, ...): ( diff --git a/pkg/importer/proto/proto_parser_test.arrai b/pkg/importer/proto/proto_parser_test.arrai index 386d2917..e81f3384 100644 --- a/pkg/importer/proto/proto_parser_test.arrai +++ b/pkg/importer/proto/proto_parser_test.arrai @@ -3,7 +3,7 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser}; ( constant: ( string: - let constant = (strLit: ('': [153\'"', 154\'test', 231\'"'])); + let constant = (strLit: ('': [153\'"', 231\'"'], @choice: [0], s: [('': [154\'test'])])); let expected = (s: "test"); let actual = evalConstant(constant); //test.assert.equal(expected, actual), @@ -23,12 +23,12 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser}; let actual = evalConstant(constant); //test.assert.equal(expected, actual), object: - let constant = (object: (objectField: [('': 1390\':', objectKey: (constant: (fullIdent: (ident: [('': [1387\'g', 1388\'et'])]))), objectValue: (constant: (strLit: ('': [1392\'"', 1393\'/api/accounts', 1415\'"']))))])); + let constant = (object: (objectField: [('': 1390\':', objectKey: (constant: (fullIdent: (ident: [('': [1387\'g', 1388\'et'])]))), objectValue: (constant: (strLit: ('': [1392\'"', 1415\'"'], @choice: [0], s: [('': [1393\'/api/accounts'])]))))])); let expected = (fields: {"get": (s: "/api/accounts")}); let actual = evalConstant(constant); //test.assert.equal(expected, actual), array: - let constant = (array: ('': [1497\'[', 1543\']'], arrayItem: [(constant: (strLit: ('': [1498\'"', 1499\'string', 1542\'"']))), (constant: (intLit: (decimalLit: ('': 235\'2'))))])); + let constant = (array: ('': [1497\'[', 1543\']'], arrayItem: [(constant: (strLit: ('': [1498\'"', 1542\'"'], @choice: [0], s: [('': [1499\'string'])]))), (constant: (intLit: (decimalLit: ('': 235\'2'))))])); let expected = [(s: "string"), (d: 2)]; let actual = evalConstant(constant); //test.assert.equal(expected, actual), @@ -251,6 +251,7 @@ let (:evalConstant, :parseFile, ...) = //{./proto_parser}; options: { '(my_option).a': (b: true), '(object_option).a': (fields: {'array': [(d: 1), (s: 'string'), (fields: {'foo': (s: 'bar')})], 'object': (fields: {'foo': (s: 'bar')})}), + 'adjacentString': (s: "firstsec'ondthi\"rdfourthfif't\"h"), }, ), }, diff --git a/pkg/importer/proto/tests/proto2.proto b/pkg/importer/proto/tests/proto2.proto index 966c50cb..51b03056 100644 --- a/pkg/importer/proto/tests/proto2.proto +++ b/pkg/importer/proto/tests/proto2.proto @@ -21,6 +21,8 @@ message Outer { array: [1, "string", {foo: "bar"}], object: {foo: "bar"} }; + option adjacentString = "first" "sec'ond" + "thi""rd" 'fourth' 'fif''t"h'; required int64 ival = 1; diff --git a/pkg/importer/proto/tests/proto2.sysl b/pkg/importer/proto/tests/proto2.sysl index 544e1fc2..d0966c55 100644 --- a/pkg/importer/proto/tests/proto2.sysl +++ b/pkg/importer/proto/tests/proto2.sysl @@ -35,7 +35,7 @@ proto2: !type Outer: @description =: | Level 1 - @proto_options = ["(my_option).a = true", "(object_option).a = {\"array: [1, 'string', {'foo: bar'}]\", \"object: {'foo: bar'}\"}"] + @proto_options = ["(my_option).a = true", "(object_option).a = {\"array: [1, 'string', {'foo: bar'}]\", \"object: {'foo: bar'}\"}", "adjacentString = firstsec'ondthi\"rdfourthfif't\"h"] @source_path = "proto/tests/proto2.proto" enum_field <: EnumAllowingAlias?: @json_tag = "enumField"