diff --git a/README.md b/README.md index c788e3e9..8da7f4d3 100644 --- a/README.md +++ b/README.md @@ -518,6 +518,17 @@ The modules that ship with Scryer Prolog are also called * [`csv`](src/lib/csv.pl) `parse_csv//1` and `parse_csv//2` can be used with [`phrase_from_file/2`](src/lib/pio.pl) or [`phrase/2`](src/lib/dcgs.pl) to parse csv +* [`serialization/abnf`](src/lib/serialization/abnf.pl) + DCGs describing the + [ABNF grammar core (RFC 5234)](https://tools.ietf.org/html/rfc5234#appendix-B.1), + which is used to describe many [IETF](https://www.ietf.org/standards/rfcs/) + syntaxes, such as [HTTP v1.1](https://www.rfc-editor.org/rfc/rfc7230.html#page-82), + [SMTP](https://www.rfc-editor.org/rfc/rfc5321.html), + [iCalendar](https://www.rfc-editor.org/rfc/rfc5545.html), and more. +* [`serialization/json`](src/lib/serialization/json.pl) + `json_chars//1` can be used with [`phrase_from_file/2`](src/lib/pio.pl) + or [`phrase/2`](src/lib/dcgs.pl) to parse and generate + [JSON](https://www.json.org/json-en.html). * [`xpath`](src/lib/xpath.pl) The predicate `xpath/3` is used for convenient reasoning about HTML and XML documents, inspired by the XPath language. This library @@ -539,8 +550,6 @@ The modules that ship with Scryer Prolog are also called ECDH key exchange over Curve25519 (X25519), authenticated symmetric encryption with ChaCha20-Poly1305, and reasoning about elliptic curves. * [`uuid`](src/lib/uuid.pl) UUIDv4 generation and hex representation -* [`json`](src/lib/json.pl) [JSON](https://www.json.org/json-en.html) - parsing and generation (beta version, subject to interface changes). To use predicates provided by the `lists` library, write: diff --git a/crates/prolog_parser/src/macros.rs b/crates/prolog_parser/src/macros.rs index c05ed69b..f8ec9072 100644 --- a/crates/prolog_parser/src/macros.rs +++ b/crates/prolog_parser/src/macros.rs @@ -4,131 +4,6 @@ macro_rules! char_class { ($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || $crate::char_class!($c, [$($cs),*])); } -#[macro_export] -macro_rules! symbolic_control_char { - ($c: expr) => { - $crate::char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0']) - }; -} - -#[macro_export] -macro_rules! space_char { - ($c: expr) => { - $c == ' ' - }; -} - -#[macro_export] -macro_rules! layout_char { - ($c: expr) => { - $crate::char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}']) - }; -} - -#[macro_export] -macro_rules! symbolic_hexadecimal_char { - ($c: expr) => { - $c == 'x' - }; -} - -#[macro_export] -macro_rules! octal_digit_char { - ($c: expr) => { - ('0'..='7').contains(&$c) - }; -} - -#[macro_export] -macro_rules! binary_digit_char { - ($c: expr) => { - $c >= '0' && $c <= '1' - }; -} - -#[macro_export] -macro_rules! hexadecimal_digit_char { - ($c: expr) => { - ('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c) - }; -} - -#[macro_export] -macro_rules! exponent_char { - ($c: expr) => { - $c == 'e' || $c == 'E' - }; -} - -#[macro_export] -macro_rules! sign_char { - ($c: expr) => { - $c == '-' || $c == '+' - }; -} - -#[macro_export] -macro_rules! new_line_char { - ($c: expr) => { - $c == '\n' - }; -} - -#[macro_export] -macro_rules! end_line_comment_char { - ($c: expr) => { - $c == '%' - }; -} - -#[macro_export] -macro_rules! comment_1_char { - ($c: expr) => { - $c == '/' - }; -} - -#[macro_export] -macro_rules! comment_2_char { - ($c: expr) => { - $c == '*' - }; -} - -#[macro_export] -macro_rules! capital_letter_char { - ($c: expr) => { - ('A'..='Z').contains(&$c) - }; -} - -#[macro_export] -macro_rules! small_letter_char { - ($c: expr) => { - ('a'..='z').contains(&$c) - }; -} - -#[macro_export] -macro_rules! variable_indicator_char { - ($c: expr) => { - $c == '_' - }; -} - -#[macro_export] -macro_rules! graphic_char { - ($c: expr) => ($crate::char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':', - '<', '=', '>', '?', '@', '^', '~'])) -} - -#[macro_export] -macro_rules! graphic_token_char { - ($c: expr) => { - $crate::graphic_char!($c) || $crate::backslash_char!($c) - }; -} - #[macro_export] macro_rules! alpha_char { ($c: expr) => { @@ -157,6 +32,62 @@ macro_rules! alpha_char { }; } +#[macro_export] +macro_rules! alpha_numeric_char { + ($c: expr) => { + $crate::alpha_char!($c) || $crate::decimal_digit_char!($c) + }; +} + +#[macro_export] +macro_rules! backslash_char { + ($c: expr) => { + $c == '\\' + }; +} + +#[macro_export] +macro_rules! back_quote_char { + ($c: expr) => { + $c == '`' + }; +} + +#[macro_export] +macro_rules! binary_digit_char { + ($c: expr) => { + $c >= '0' && $c <= '1' + }; +} + +#[macro_export] +macro_rules! capital_letter_char { + ($c: expr) => { + ('A'..='Z').contains(&$c) + }; +} + +#[macro_export] +macro_rules! comment_1_char { + ($c: expr) => { + $c == '/' + }; +} + +#[macro_export] +macro_rules! comment_2_char { + ($c: expr) => { + $c == '*' + }; +} + +#[macro_export] +macro_rules! cut_char { + ($c: expr) => { + $c == '!' + }; +} + #[macro_export] macro_rules! decimal_digit_char { ($c: expr) => { @@ -171,41 +102,6 @@ macro_rules! decimal_point_char { }; } -#[macro_export] -macro_rules! alpha_numeric_char { - ($c: expr) => { - $crate::alpha_char!($c) || $crate::decimal_digit_char!($c) - }; -} - -#[macro_export] -macro_rules! cut_char { - ($c: expr) => { - $c == '!' - }; -} - -#[macro_export] -macro_rules! semicolon_char { - ($c: expr) => { - $c == ';' - }; -} - -#[macro_export] -macro_rules! backslash_char { - ($c: expr) => { - $c == '\\' - }; -} - -#[macro_export] -macro_rules! single_quote_char { - ($c: expr) => { - $c == '\'' - }; -} - #[macro_export] macro_rules! double_quote_char { ($c: expr) => { @@ -214,9 +110,43 @@ macro_rules! double_quote_char { } #[macro_export] -macro_rules! back_quote_char { +macro_rules! end_line_comment_char { ($c: expr) => { - $c == '`' + $c == '%' + }; +} + +#[macro_export] +macro_rules! exponent_char { + ($c: expr) => { + $c == 'e' || $c == 'E' + }; +} + +#[macro_export] +macro_rules! graphic_char { + ($c: expr) => ($crate::char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':', + '<', '=', '>', '?', '@', '^', '~'])) +} + +#[macro_export] +macro_rules! graphic_token_char { + ($c: expr) => { + $crate::graphic_char!($c) || $crate::backslash_char!($c) + }; +} + +#[macro_export] +macro_rules! hexadecimal_digit_char { + ($c: expr) => { + ('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c) + }; +} + +#[macro_export] +macro_rules! layout_char { + ($c: expr) => { + $crate::char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}']) }; } @@ -228,9 +158,23 @@ macro_rules! meta_char { } #[macro_export] -macro_rules! solo_char { +macro_rules! new_line_char { ($c: expr) => { - $crate::char_class!($c, ['!', '(', ')', ',', ';', '[', ']', '{', '}', '|', '%']) + $c == '\n' + }; +} + +#[macro_export] +macro_rules! octal_digit_char { + ($c: expr) => { + ('0'..='7').contains(&$c) + }; +} + +#[macro_export] +macro_rules! octet_char { + ($c: expr) => { + ('\u{0000}'..='\u{00FF}').contains(&$c) }; } @@ -244,3 +188,66 @@ macro_rules! prolog_char { || $crate::meta_char!($c) }; } + +#[macro_export] +macro_rules! semicolon_char { + ($c: expr) => { + $c == ';' + }; +} + +#[macro_export] +macro_rules! sign_char { + ($c: expr) => { + $c == '-' || $c == '+' + }; +} + +#[macro_export] +macro_rules! single_quote_char { + ($c: expr) => { + $c == '\'' + }; +} + +#[macro_export] +macro_rules! small_letter_char { + ($c: expr) => { + ('a'..='z').contains(&$c) + }; +} + +#[macro_export] +macro_rules! solo_char { + ($c: expr) => { + $crate::char_class!($c, ['!', '(', ')', ',', ';', '[', ']', '{', '}', '|', '%']) + }; +} + +#[macro_export] +macro_rules! space_char { + ($c: expr) => { + $c == ' ' + }; +} + +#[macro_export] +macro_rules! symbolic_control_char { + ($c: expr) => { + $crate::char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0']) + }; +} + +#[macro_export] +macro_rules! symbolic_hexadecimal_char { + ($c: expr) => { + $c == 'x' + }; +} + +#[macro_export] +macro_rules! variable_indicator_char { + ($c: expr) => { + $c == '_' + }; +} diff --git a/src/lib/charsio.pl b/src/lib/charsio.pl index abd30311..d186eaf4 100644 --- a/src/lib/charsio.pl +++ b/src/lib/charsio.pl @@ -97,6 +97,7 @@ ctype(lower). ctype(meta). ctype(numeric). ctype(octal_digit). +ctype(octet). ctype(prolog). ctype(sign). ctype(solo). diff --git a/src/lib/serialization/abnf.pl b/src/lib/serialization/abnf.pl new file mode 100644 index 00000000..bf71ab9c --- /dev/null +++ b/src/lib/serialization/abnf.pl @@ -0,0 +1,166 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu) + Part of Scryer Prolog. + + [Core Rules](https://tools.ietf.org/html/rfc5234#appendix-B.1) of the + Augmented Backus-Naur Form specification (ABNF - RFC 5234). ABNF commonly + serves as the definition language for IETF communication protocols, so + having these DCGs can be extremely useful for reasoning about most IETF + syntaxes. The DCGs are presented in the order they appear in the RFC. + While some DCGs below use `char_type/2`, the most common ones are defined + manually in order to take advantage of Prolog's first-argument indexing. + + BSD 3-Clause License + + Copyright (c) 2021, Aram Panasenco + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +:- module(abnf, [abnf_alpha//1, + abnf_bit//1, + abnf_char//1, + abnf_cr//0, + abnf_crlf//0, + abnf_ctl//1, + abnf_digit//1, + abnf_dquote//0, + abnf_hexdig//1, + abnf_htab//0, + abnf_lf//0, + abnf_lwsp//0, + abnf_octet//1, + abnf_sp//0, + abnf_vchar//1, + abnf_wsp//0 ]). + +:- use_module(library(charsio)). +:- use_module(library(dcgs)). +:- use_module(library(dif)). +:- use_module(library(lists)). + +abnf_alpha('a') --> "a". +abnf_alpha('b') --> "b". +abnf_alpha('c') --> "c". +abnf_alpha('d') --> "d". +abnf_alpha('e') --> "e". +abnf_alpha('f') --> "f". +abnf_alpha('g') --> "g". +abnf_alpha('h') --> "h". +abnf_alpha('i') --> "i". +abnf_alpha('j') --> "j". +abnf_alpha('k') --> "k". +abnf_alpha('l') --> "l". +abnf_alpha('m') --> "m". +abnf_alpha('n') --> "n". +abnf_alpha('o') --> "o". +abnf_alpha('p') --> "p". +abnf_alpha('q') --> "q". +abnf_alpha('r') --> "r". +abnf_alpha('s') --> "s". +abnf_alpha('t') --> "t". +abnf_alpha('u') --> "u". +abnf_alpha('v') --> "v". +abnf_alpha('w') --> "w". +abnf_alpha('x') --> "x". +abnf_alpha('y') --> "y". +abnf_alpha('z') --> "z". +abnf_alpha('A') --> "A". +abnf_alpha('B') --> "B". +abnf_alpha('C') --> "C". +abnf_alpha('D') --> "D". +abnf_alpha('E') --> "E". +abnf_alpha('F') --> "F". +abnf_alpha('G') --> "G". +abnf_alpha('H') --> "H". +abnf_alpha('I') --> "I". +abnf_alpha('J') --> "J". +abnf_alpha('K') --> "K". +abnf_alpha('L') --> "L". +abnf_alpha('M') --> "M". +abnf_alpha('N') --> "N". +abnf_alpha('O') --> "O". +abnf_alpha('P') --> "P". +abnf_alpha('Q') --> "Q". +abnf_alpha('R') --> "R". +abnf_alpha('S') --> "S". +abnf_alpha('T') --> "T". +abnf_alpha('U') --> "U". +abnf_alpha('V') --> "V". +abnf_alpha('W') --> "W". +abnf_alpha('X') --> "X". +abnf_alpha('Y') --> "Y". +abnf_alpha('Z') --> "Z". + +abnf_bit('0') --> "0". +abnf_bit('1') --> "1". + +abnf_char(Char) --> [Char], { dif(Char, '\x0000\'), char_type(Char, ascii) }. %' + +abnf_cr --> "\r". + +abnf_crlf --> "\r\n". + +abnf_ctl(Char) --> [Char], { char_type(Char, ascii), char_type(Char, control) }. + +abnf_digit('0') --> "0". +abnf_digit('1') --> "1". +abnf_digit('2') --> "2". +abnf_digit('3') --> "3". +abnf_digit('4') --> "4". +abnf_digit('5') --> "5". +abnf_digit('6') --> "6". +abnf_digit('7') --> "7". +abnf_digit('8') --> "8". +abnf_digit('9') --> "9". + +abnf_dquote --> "\"". + +abnf_hexdig(Char) --> abnf_digit(Char). +abnf_hexdig('A') --> "A". +abnf_hexdig('B') --> "B". +abnf_hexdig('C') --> "C". +abnf_hexdig('D') --> "D". +abnf_hexdig('E') --> "E". +abnf_hexdig('F') --> "F". + +abnf_htab --> "\t". + +abnf_lf --> "\n". + +abnf_lwsp --> "". +abnf_lwsp --> abnf_wsp, abnf_lwsp. +abnf_lwsp --> abnf_clrf, abnf_wsp, abnf_lwsp. + +abnf_octet(Char) --> [Char], char_type(Char, octet). + +abnf_sp --> " ". + +abnf_vchar(Char) --> [Char], char_type(Char, ascii_graphic). + +abnf_wsp --> abnf_sp. +abnf_wsp --> abnf_htab. diff --git a/src/lib/json.pl b/src/lib/serialization/json.pl similarity index 96% rename from src/lib/json.pl rename to src/lib/serialization/json.pl index 2d7787d8..e1bebe11 100644 --- a/src/lib/json.pl +++ b/src/lib/serialization/json.pl @@ -2,6 +2,9 @@ Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu) Part of Scryer Prolog. + `json_chars//1` can be used with [`phrase_from_file/2`](src/lib/pio.pl) + or [`phrase/2`](src/lib/dcgs.pl) to parse and generate [JSON](https://www.json.org/json-en.html). + BSD 3-Clause License Copyright (c) 2021, Aram Panasenco @@ -49,8 +52,8 @@ json_chars(Internal) --> json_element(Internal). different types of values based on their principal functor. The principal functors match the types defined in the JSON Schema spec here: https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.1.1 EXCEPT we don't yet support the integer type. There are plans for more JSON Schema support in the near future. */ -json_value(object(Assoc)) --> json_object(Assoc). -json_value(array(List)) --> json_array(List). +json_value(pairs(Pairs)) --> json_object(Pairs). +json_value(list(List)) --> json_array(List). json_value(string(Chars)) --> json_string(Chars). json_value(number(Number)) --> json_number(Number). json_value(boolean(Bool)) --> json_boolean(Bool). @@ -82,7 +85,7 @@ json_members([NextPair|Pairs], Key-Value) --> ",", json_members(Pairs, NextPair). -json_member(Key, Value) --> json_ws, json_string(Key), json_ws, ":", json_element(Value). +json_member(string(Key), Value) --> json_ws, json_string(Key), json_ws, ":", json_element(Value). json_array([]) --> "[", json_ws, "]". json_array([Value|Values]) --> "[", json_elements(Values, Value), "]". diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 082a3e16..00aa6d6e 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -3,7 +3,7 @@ use prolog_parser::parser::*; use prolog_parser::{ alpha_char, alpha_numeric_char, binary_digit_char, clause_name, decimal_digit_char, exponent_char, graphic_char, graphic_token_char, hexadecimal_digit_char, layout_char, - meta_char, new_line_char, octal_digit_char, prolog_char, sign_char, solo_char, + meta_char, new_line_char, octal_digit_char, octet_char, prolog_char, sign_char, solo_char, symbolic_control_char, symbolic_hexadecimal_char, temp_v, }; @@ -1775,46 +1775,47 @@ impl MachineState { } }; } - macro_check!(symbolic_control_char, "symbolic_control"); - // macro_check!(space_char, "space"); - macro_check!(layout_char, "layout"); - macro_check!(symbolic_hexadecimal_char, "symbolic_hexadecimal"); - macro_check!(octal_digit_char, "octal_digit"); - macro_check!(binary_digit_char, "binary_digit"); - macro_check!(hexadecimal_digit_char, "hexadecimal_digit"); - macro_check!(exponent_char, "exponent"); - macro_check!(sign_char, "sign"); - // macro_check!(new_line_char, "new_line"); - // macro_check!(comment_1_char, "comment_1"); - // macro_check!(comment_2_char, "comment_2"); - // macro_check!(capital_letter_char, "upper"); - // macro_check!(small_letter_char, "lower"); - // macro_check!(variable_indicator_char, "variable_indicator"); - macro_check!(graphic_char, "graphic"); - macro_check!(graphic_token_char, "graphic_token"); macro_check!(alpha_char, "alpha"); - macro_check!(decimal_digit_char, "decimal_digit"); - // macro_check!(decimal_point_char, "decimal_point"); - macro_check!(alpha_numeric_char, "alnum"); - // macro_check!(cut_char, "cut"); - // macro_check!(semicolon_char, "semicolon"); - // macro_check!(backslash_char, "backslash"); - // macro_check!(single_quote_char, "single_quote"); - // macro_check!(double_quote_char, "double_quote"); - // macro_check!(back_quote_char, "back_quote"); - macro_check!(meta_char, "meta"); - macro_check!(solo_char, "solo"); - macro_check!(prolog_char, "prolog"); method_check!(is_alphabetic, "alphabetic"); - method_check!(is_lowercase, "lower"); - method_check!(is_uppercase, "upper"); - method_check!(is_whitespace, "whitespace"); method_check!(is_alphanumeric, "alphanumeric"); - method_check!(is_control, "control"); - method_check!(is_numeric, "numeric"); + macro_check!(alpha_numeric_char, "alnum"); method_check!(is_ascii, "ascii"); method_check!(is_ascii_punctuation, "ascii_ponctuaction"); method_check!(is_ascii_graphic, "ascii_graphic"); + // macro_check!(backslash_char, "backslash"); + // macro_check!(back_quote_char, "back_quote"); + macro_check!(binary_digit_char, "binary_digit"); + // macro_check!(capital_letter_char, "upper"); + // macro_check!(comment_1_char, "comment_1"); + // macro_check!(comment_2_char, "comment_2"); + method_check!(is_control, "control"); + // macro_check!(cut_char, "cut"); + macro_check!(decimal_digit_char, "decimal_digit"); + // macro_check!(decimal_point_char, "decimal_point"); + // macro_check!(double_quote_char, "double_quote"); + macro_check!(exponent_char, "exponent"); + macro_check!(graphic_char, "graphic"); + macro_check!(graphic_token_char, "graphic_token"); + macro_check!(hexadecimal_digit_char, "hexadecimal_digit"); + macro_check!(layout_char, "layout"); + method_check!(is_lowercase, "lower"); + macro_check!(meta_char, "meta"); + // macro_check!(new_line_char, "new_line"); + method_check!(is_numeric, "numeric"); + macro_check!(octal_digit_char, "octal_digit"); + macro_check!(octet_char, "octet"); + macro_check!(prolog_char, "prolog"); + // macro_check!(semicolon_char, "semicolon"); + macro_check!(sign_char, "sign"); + // macro_check!(single_quote_char, "single_quote"); + // macro_check!(small_letter_char, "lower"); + macro_check!(solo_char, "solo"); + // macro_check!(space_char, "space"); + macro_check!(symbolic_hexadecimal_char, "symbolic_hexadecimal"); + macro_check!(symbolic_control_char, "symbolic_control"); + method_check!(is_uppercase, "upper"); + // macro_check!(variable_indicator_char, "variable_indicator"); + method_check!(is_whitespace, "whitespace"); } &SystemClauseType::CheckCutPoint => { let addr = self.store(self.deref(self[temp_v!(1)])); diff --git a/src/tests/json/pass_everything.min.json b/src/tests/json/pass_everything.min.json index e474c5dc..27f37e62 100644 --- a/src/tests/json/pass_everything.min.json +++ b/src/tests/json/pass_everything.min.json @@ -1 +1 @@ -["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":0.000000000000123456789,"E":12345678900000000000000000000000000.0,"":23456789012000000000000000000000000000000000000000000000000000000000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"ģ䕧覫\u0001췯ꯍ\u001a","true":true,"false":false,"null":null,"array":[],"object":{},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"쫾몾ꮘﳞ볚\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] \ No newline at end of file +["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":0.000000000000123456789,"E":12345678900000000000000000000000000.0,"":23456789012000000000000000000000000000000000000000000000000000000000000000000,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"ģ䕧覫\u0001췯ꯍ\u001a","true":true,"false":false,"null":null,"array":[],"object":{},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"" \" %22 0x22 034 "","\/\\\"쫾몾ꮘﳞ볚\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"] diff --git a/src/tests/json/test_json.pl b/src/tests/json/test_json.pl index e41688ca..8b6d73bc 100644 --- a/src/tests/json/test_json.pl +++ b/src/tests/json/test_json.pl @@ -3,11 +3,11 @@ :- use_module(library(charsio)). :- use_module(library(dcgs)). :- use_module(library(format)). -:- use_module(library(json)). +:- use_module(library(iso_ext)). :- use_module(library(lists)). :- use_module(library(os)). :- use_module(library(pio)). -:- use_module(library(iso_ext)). +:- use_module(library(serialization/json)). :- use_module(library(time)). test_path(TestName, TestPath) :- @@ -36,7 +36,7 @@ minify_sample_json :- test_path("pass_everything.min.json", MinPath), setup_call_cleanup( open(MinPath, write, Stream), - format(Stream, "~s", [MinChars]), + format(Stream, "~s~n", [MinChars]), close(Stream) ). @@ -45,7 +45,8 @@ test_json_minify :- once(phrase_from_file(seq(RefChars), MinPath)), name_parse("pass_everything.json", Json), time(once(phrase(json_chars(Json), MinChars))), - RefChars = MinChars. + append(MinChars, "\n", MinFileChars), + RefChars = MinFileChars. test_json_int_float :- once(phrase(json_chars(number(ZeroInt)), "0")),