| Did you know ... | Search Documentation: |
| Packs (add-ons) for SWI-Prolog |
| Title: | PEG syntax for prolog |
|---|---|
| Rating: | Not rated. Create the first rating! |
| Latest version: | 1.0 |
| SHA1 sum: | c5dc6771d1744eca5f526f3671c7fbeb5a37dd5b |
| Author: | samlai <piortlierr@gmail.com> |
| Maintainer: | samlai <piortlierr@gmail.com> |
| Packager: | samlai <piortlierr@gmail.com> |
No reviews. Create the first review!.
| Version | SHA1 | #Downloads | URL |
|---|---|---|---|
| 1.0 | 373c74e5da9dfe544634ca0478e3156c5ebe7b64 | 5 | https://github.com/lasamlai/peg_syntax.git |
| c5dc6771d1744eca5f526f3671c7fbeb5a37dd5b | 6 | https://github.com/lasamlai/peg_syntax.git | |
| 0.1 | b3d61ba431370ad760e4e7e9bac04c0ecd47b73c | 4 | https://github.com/lasamlai/peg_syntax.git |
This package implement [PEG] syntax in [swi-prolog] by [term_expansion/2].
This package adds new operators:
| Precedence | Type | Name | Description |
|---|---|---|---|
| 1200 | xfx | <-- | Rule |
| 1105 | xfy | / | Ordered choice |
| 700 | xf | ? | Zero-or-more |
| 700 | xf | * | One-or-more |
| 700 | xf | + | Optional |
| 700 | fx | & | And-predicate |
| 700 | fx | ! | Not-predicate |
Write PEG like [DCG] clauses in prolog, but use <--/2 instead of -->/2. The /, ?, * and + operators and the DCG operators (like {}, `,`, `|`) are allowed in the body of the PEG clause. (If you use the `|` operator it create choice points like DCG).
:- use_module(library(peg_syntax)).
gram <-- "#", ("a" / "b")*, c+, "#"? .
c <-- "c".
Note: The space between the ? and `.` characters is necessary!
?- phrase(gram, `#abbacc`, T). T = []. ?- phrase(gram, `#abba`, T). false. ?- phrase(gram, `#abba#`, T). false. ?- phrase(gram, `#ccc#`, T). T = [].
Note: Each execution should have no choice points.
Using the star * and the plus + operators change the semantic of variables inside these operators. As bellow, the H var inside the star operator describes an element of a list, but outside of the star operator describe that list.
:- use_module(library(peg_syntax)). bs(H) <-- (a(H) / b(H))* . a(a) <-- "a". b(b) <-- "b".
?- phrase(bs(V), `bbabxy`, T). V = [b, b, a, b], T = [120, 121]. ?- phrase(bs(V), ``, T). V = T, T = [].
For each variable in a * operator is creating a separate list. Each element of the list is default uninitialized.
:- use_module(library(peg_syntax)). pars(lists(A,B)) <-- (a(A)/ b(B))* . a(a) <-- "a". b(b) <-- "b".
?- phrase(pars(P), `abba`, T). P = lists([a, _, _, a], [_, b, b, _]), T = [].
If you want to have a different aggregator, add it by {} as below.
:- use_module(library(peg_syntax)).
pars(P) <-- ((a(A)/ b(B)), {P = pair(A, B)})* .
a(a) <-- "a".
b(b) <-- "b".
?- phrase(pars(P), `abba`, T). P = [pair(a, _), pair(_, b), pair(_, b), pair(a, _)], T = [].
Variables in the option operator if not used are uninitialized.
:- use_module(library(peg_syntax)). bopt(B) <-- b(B)? . b(b) <-- "b".
?- phrase(bopt(X), `b`, []). X = b. ?- phrase(bopt(X), ``, []). true.
The PEG grammar is [greedy] so the below bad//0 clause will not parse anything.
:- use_module(library(peg_syntax)). bad <-- "b"*, "b". good <-- "b", "b"* .
?- phrase(bad, `bb`, []). false. ?- phrase(good, `bb`, []). true.
Expressions inside the & and ! operators never consumes any input.
:- use_module(library(peg_syntax)).
diff_list(X) <-- (& (char(A), !char(A)), char(X))* .
char(A) <-- [C], {char_code(A, C)}.
Note: The space between the & and `(` characters is necessary!
?- phrase(diff_list(X), `ababa`, T). X = [a, b, a, b, a], T = []. ?- phrase(diff_list(X), `ababba`, T). X = [a, b, a], T = [98, 98, 97].
To install this package write the bellow term in the swipl REPL.
?- pack_install(peg_syntax).
[PEG]: https://en.wikipedia.org/wiki/Parsing_expression_grammar [term_expansion/2]: https://www.swi-prolog.org/pldoc/doc_for?object=term_expansion/2 [swi-prolog]: https://www.swi-prolog.org/ [DCG]: https://eu.swi-prolog.org/pldoc/man?section=DCG [greedy]: https://en.wikipedia.org/wiki/Greedy_algorithm
Pack contains 6 files holding a total of 11.7K bytes.