]> gitweb.factorcode.org Git - factor.git/commitdiff
peg.ebnf: support escaped double quote in a string
authorJon Harper <jon.harper87@gmail.com>
Mon, 24 Aug 2015 21:41:02 +0000 (23:41 +0200)
committerJon Harper <jon.harper87@gmail.com>
Sun, 30 Aug 2015 16:43:58 +0000 (18:43 +0200)
basis/peg/ebnf/ebnf-docs.factor
basis/peg/ebnf/ebnf-tests.factor
basis/peg/ebnf/ebnf.factor

index 39b48e99abe72ce05d6c2199d9ed1de1fd0c67bc..506bb662553d27414508872e1ec2a83c74d481a2 100644 (file)
@@ -60,6 +60,9 @@ HELP: EBNF:
 
 ARTICLE: "peg.ebnf.strings" "Strings"
 "A string in a rule will match that sequence of characters from the input string. "
+"The string is delimited by matching single or double quotes. "
+"Factor's escape sequences are interpreted: " { $link "escape" } ". "
+"For double quotes delimiters, an escaped double quote doesn't terminate the string. "
 "The AST result from the match is the string itself."
 { $examples
     { $example
@@ -67,6 +70,21 @@ ARTICLE: "peg.ebnf.strings" "Strings"
        "\"helloworld\" [EBNF rule=\"hello\" \"world\" EBNF] ."
        "V{ \"hello\" \"world\" }"
     }
+    { $example
+       "USING: prettyprint peg.ebnf ;"
+       "\"AΣ𝄞\" [EBNF rule='\\x41' '\\u{greek-capital-letter-sigma}' '\\u01D11E' EBNF] ."
+       "V{ \"A\" \"Σ\" \"𝄞\" }"
+    }
+    { $example
+       "USING: io peg.ebnf ;"
+       "\"A double quote: \\\"\" [EBNF rule='A double quote: \"' EBNF] print"
+       "A double quote: \""
+    }
+    { $example
+       "USING: io peg.ebnf ;"
+       "\"' and \\\"\" [EBNF rule=\"' and \\\"\" EBNF] print"
+       "' and \""
+    }
 } ;
 
 ARTICLE: "peg.ebnf.any" "Any"
index 7187d9a9d11b2a4de30103bef21d5a621a0baf1c..3b1e6f12402dcf19597caae5a8902f7aaca4e2f0 100644 (file)
@@ -124,6 +124,18 @@ IN: peg.ebnf.tests
   "'foo'" identifier-parser parse
 ] unit-test
 
+{ "\"" } [
+  "\"\\\"\"" identifier-parser parse
+] unit-test
+
+{ "\\" } [
+  "\"\\\\\"" identifier-parser parse
+] unit-test
+
+{ "AΣ𝄞" } [
+  "'\\x41\\u{greek-capital-letter-sigma}\\u01D11E'" identifier-parser parse
+] unit-test
+
 { "foo" } [
   "foo" non-terminal-parser parse symbol>>
 ] unit-test
index 8f51743e34a8da2c2c65ad78f15d7e1d6ef8a4c7..d48e0649bab3363c9a70f72f768891dad106dcae 100644 (file)
@@ -3,7 +3,7 @@
 USING: accessors arrays assocs combinators
 combinators.short-circuit effects io.streams.string kernel make
 math.parser multiline namespaces parser peg peg.parsers
-peg.search quotations sequences splitting stack-checker strings
+peg.search quotations sequences sequences.deep splitting stack-checker strings
 strings.parser summary unicode.categories words ;
 FROM: vocabs.parser => search ;
 FROM: peg.search => replace ;
@@ -120,9 +120,13 @@ C: <ebnf> ebnf
     #! or double quotes. The AST produced is the identifier
     #! between the quotes.
     [
-        [ CHAR: " = not ] satisfy repeat1 "\"" "\"" surrounded-by ,
+        [
+            [ CHAR: \ = ] satisfy
+            [ [ CHAR: " = ] [ CHAR: \ = ] bi or ] satisfy 2seq ,
+            [ CHAR: " = not ] satisfy ,
+        ] choice* repeat1 "\"" "\"" surrounded-by ,
         [ CHAR: ' = not ] satisfy repeat1 "'" "'" surrounded-by ,
-    ] choice* [ >string unescape-string ] action ;
+    ] choice* [ flatten >string unescape-string ] action ;
 
 : non-terminal-parser ( -- parser )
     #! A non-terminal is the name of another rule. It can