Merge pull request #920 from panasenco/serialize
Character logic cleanup and extension
This commit is contained in:
13
README.md
13
README.md
@@ -518,6 +518,17 @@ The modules that ship with Scryer Prolog are also called
|
|||||||
* [`csv`](src/lib/csv.pl)
|
* [`csv`](src/lib/csv.pl)
|
||||||
`parse_csv//1` and `parse_csv//2` can be used with [`phrase_from_file/2`](src/lib/pio.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
|
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)
|
* [`xpath`](src/lib/xpath.pl)
|
||||||
The predicate `xpath/3` is used for convenient reasoning about HTML
|
The predicate `xpath/3` is used for convenient reasoning about HTML
|
||||||
and XML documents, inspired by the XPath language. This library
|
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
|
ECDH key exchange over Curve25519 (X25519), authenticated symmetric
|
||||||
encryption with ChaCha20-Poly1305, and reasoning about elliptic curves.
|
encryption with ChaCha20-Poly1305, and reasoning about elliptic curves.
|
||||||
* [`uuid`](src/lib/uuid.pl) UUIDv4 generation and hex representation
|
* [`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:
|
To use predicates provided by the `lists` library, write:
|
||||||
|
|
||||||
|
|||||||
@@ -4,131 +4,6 @@ macro_rules! char_class {
|
|||||||
($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || $crate::char_class!($c, [$($cs),*]));
|
($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_export]
|
||||||
macro_rules! alpha_char {
|
macro_rules! alpha_char {
|
||||||
($c: expr) => {
|
($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_export]
|
||||||
macro_rules! decimal_digit_char {
|
macro_rules! decimal_digit_char {
|
||||||
($c: expr) => {
|
($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_export]
|
||||||
macro_rules! double_quote_char {
|
macro_rules! double_quote_char {
|
||||||
($c: expr) => {
|
($c: expr) => {
|
||||||
@@ -214,9 +110,43 @@ macro_rules! double_quote_char {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! back_quote_char {
|
macro_rules! end_line_comment_char {
|
||||||
($c: expr) => {
|
($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_export]
|
||||||
macro_rules! solo_char {
|
macro_rules! new_line_char {
|
||||||
($c: expr) => {
|
($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)
|
|| $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 == '_'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ ctype(lower).
|
|||||||
ctype(meta).
|
ctype(meta).
|
||||||
ctype(numeric).
|
ctype(numeric).
|
||||||
ctype(octal_digit).
|
ctype(octal_digit).
|
||||||
|
ctype(octet).
|
||||||
ctype(prolog).
|
ctype(prolog).
|
||||||
ctype(sign).
|
ctype(sign).
|
||||||
ctype(solo).
|
ctype(solo).
|
||||||
|
|||||||
166
src/lib/serialization/abnf.pl
Normal file
166
src/lib/serialization/abnf.pl
Normal file
@@ -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.
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu)
|
Written Apr 2021 by Aram Panasenco (panasenco@ucla.edu)
|
||||||
Part of Scryer Prolog.
|
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
|
BSD 3-Clause License
|
||||||
|
|
||||||
Copyright (c) 2021, Aram Panasenco
|
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
|
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
|
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. */
|
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(pairs(Pairs)) --> json_object(Pairs).
|
||||||
json_value(array(List)) --> json_array(List).
|
json_value(list(List)) --> json_array(List).
|
||||||
json_value(string(Chars)) --> json_string(Chars).
|
json_value(string(Chars)) --> json_string(Chars).
|
||||||
json_value(number(Number)) --> json_number(Number).
|
json_value(number(Number)) --> json_number(Number).
|
||||||
json_value(boolean(Bool)) --> json_boolean(Bool).
|
json_value(boolean(Bool)) --> json_boolean(Bool).
|
||||||
@@ -82,7 +85,7 @@ json_members([NextPair|Pairs], Key-Value) -->
|
|||||||
",",
|
",",
|
||||||
json_members(Pairs, NextPair).
|
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([]) --> "[", json_ws, "]".
|
||||||
json_array([Value|Values]) --> "[", json_elements(Values, Value), "]".
|
json_array([Value|Values]) --> "[", json_elements(Values, Value), "]".
|
||||||
@@ -3,7 +3,7 @@ use prolog_parser::parser::*;
|
|||||||
use prolog_parser::{
|
use prolog_parser::{
|
||||||
alpha_char, alpha_numeric_char, binary_digit_char, clause_name, decimal_digit_char,
|
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,
|
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,
|
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!(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_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_alphanumeric, "alphanumeric");
|
||||||
method_check!(is_control, "control");
|
macro_check!(alpha_numeric_char, "alnum");
|
||||||
method_check!(is_numeric, "numeric");
|
|
||||||
method_check!(is_ascii, "ascii");
|
method_check!(is_ascii, "ascii");
|
||||||
method_check!(is_ascii_punctuation, "ascii_ponctuaction");
|
method_check!(is_ascii_punctuation, "ascii_ponctuaction");
|
||||||
method_check!(is_ascii_graphic, "ascii_graphic");
|
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 => {
|
&SystemClauseType::CheckCutPoint => {
|
||||||
let addr = self.store(self.deref(self[temp_v!(1)]));
|
let addr = self.store(self.deref(self[temp_v!(1)]));
|
||||||
|
|||||||
@@ -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"]
|
["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"]
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
:- use_module(library(charsio)).
|
:- use_module(library(charsio)).
|
||||||
:- use_module(library(dcgs)).
|
:- use_module(library(dcgs)).
|
||||||
:- use_module(library(format)).
|
:- use_module(library(format)).
|
||||||
:- use_module(library(json)).
|
:- use_module(library(iso_ext)).
|
||||||
:- use_module(library(lists)).
|
:- use_module(library(lists)).
|
||||||
:- use_module(library(os)).
|
:- use_module(library(os)).
|
||||||
:- use_module(library(pio)).
|
:- use_module(library(pio)).
|
||||||
:- use_module(library(iso_ext)).
|
:- use_module(library(serialization/json)).
|
||||||
:- use_module(library(time)).
|
:- use_module(library(time)).
|
||||||
|
|
||||||
test_path(TestName, TestPath) :-
|
test_path(TestName, TestPath) :-
|
||||||
@@ -36,7 +36,7 @@ minify_sample_json :-
|
|||||||
test_path("pass_everything.min.json", MinPath),
|
test_path("pass_everything.min.json", MinPath),
|
||||||
setup_call_cleanup(
|
setup_call_cleanup(
|
||||||
open(MinPath, write, Stream),
|
open(MinPath, write, Stream),
|
||||||
format(Stream, "~s", [MinChars]),
|
format(Stream, "~s~n", [MinChars]),
|
||||||
close(Stream)
|
close(Stream)
|
||||||
).
|
).
|
||||||
|
|
||||||
@@ -45,7 +45,8 @@ test_json_minify :-
|
|||||||
once(phrase_from_file(seq(RefChars), MinPath)),
|
once(phrase_from_file(seq(RefChars), MinPath)),
|
||||||
name_parse("pass_everything.json", Json),
|
name_parse("pass_everything.json", Json),
|
||||||
time(once(phrase(json_chars(Json), MinChars))),
|
time(once(phrase(json_chars(Json), MinChars))),
|
||||||
RefChars = MinChars.
|
append(MinChars, "\n", MinFileChars),
|
||||||
|
RefChars = MinFileChars.
|
||||||
|
|
||||||
test_json_int_float :-
|
test_json_int_float :-
|
||||||
once(phrase(json_chars(number(ZeroInt)), "0")),
|
once(phrase(json_chars(number(ZeroInt)), "0")),
|
||||||
|
|||||||
Reference in New Issue
Block a user