feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1 @@
.. include:: ../CODE_OF_CONDUCT.rst

View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = PyParsing
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@@ -0,0 +1,503 @@
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.railroad-heading {
font-family: monospace;
}
</style>
</head>
<body>
<div class="railroad-group">
<h1 class="railroad-heading">Forward</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="172" viewBox="0 0 1344.0 172" width="1344.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 53v20m10 -20v20m-10 -10h20"></path></g><path d="M40 63h10"></path><g>
<path d="M50 63h0.0"></path><path d="M1294.0 63h0.0"></path><g>
<path d="M50.0 63h0.0"></path><path d="M1048.0 63h0.0"></path><g>
<path d="M50.0 63h0.0"></path><path d="M662.0 63h0.0"></path><g>
<path d="M50.0 63h0.0"></path><path d="M571.0 63h0.0"></path><g class="terminal">
<path d="M50.0 63h0.0"></path><path d="M138.0 63h0.0"></path><rect height="22" rx="10" ry="10" width="88.0" x="50.0" y="52"></rect><text x="94.0" y="67">'select'</text></g><path d="M138.0 63h10"></path><g>
<path d="M148.0 63h0.0"></path><path d="M571.0 63h0.0"></path><path d="M148.0 63h20"></path><g class="terminal">
<path d="M168.0 63h168.75"></path><path d="M382.25 63h168.75"></path><rect height="22" rx="10" ry="10" width="45.5" x="336.75" y="52"></rect><text x="359.5" y="67">'&#42;'</text></g><path d="M551.0 63h20"></path><path d="M148.0 63a10 10 0 0 1 10 10v42a10 10 0 0 0 10 10"></path><g>
<path d="M168.0 125h0.0"></path><path d="M551.0 125h0.0"></path><g class="non-terminal">
<path d="M168.0 125h0.0"></path><path d="M281.5 125h0.0"></path><rect height="22" width="113.5" x="168.0" y="114"></rect><text x="224.75" y="129">column name</text></g><path d="M281.5 125h10"></path><g>
<path d="M291.5 125h0.0"></path><path d="M551.0 125h0.0"></path><path d="M291.5 125a10 10 0 0 0 10 -10v-23a10 10 0 0 1 10 -10"></path><g>
<path d="M311.5 82h219.5"></path></g><path d="M531.0 82a10 10 0 0 1 10 10v23a10 10 0 0 0 10 10"></path><path d="M291.5 125h20"></path><g>
<path d="M311.5 125h0.0"></path><path d="M531.0 125h0.0"></path><path d="M311.5 125h10"></path><g>
<path d="M321.5 125h0.0"></path><path d="M521.0 125h0.0"></path><g>
<path d="M321.5 125h0.0"></path><path d="M387.5 125h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="66" x="321.5" y="106"></rect><g class="terminal">
<path d="M321.5 125h10.25"></path><path d="M377.25 125h10.25"></path><rect height="22" rx="10" ry="10" width="45.5" x="331.75" y="114"></rect><text x="354.5" y="129">','</text></g><g>
<path d="M321.5 98h0.0"></path><path d="M387.5 98h0.0"></path><text class="comment" x="354.5" y="103">Suppress</text></g></g><path d="M387.5 125h10"></path><path d="M397.5 125h10"></path><g class="non-terminal">
<path d="M407.5 125h0.0"></path><path d="M521.0 125h0.0"></path><rect height="22" width="113.5" x="407.5" y="114"></rect><text x="464.25" y="129">column name</text></g></g><path d="M521.0 125h10"></path><path d="M321.5 125a10 10 0 0 0 -10 10v7a10 10 0 0 0 10 10"></path><g>
<path d="M321.5 152h199.5"></path></g><path d="M521.0 152a10 10 0 0 0 10 -10v-7a10 10 0 0 0 -10 -10"></path></g><path d="M531.0 125h20"></path></g></g><path d="M551.0 125a10 10 0 0 0 10 -10v-42a10 10 0 0 1 10 -10"></path></g></g><path d="M571.0 63h10"></path><path d="M581.0 63h10"></path><g class="terminal">
<path d="M591.0 63h0.0"></path><path d="M662.0 63h0.0"></path><rect height="22" rx="10" ry="10" width="71.0" x="591.0" y="52"></rect><text x="626.5" y="67">'from'</text></g></g><path d="M662.0 63h10"></path><path d="M672.0 63h10"></path><g>
<path d="M682.0 63h0.0"></path><path d="M1048.0 63h0.0"></path><g class="non-terminal">
<path d="M682.0 63h0.0"></path><path d="M787.0 63h0.0"></path><rect height="22" width="105.0" x="682.0" y="52"></rect><text x="734.5" y="67">table name</text></g><path d="M787.0 63h10"></path><g>
<path d="M797.0 63h0.0"></path><path d="M1048.0 63h0.0"></path><path d="M797.0 63a10 10 0 0 0 10 -10v-23a10 10 0 0 1 10 -10"></path><g>
<path d="M817.0 20h211.0"></path></g><path d="M1028.0 20a10 10 0 0 1 10 10v23a10 10 0 0 0 10 10"></path><path d="M797.0 63h20"></path><g>
<path d="M817.0 63h0.0"></path><path d="M1028.0 63h0.0"></path><path d="M817.0 63h10"></path><g>
<path d="M827.0 63h0.0"></path><path d="M1018.0 63h0.0"></path><g>
<path d="M827.0 63h0.0"></path><path d="M893.0 63h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="66" x="827.0" y="44"></rect><g class="terminal">
<path d="M827.0 63h10.25"></path><path d="M882.75 63h10.25"></path><rect height="22" rx="10" ry="10" width="45.5" x="837.25" y="52"></rect><text x="860.0" y="67">','</text></g><g>
<path d="M827.0 36h0.0"></path><path d="M893.0 36h0.0"></path><text class="comment" x="860.0" y="41">Suppress</text></g></g><path d="M893.0 63h10"></path><path d="M903.0 63h10"></path><g class="non-terminal">
<path d="M913.0 63h0.0"></path><path d="M1018.0 63h0.0"></path><rect height="22" width="105.0" x="913.0" y="52"></rect><text x="965.5" y="67">table name</text></g></g><path d="M1018.0 63h10"></path><path d="M827.0 63a10 10 0 0 0 -10 10v7a10 10 0 0 0 10 10"></path><g>
<path d="M827.0 90h191.0"></path></g><path d="M1018.0 90a10 10 0 0 0 10 -10v-7a10 10 0 0 0 -10 -10"></path></g><path d="M1028.0 63h20"></path></g></g></g><path d="M1048.0 63h10"></path><g>
<path d="M1058.0 63h0.0"></path><path d="M1294.0 63h0.0"></path><path d="M1058.0 63a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g>
<path d="M1078.0 43h196.0"></path></g><path d="M1274.0 43a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M1058.0 63h20"></path><g>
<path d="M1078.0 63h0.0"></path><path d="M1274.0 63h0.0"></path><g class="terminal">
<path d="M1078.0 63h0.0"></path><path d="M1157.5 63h0.0"></path><rect height="22" rx="10" ry="10" width="79.5" x="1078.0" y="52"></rect><text x="1117.75" y="67">'where'</text></g><path d="M1157.5 63h10"></path><path d="M1167.5 63h10"></path><g class="non-terminal">
<path d="M1177.5 63h0.0"></path><path d="M1274.0 63h0.0"></path><rect height="22" width="96.5" x="1177.5" y="52"></rect><text x="1225.75" y="67">'or' term</text></g></g><path d="M1274.0 63h20"></path></g></g><path d="M1294.0 63h10"></path><path d="M 1304.0 63 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">column name</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="110" viewBox="0 0 706.5 110" width="706.5" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 53v20m10 -20v20m-10 -10h20"></path></g><path d="M40 63h10"></path><g>
<path d="M50 63h0.0"></path><path d="M656.5 63h0.0"></path><g>
<path d="M50.0 63h0.0"></path><path d="M285.5 63h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="235.5" x="50.0" y="44"></rect><g class="terminal">
<path d="M50.0 63h10.0"></path><path d="M275.5 63h10.0"></path><rect height="22" rx="10" ry="10" width="215.5" x="60.0" y="52"></rect><text x="167.75" y="67">W:(A-Za-z, $0-9A-Z&#95;a-z)</text></g><g>
<path d="M50.0 36h0.0"></path><path d="M130.0 36h0.0"></path><text class="comment" x="90.0" y="41">identifier</text></g></g><path d="M285.5 63h10"></path><g>
<path d="M295.5 63h0.0"></path><path d="M656.5 63h0.0"></path><path d="M295.5 63a10 10 0 0 0 10 -10v-23a10 10 0 0 1 10 -10"></path><g>
<path d="M315.5 20h321.0"></path></g><path d="M636.5 20a10 10 0 0 1 10 10v23a10 10 0 0 0 10 10"></path><path d="M295.5 63h20"></path><g>
<path d="M315.5 63h0.0"></path><path d="M636.5 63h0.0"></path><path d="M315.5 63h10"></path><g>
<path d="M325.5 63h0.0"></path><path d="M626.5 63h0.0"></path><g class="terminal">
<path d="M325.5 63h0.0"></path><path d="M371.0 63h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="325.5" y="52"></rect><text x="348.25" y="67">'.'</text></g><path d="M371.0 63h10"></path><path d="M381.0 63h10"></path><g>
<path d="M391.0 63h0.0"></path><path d="M626.5 63h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="235.5" x="391.0" y="44"></rect><g class="terminal">
<path d="M391.0 63h10.0"></path><path d="M616.5 63h10.0"></path><rect height="22" rx="10" ry="10" width="215.5" x="401.0" y="52"></rect><text x="508.75" y="67">W:(A-Za-z, $0-9A-Z&#95;a-z)</text></g><g>
<path d="M391.0 36h0.0"></path><path d="M471.0 36h0.0"></path><text class="comment" x="431.0" y="41">identifier</text></g></g></g><path d="M626.5 63h10"></path><path d="M325.5 63a10 10 0 0 0 -10 10v7a10 10 0 0 0 10 10"></path><g>
<path d="M325.5 90h301.0"></path></g><path d="M626.5 90a10 10 0 0 0 10 -10v-7a10 10 0 0 0 -10 -10"></path></g><path d="M636.5 63h20"></path></g></g><path d="M656.5 63h10"></path><path d="M 666.5 63 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">table name</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="110" viewBox="0 0 706.5 110" width="706.5" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 53v20m10 -20v20m-10 -10h20"></path></g><path d="M40 63h10"></path><g>
<path d="M50 63h0.0"></path><path d="M656.5 63h0.0"></path><g>
<path d="M50.0 63h0.0"></path><path d="M285.5 63h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="235.5" x="50.0" y="44"></rect><g class="terminal">
<path d="M50.0 63h10.0"></path><path d="M275.5 63h10.0"></path><rect height="22" rx="10" ry="10" width="215.5" x="60.0" y="52"></rect><text x="167.75" y="67">W:(A-Za-z, $0-9A-Z&#95;a-z)</text></g><g>
<path d="M50.0 36h0.0"></path><path d="M130.0 36h0.0"></path><text class="comment" x="90.0" y="41">identifier</text></g></g><path d="M285.5 63h10"></path><g>
<path d="M295.5 63h0.0"></path><path d="M656.5 63h0.0"></path><path d="M295.5 63a10 10 0 0 0 10 -10v-23a10 10 0 0 1 10 -10"></path><g>
<path d="M315.5 20h321.0"></path></g><path d="M636.5 20a10 10 0 0 1 10 10v23a10 10 0 0 0 10 10"></path><path d="M295.5 63h20"></path><g>
<path d="M315.5 63h0.0"></path><path d="M636.5 63h0.0"></path><path d="M315.5 63h10"></path><g>
<path d="M325.5 63h0.0"></path><path d="M626.5 63h0.0"></path><g class="terminal">
<path d="M325.5 63h0.0"></path><path d="M371.0 63h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="325.5" y="52"></rect><text x="348.25" y="67">'.'</text></g><path d="M371.0 63h10"></path><path d="M381.0 63h10"></path><g>
<path d="M391.0 63h0.0"></path><path d="M626.5 63h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="235.5" x="391.0" y="44"></rect><g class="terminal">
<path d="M391.0 63h10.0"></path><path d="M616.5 63h10.0"></path><rect height="22" rx="10" ry="10" width="215.5" x="401.0" y="52"></rect><text x="508.75" y="67">W:(A-Za-z, $0-9A-Z&#95;a-z)</text></g><g>
<path d="M391.0 36h0.0"></path><path d="M471.0 36h0.0"></path><text class="comment" x="431.0" y="41">identifier</text></g></g></g><path d="M626.5 63h10"></path><path d="M325.5 63a10 10 0 0 0 -10 10v7a10 10 0 0 0 10 10"></path><g>
<path d="M325.5 90h301.0"></path></g><path d="M626.5 90a10 10 0 0 0 10 -10v-7a10 10 0 0 0 -10 -10"></path></g><path d="M636.5 63h20"></path></g></g><path d="M656.5 63h10"></path><path d="M 666.5 63 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">'or' term</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="125" viewBox="0 0 788.0 125" width="788.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 45v20m10 -20v20m-10 -10h20"></path></g><g>
<path d="M40 55h0.0"></path><path d="M748.0 55h0.0"></path><path d="M40.0 55h20"></path><g>
<path d="M60.0 55h0.0"></path><path d="M728.0 55h0.0"></path><g>
<path d="M60.0 55h0.0"></path><path d="M384.0 55h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="324.0" x="60.0" y="36"></rect><g>
<path d="M60.0 55h10.0"></path><path d="M374.0 55h10.0"></path><g>
<path d="M70.0 55h0.0"></path><path d="M249.0 55h0.0"></path><g class="non-terminal">
<path d="M70.0 55h0.0"></path><path d="M175.0 55h0.0"></path><rect height="22" width="105.0" x="70.0" y="44"></rect><text x="122.5" y="59">'and' term</text></g><path d="M175.0 55h10"></path><path d="M185.0 55h10"></path><g class="terminal">
<path d="M195.0 55h0.0"></path><path d="M249.0 55h0.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="195.0" y="44"></rect><text x="222.0" y="59">'or'</text></g></g><path d="M249.0 55h10"></path><path d="M259.0 55h10"></path><g class="non-terminal">
<path d="M269.0 55h0.0"></path><path d="M374.0 55h0.0"></path><rect height="22" width="105.0" x="269.0" y="44"></rect><text x="321.5" y="59">'and' term</text></g></g><g>
<path d="M60.0 28h0.0"></path><path d="M91.0 28h0.0"></path><text class="comment" x="75.5" y="33">&#95;FB</text></g></g><path d="M384.0 55h10"></path><path d="M394.0 55h10"></path><g>
<path d="M404.0 55h0.0"></path><path d="M728.0 55h0.0"></path><g class="non-terminal">
<path d="M404.0 55h0.0"></path><path d="M509.0 55h0.0"></path><rect height="22" width="105.0" x="404.0" y="44"></rect><text x="456.5" y="59">'and' term</text></g><path d="M509.0 55h10"></path><path d="M519.0 55h10"></path><g>
<path d="M529.0 55h0.0"></path><path d="M728.0 55h0.0"></path><path d="M529.0 55h10"></path><g>
<path d="M539.0 55h0.0"></path><path d="M718.0 55h0.0"></path><g class="terminal">
<path d="M539.0 55h0.0"></path><path d="M593.0 55h0.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="539.0" y="44"></rect><text x="566.0" y="59">'or'</text></g><path d="M593.0 55h10"></path><path d="M603.0 55h10"></path><g class="non-terminal">
<path d="M613.0 55h0.0"></path><path d="M718.0 55h0.0"></path><rect height="22" width="105.0" x="613.0" y="44"></rect><text x="665.5" y="59">'and' term</text></g></g><path d="M718.0 55h10"></path><path d="M539.0 55a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g>
<path d="M539.0 75h179.0"></path></g><path d="M718.0 75a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g></g></g><path d="M728.0 55h20"></path><path d="M40.0 55a10 10 0 0 1 10 10v19a10 10 0 0 0 10 10"></path><g class="non-terminal">
<path d="M60.0 94h281.5"></path><path d="M446.5 94h281.5"></path><rect height="22" width="105.0" x="341.5" y="83"></rect><text x="394.0" y="98">'and' term</text></g><path d="M728.0 94a10 10 0 0 0 10 -10v-19a10 10 0 0 1 10 -10"></path></g><path d="M 748.0 55 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">'and' term</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="125" viewBox="0 0 805.0 125" width="805.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 45v20m10 -20v20m-10 -10h20"></path></g><g>
<path d="M40 55h0.0"></path><path d="M765.0 55h0.0"></path><path d="M40.0 55h20"></path><g>
<path d="M60.0 55h0.0"></path><path d="M745.0 55h0.0"></path><g>
<path d="M60.0 55h0.0"></path><path d="M392.5 55h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="332.5" x="60.0" y="36"></rect><g>
<path d="M60.0 55h10.0"></path><path d="M382.5 55h10.0"></path><g>
<path d="M70.0 55h0.0"></path><path d="M257.5 55h0.0"></path><g class="non-terminal">
<path d="M70.0 55h0.0"></path><path d="M175.0 55h0.0"></path><rect height="22" width="105.0" x="70.0" y="44"></rect><text x="122.5" y="59">'not' term</text></g><path d="M175.0 55h10"></path><path d="M185.0 55h10"></path><g class="terminal">
<path d="M195.0 55h0.0"></path><path d="M257.5 55h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="195.0" y="44"></rect><text x="226.25" y="59">'and'</text></g></g><path d="M257.5 55h10"></path><path d="M267.5 55h10"></path><g class="non-terminal">
<path d="M277.5 55h0.0"></path><path d="M382.5 55h0.0"></path><rect height="22" width="105.0" x="277.5" y="44"></rect><text x="330.0" y="59">'not' term</text></g></g><g>
<path d="M60.0 28h0.0"></path><path d="M91.0 28h0.0"></path><text class="comment" x="75.5" y="33">&#95;FB</text></g></g><path d="M392.5 55h10"></path><path d="M402.5 55h10"></path><g>
<path d="M412.5 55h0.0"></path><path d="M745.0 55h0.0"></path><g class="non-terminal">
<path d="M412.5 55h0.0"></path><path d="M517.5 55h0.0"></path><rect height="22" width="105.0" x="412.5" y="44"></rect><text x="465.0" y="59">'not' term</text></g><path d="M517.5 55h10"></path><path d="M527.5 55h10"></path><g>
<path d="M537.5 55h0.0"></path><path d="M745.0 55h0.0"></path><path d="M537.5 55h10"></path><g>
<path d="M547.5 55h0.0"></path><path d="M735.0 55h0.0"></path><g class="terminal">
<path d="M547.5 55h0.0"></path><path d="M610.0 55h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="547.5" y="44"></rect><text x="578.75" y="59">'and'</text></g><path d="M610.0 55h10"></path><path d="M620.0 55h10"></path><g class="non-terminal">
<path d="M630.0 55h0.0"></path><path d="M735.0 55h0.0"></path><rect height="22" width="105.0" x="630.0" y="44"></rect><text x="682.5" y="59">'not' term</text></g></g><path d="M735.0 55h10"></path><path d="M547.5 55a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path><g>
<path d="M547.5 75h187.5"></path></g><path d="M735.0 75a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path></g></g></g><path d="M745.0 55h20"></path><path d="M40.0 55a10 10 0 0 1 10 10v19a10 10 0 0 0 10 10"></path><g class="non-terminal">
<path d="M60.0 94h290.0"></path><path d="M455.0 94h290.0"></path><rect height="22" width="105.0" x="350.0" y="83"></rect><text x="402.5" y="98">'not' term</text></g><path d="M745.0 94a10 10 0 0 0 10 -10v-19a10 10 0 0 1 10 -10"></path></g><path d="M 765.0 55 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">'not' term</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="372" viewBox="0 0 1622.5 372" width="1622.5" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 45v20m10 -20v20m-10 -10h20"></path></g><g>
<path d="M40 55h0.0"></path><path d="M1582.5 55h0.0"></path><path d="M40.0 55h20"></path><g>
<path d="M60.0 55h528.75"></path><path d="M1033.75 55h528.75"></path><g>
<path d="M588.75 55h0.0"></path><path d="M796.25 55h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="207.5" x="588.75" y="36"></rect><g>
<path d="M588.75 55h10.0"></path><path d="M786.25 55h10.0"></path><g class="terminal">
<path d="M598.75 55h0.0"></path><path d="M661.25 55h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="598.75" y="44"></rect><text x="630.0" y="59">'not'</text></g><path d="M661.25 55h10"></path><path d="M671.25 55h10"></path><g class="non-terminal">
<path d="M681.25 55h0.0"></path><path d="M786.25 55h0.0"></path><rect height="22" width="105.0" x="681.25" y="44"></rect><text x="733.75" y="59">'not' term</text></g></g><g>
<path d="M588.75 28h0.0"></path><path d="M619.75 28h0.0"></path><text class="comment" x="604.25" y="33">&#95;FB</text></g></g><path d="M796.25 55h10"></path><path d="M806.25 55h10"></path><g>
<path d="M816.25 55h0.0"></path><path d="M1033.75 55h0.0"></path><g>
<path d="M816.25 55h0.0"></path><path d="M918.75 55h0.0"></path><path d="M816.25 55a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><g>
<path d="M836.25 35h62.5"></path></g><path d="M898.75 35a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M816.25 55h20"></path><g class="terminal">
<path d="M836.25 55h0.0"></path><path d="M898.75 55h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="836.25" y="44"></rect><text x="867.5" y="59">'not'</text></g><path d="M898.75 55h20"></path></g><path d="M918.75 55h10"></path><g class="non-terminal">
<path d="M928.75 55h0.0"></path><path d="M1033.75 55h0.0"></path><rect height="22" width="105.0" x="928.75" y="44"></rect><text x="981.25" y="59">'not' term</text></g></g></g><path d="M1562.5 55h20"></path><path d="M40.0 55a10 10 0 0 1 10 10v27a10 10 0 0 0 10 10"></path><g>
<path d="M60.0 102h0.0"></path><path d="M1562.5 102h0.0"></path><path d="M60.0 102h20"></path><g>
<path d="M80.0 102h0.0"></path><path d="M1542.5 102h0.0"></path><path d="M80.0 102h20"></path><g>
<path d="M100.0 102h0.0"></path><path d="M1522.5 102h0.0"></path><path d="M100.0 102h20"></path><g>
<path d="M120.0 102h0.0"></path><path d="M1502.5 102h0.0"></path><path d="M120.0 102h20"></path><g>
<path d="M140.0 102h0.0"></path><path d="M1482.5 102h0.0"></path><g>
<path d="M140.0 102h0.0"></path><path d="M1366.0 102h0.0"></path><g class="non-terminal">
<path d="M140.0 102h0.0"></path><path d="M253.5 102h0.0"></path><rect height="22" width="113.5" x="140.0" y="91"></rect><text x="196.75" y="106">column name</text></g><path d="M253.5 102h10"></path><g>
<path d="M263.5 102h0.0"></path><path d="M1366.0 102h0.0"></path><path d="M263.5 102a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10h978.5"></path><path d="M359.0 122h987.0a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path><path d="M263.5 102h10"></path><g class="terminal">
<path d="M273.5 102h10.0"></path><path d="M329.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="283.5" y="91"></rect><text x="306.25" y="106">'='</text></g><path d="M339.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M339.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M359.0 102h10.0"></path><path d="M423.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="369.0" y="91"></rect><text x="396.0" y="106">'!='</text></g><path d="M433.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M433.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M453.0 102h10.0"></path><path d="M517.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="463.0" y="91"></rect><text x="490.0" y="106">'&#60;='</text></g><path d="M527.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M527.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M547.0 102h10.0"></path><path d="M602.5 102h10.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="557.0" y="91"></rect><text x="579.75" y="106">'&#60;'</text></g><path d="M612.5 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M612.5 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M632.5 102h10.0"></path><path d="M696.5 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="642.5" y="91"></rect><text x="669.5" y="106">'>='</text></g><path d="M706.5 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M706.5 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M726.5 102h10.0"></path><path d="M782.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="736.5" y="91"></rect><text x="759.25" y="106">'>'</text></g><path d="M792.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M792.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M812.0 102h10.0"></path><path d="M876.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="822.0" y="91"></rect><text x="849.0" y="106">'EQ'</text></g><path d="M886.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M886.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M906.0 102h10.0"></path><path d="M970.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="916.0" y="91"></rect><text x="943.0" y="106">'NE'</text></g><path d="M980.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M980.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M1000.0 102h10.0"></path><path d="M1064.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="1010.0" y="91"></rect><text x="1037.0" y="106">'LT'</text></g><path d="M1074.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M1074.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M1094.0 102h10.0"></path><path d="M1158.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="1104.0" y="91"></rect><text x="1131.0" y="106">'LE'</text></g><path d="M1168.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M1168.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M1188.0 102h10.0"></path><path d="M1252.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="1198.0" y="91"></rect><text x="1225.0" y="106">'GT'</text></g><path d="M1262.0 102a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><path d="M1262.0 82a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M1282.0 102h10.0"></path><path d="M1346.0 102h10.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="1292.0" y="91"></rect><text x="1319.0" y="106">'GE'</text></g><path d="M1356.0 102h10"></path></g></g><path d="M1366.0 102h10"></path><path d="M1376.0 102h10"></path><g class="non-terminal">
<path d="M1386.0 102h0.0"></path><path d="M1482.5 102h0.0"></path><rect height="22" width="96.5" x="1386.0" y="91"></rect><text x="1434.25" y="106">Unnamed 2</text></g></g><path d="M1482.5 102h20"></path><path d="M120.0 102a10 10 0 0 1 10 10v51a10 10 0 0 0 10 10"></path><g>
<path d="M140.0 173h327.5"></path><path d="M1155.0 173h327.5"></path><g>
<path d="M467.5 173h0.0"></path><path d="M655.0 173h0.0"></path><g class="non-terminal">
<path d="M467.5 173h0.0"></path><path d="M581.0 173h0.0"></path><rect height="22" width="113.5" x="467.5" y="162"></rect><text x="524.25" y="177">column name</text></g><path d="M581.0 173h10"></path><path d="M591.0 173h10"></path><g class="terminal">
<path d="M601.0 173h0.0"></path><path d="M655.0 173h0.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="601.0" y="162"></rect><text x="628.0" y="177">'in'</text></g></g><path d="M655.0 173h10"></path><path d="M665.0 173h10"></path><g>
<path d="M675.0 173h0.0"></path><path d="M1155.0 173h0.0"></path><g>
<path d="M675.0 173h0.0"></path><path d="M1089.5 173h0.0"></path><g class="terminal">
<path d="M675.0 173h0.0"></path><path d="M720.5 173h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="675.0" y="162"></rect><text x="697.75" y="177">'('</text></g><path d="M720.5 173h10"></path><path d="M730.5 173h10"></path><g>
<path d="M740.5 173h0.0"></path><path d="M1089.5 173h0.0"></path><g class="non-terminal">
<path d="M740.5 173h0.0"></path><path d="M837.0 173h0.0"></path><rect height="22" width="96.5" x="740.5" y="162"></rect><text x="788.75" y="177">Unnamed 2</text></g><path d="M837.0 173h10"></path><g>
<path d="M847.0 173h0.0"></path><path d="M1089.5 173h0.0"></path><path d="M847.0 173a10 10 0 0 0 10 -10v-23a10 10 0 0 1 10 -10"></path><g>
<path d="M867.0 130h202.5"></path></g><path d="M1069.5 130a10 10 0 0 1 10 10v23a10 10 0 0 0 10 10"></path><path d="M847.0 173h20"></path><g>
<path d="M867.0 173h0.0"></path><path d="M1069.5 173h0.0"></path><path d="M867.0 173h10"></path><g>
<path d="M877.0 173h0.0"></path><path d="M1059.5 173h0.0"></path><g>
<path d="M877.0 173h0.0"></path><path d="M943.0 173h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="66" x="877.0" y="154"></rect><g class="terminal">
<path d="M877.0 173h10.25"></path><path d="M932.75 173h10.25"></path><rect height="22" rx="10" ry="10" width="45.5" x="887.25" y="162"></rect><text x="910.0" y="177">','</text></g><g>
<path d="M877.0 146h0.0"></path><path d="M943.0 146h0.0"></path><text class="comment" x="910.0" y="151">Suppress</text></g></g><path d="M943.0 173h10"></path><path d="M953.0 173h10"></path><g class="non-terminal">
<path d="M963.0 173h0.0"></path><path d="M1059.5 173h0.0"></path><rect height="22" width="96.5" x="963.0" y="162"></rect><text x="1011.25" y="177">Unnamed 2</text></g></g><path d="M1059.5 173h10"></path><path d="M877.0 173a10 10 0 0 0 -10 10v7a10 10 0 0 0 10 10"></path><g>
<path d="M877.0 200h182.5"></path></g><path d="M1059.5 200a10 10 0 0 0 10 -10v-7a10 10 0 0 0 -10 -10"></path></g><path d="M1069.5 173h20"></path></g></g></g><path d="M1089.5 173h10"></path><path d="M1099.5 173h10"></path><g class="terminal">
<path d="M1109.5 173h0.0"></path><path d="M1155.0 173h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="1109.5" y="162"></rect><text x="1132.25" y="177">')'</text></g></g></g><path d="M1482.5 173a10 10 0 0 0 10 -10v-51a10 10 0 0 1 10 -10"></path></g><path d="M1502.5 102h20"></path><path d="M100.0 102a10 10 0 0 1 10 10v97a10 10 0 0 0 10 10"></path><g>
<path d="M120.0 219h482.25"></path><path d="M1020.25 219h482.25"></path><g>
<path d="M602.25 219h0.0"></path><path d="M789.75 219h0.0"></path><g class="non-terminal">
<path d="M602.25 219h0.0"></path><path d="M715.75 219h0.0"></path><rect height="22" width="113.5" x="602.25" y="208"></rect><text x="659.0" y="223">column name</text></g><path d="M715.75 219h10"></path><path d="M725.75 219h10"></path><g class="terminal">
<path d="M735.75 219h0.0"></path><path d="M789.75 219h0.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="735.75" y="208"></rect><text x="762.75" y="223">'in'</text></g></g><path d="M789.75 219h10"></path><path d="M799.75 219h10"></path><g>
<path d="M809.75 219h0.0"></path><path d="M1020.25 219h0.0"></path><g>
<path d="M809.75 219h0.0"></path><path d="M954.75 219h0.0"></path><g class="terminal">
<path d="M809.75 219h0.0"></path><path d="M855.25 219h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="809.75" y="208"></rect><text x="832.5" y="223">'('</text></g><path d="M855.25 219h10"></path><path d="M865.25 219h10"></path><g class="non-terminal">
<path d="M875.25 219h0.0"></path><path d="M954.75 219h0.0"></path><rect height="22" width="79.5" x="875.25" y="208"></rect><text x="915.0" y="223">Forward</text></g></g><path d="M954.75 219h10"></path><path d="M964.75 219h10"></path><g class="terminal">
<path d="M974.75 219h0.0"></path><path d="M1020.25 219h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="974.75" y="208"></rect><text x="997.5" y="223">')'</text></g></g></g><path d="M1502.5 219a10 10 0 0 0 10 -10v-97a10 10 0 0 1 10 -10"></path></g><path d="M1522.5 102h20"></path><path d="M80.0 102a10 10 0 0 1 10 10v127a10 10 0 0 0 10 10"></path><g>
<path d="M100.0 249h515.75"></path><path d="M1006.75 249h515.75"></path><g>
<path d="M615.75 249h0.0"></path><path d="M803.25 249h0.0"></path><g class="non-terminal">
<path d="M615.75 249h0.0"></path><path d="M729.25 249h0.0"></path><rect height="22" width="113.5" x="615.75" y="238"></rect><text x="672.5" y="253">column name</text></g><path d="M729.25 249h10"></path><path d="M739.25 249h10"></path><g class="terminal">
<path d="M749.25 249h0.0"></path><path d="M803.25 249h0.0"></path><rect height="22" rx="10" ry="10" width="54.0" x="749.25" y="238"></rect><text x="776.25" y="253">'is'</text></g></g><path d="M803.25 249h10"></path><g>
<path d="M813.25 249h0.0"></path><path d="M1006.75 249h0.0"></path><path d="M813.25 249h20"></path><g class="terminal">
<path d="M833.25 249h41.25"></path><path d="M945.5 249h41.25"></path><rect height="22" rx="10" ry="10" width="71.0" x="874.5" y="238"></rect><text x="910.0" y="253">'null'</text></g><path d="M986.75 249h20"></path><path d="M813.25 249a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g>
<path d="M833.25 279h0.0"></path><path d="M986.75 279h0.0"></path><g class="terminal">
<path d="M833.25 279h0.0"></path><path d="M895.75 279h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="833.25" y="268"></rect><text x="864.5" y="283">'not'</text></g><path d="M895.75 279h10"></path><path d="M905.75 279h10"></path><g class="terminal">
<path d="M915.75 279h0.0"></path><path d="M986.75 279h0.0"></path><rect height="22" rx="10" ry="10" width="71.0" x="915.75" y="268"></rect><text x="951.25" y="283">'null'</text></g></g><path d="M986.75 279a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g></g><path d="M1522.5 249a10 10 0 0 0 10 -10v-127a10 10 0 0 1 10 -10"></path></g><path d="M1542.5 102h20"></path><path d="M60.0 102a10 10 0 0 1 10 10v211a10 10 0 0 0 10 10"></path><g>
<path d="M80.0 333h597.0"></path><path d="M945.5 333h597.0"></path><g>
<path d="M677.0 333h0.0"></path><path d="M859.5 333h0.0"></path><g>
<path d="M677.0 333h0.0"></path><path d="M743.0 333h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="66" x="677.0" y="314"></rect><g class="terminal">
<path d="M677.0 333h10.25"></path><path d="M732.75 333h10.25"></path><rect height="22" rx="10" ry="10" width="45.5" x="687.25" y="322"></rect><text x="710.0" y="337">'('</text></g><g>
<path d="M677.0 306h0.0"></path><path d="M743.0 306h0.0"></path><text class="comment" x="710.0" y="311">Suppress</text></g></g><path d="M743.0 333h10"></path><path d="M753.0 333h10"></path><g class="non-terminal">
<path d="M763.0 333h0.0"></path><path d="M859.5 333h0.0"></path><rect height="22" width="96.5" x="763.0" y="322"></rect><text x="811.25" y="337">'or' term</text></g></g><path d="M859.5 333h10"></path><path d="M869.5 333h10"></path><g>
<path d="M879.5 333h0.0"></path><path d="M945.5 333h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="66" x="879.5" y="314"></rect><g class="terminal">
<path d="M879.5 333h10.25"></path><path d="M935.25 333h10.25"></path><rect height="22" rx="10" ry="10" width="45.5" x="889.75" y="322"></rect><text x="912.5" y="337">')'</text></g><g>
<path d="M879.5 306h0.0"></path><path d="M945.5 306h0.0"></path><text class="comment" x="912.5" y="311">Suppress</text></g></g></g><path d="M1542.5 333a10 10 0 0 0 10 -10v-211a10 10 0 0 1 10 -10"></path></g><path d="M1562.5 102a10 10 0 0 0 10 -10v-27a10 10 0 0 1 10 -10"></path></g><path d="M 1582.5 55 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
<div class="railroad-group">
<h1 class="railroad-heading">Unnamed 2</h1>
<div class="railroad-description"></div>
<div class="railroad-svg">
<svg class="railroad-diagram" height="278" viewBox="0 0 787.0 278" width="787.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
svg.railroad-diagram {
background-color:hsl(30,20%,95%);
}
svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill:rgba(0,0,0,0);
}
svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}
svg.railroad-diagram text.label{
text-anchor:start;
}
svg.railroad-diagram text.comment{
font:italic 12px monospace;
}
svg.railroad-diagram rect{
stroke-width:3;
stroke:black;
fill:hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}
/* ]]> */
</style><g>
<path d="M20 45v20m10 -20v20m-10 -10h20"></path></g><g>
<path d="M40 55h0.0"></path><path d="M747.0 55h0.0"></path><path d="M40.0 55h20"></path><g>
<path d="M60.0 55h0.0"></path><path d="M727.0 55h0.0"></path><path d="M60.0 55h20"></path><g>
<path d="M80.0 55h146.0"></path><path d="M561.0 55h146.0"></path><path d="M226.0 55h20"></path><g>
<path d="M246.0 55h0.0"></path><path d="M541.0 55h0.0"></path><rect class="group-box" height="38" rx="10" ry="10" width="295.0" x="246.0" y="36"></rect><g class="terminal">
<path d="M246.0 55h10.0"></path><path d="M531.0 55h10.0"></path><rect height="22" rx="10" ry="10" width="275.0" x="256.0" y="44"></rect><text x="393.5" y="59">Re:('&#91;+-&#93;?(?:\d+\.\d&#42;|\.\d+)')</text></g><g>
<path d="M246.0 28h0.0"></path><path d="M333.0 28h0.0"></path><text class="comment" x="289.5" y="33">real number</text></g></g><path d="M541.0 55h20"></path><path d="M226.0 55a10 10 0 0 1 10 10v42a10 10 0 0 0 10 10"></path><g>
<path d="M246.0 117h63.75"></path><path d="M477.25 117h63.75"></path><rect class="group-box" height="38" rx="10" ry="10" width="167.5" x="309.75" y="98"></rect><g class="terminal">
<path d="M309.75 117h10.0"></path><path d="M467.25 117h10.0"></path><rect height="22" rx="10" ry="10" width="147.5" x="319.75" y="106"></rect><text x="393.5" y="121">Re:('&#91;+-&#93;?\d+')</text></g><g>
<path d="M309.75 90h0.0"></path><path d="M417.75 90h0.0"></path><text class="comment" x="363.75" y="95">signed integer</text></g></g><path d="M541.0 117a10 10 0 0 0 10 -10v-42a10 10 0 0 1 10 -10"></path></g><path d="M707.0 55h20"></path><path d="M60.0 55a10 10 0 0 1 10 10v104a10 10 0 0 0 10 10"></path><g>
<path d="M80.0 179h0.0"></path><path d="M707.0 179h0.0"></path><rect class="group-box" height="68" rx="10" ry="10" width="627.0" x="80.0" y="160"></rect><g>
<path d="M80.0 179h0.0"></path><path d="M707.0 179h0.0"></path><path d="M80.0 179h20"></path><g>
<path d="M100.0 179h0.0"></path><path d="M687.0 179h0.0"></path><g class="terminal">
<path d="M100.0 179h0.0"></path><path d="M621.5 179h0.0"></path><rect height="22" rx="10" ry="10" width="521.5" x="100.0" y="168"></rect><text x="360.75" y="183">Re:('"(?:&#91;^"\n\r\\&#93;|(?:"")|(?:\\(?:&#91;^x&#93;|x&#91;0-9a-fA-F&#93;+)))&#42;')</text></g><path d="M621.5 179h10"></path><path d="M631.5 179h10"></path><g class="terminal">
<path d="M641.5 179h0.0"></path><path d="M687.0 179h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="641.5" y="168"></rect><text x="664.25" y="183">'"'</text></g></g><path d="M687.0 179h20"></path><path d="M80.0 179a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g>
<path d="M100.0 209h0.0"></path><path d="M687.0 209h0.0"></path><g class="terminal">
<path d="M100.0 209h0.0"></path><path d="M621.5 209h0.0"></path><rect height="22" rx="10" ry="10" width="521.5" x="100.0" y="198"></rect><text x="360.75" y="213">Re:("'(?:&#91;^'\n\r\\&#93;|(?:'')|(?:\\(?:&#91;^x&#93;|x&#91;0-9a-fA-F&#93;+)))&#42;")</text></g><path d="M621.5 209h10"></path><path d="M631.5 209h10"></path><g class="terminal">
<path d="M641.5 209h0.0"></path><path d="M687.0 209h0.0"></path><rect height="22" rx="10" ry="10" width="45.5" x="641.5" y="198"></rect><text x="664.25" y="213">"'"</text></g></g><path d="M687.0 209a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g>
<path d="M80.0 152h0.0"></path><path d="M384.0 152h0.0"></path><text class="comment" x="232.0" y="157">quotedString using single or double quotes</text></g></g><path d="M707.0 179a10 10 0 0 0 10 -10v-104a10 10 0 0 1 10 -10"></path></g><path d="M727.0 55h20"></path><path d="M40.0 55a10 10 0 0 1 10 10v172a10 10 0 0 0 10 10"></path><g class="non-terminal">
<path d="M60.0 247h276.75"></path><path d="M450.25 247h276.75"></path><rect height="22" width="113.5" x="336.75" y="236"></rect><text x="393.5" y="251">column name</text></g><path d="M727.0 247a10 10 0 0 0 10 -10v-172a10 10 0 0 1 10 -10"></path></g><path d="M 747.0 55 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,184 @@
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath(".."))
from pyparsing import __version__ as pyparsing_version
# -- Project information -----------------------------------------------------
project = "PyParsing"
copyright = "2018-2024, Paul T. McGuire"
author = "Paul T. McGuire"
# The short X.Y version
version = pyparsing_version
# The full version, including alpha/beta/rc tags
release = pyparsing_version
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffixes:
source_suffix = {'.rst': 'restructuredtext'}
# The master toctree document.
master_doc = "index"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "classic"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = "PyParsingdoc"
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(
master_doc,
"PyParsing.tex",
"PyParsing Documentation",
"Paul T. McGuire",
"manual",
),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "pyparsing", "PyParsing Documentation", [author], 1)]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"PyParsing",
"PyParsing Documentation",
author,
"PyParsing",
"Python PEG parsing library.",
"Miscellaneous",
),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ["search.html"]
# -- Extension configuration -------------------------------------------------

View File

@@ -0,0 +1,27 @@
.. PyParsing documentation master file, created by
sphinx-quickstart on Mon Nov 19 15:06:52 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to PyParsing's documentation!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Release v\ |version|
.. toctree::
:maxdepth: 2
:caption: Contents:
HowToUsePyparsing
whats_new_in_3_2
whats_new_in_3_1
whats_new_in_3_0_0
modules
CODE_OF_CONDUCT
Indices and tables
~~~~~~~~~~~~~~~~~~
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1 @@
sphinx-build.exe -E -b html . _build

View File

@@ -0,0 +1,7 @@
pyparsing
=========
.. toctree::
:maxdepth: 4
pyparsing

View File

@@ -0,0 +1,7 @@
pyparsing module
================
.. automodule:: pyparsing
:members:
:special-members:
:show-inheritance:

View File

@@ -0,0 +1,352 @@
@startuml
'https://plantuml.com/class-diagram
top to bottom direction
hide circle
hide empty members
'hide empty methods
skinparam groupInheritance 3
note as N1
Class Diagram
---
<size 18>pyparsing 3.0.9
<size 18>May, 2022
end note
N1 <-[hidden]- unicode
package core {
class globals {
quoted_string
sgl_quoted_string
dbl_quoted_string
counted_array()
match_previous_literal()
match_previous_expr()
one_of()
dict_of()
original_text_for()
ungroup()
nested_expr()
make_html_tags()
make_xml_tags()
common_html_entity
replace_html_entity()
class OpAssoc
infix_notation()
class IndentedBlock
c_style_comment
html_comment
rest_of_line
dbl_slash_comment
cpp_style_comment
java_style_comment
python_style_comment
match_only_at_col()
replace_with()
remove_quotes()
with_attribute()
with_class()
trace_parse_action()
condition_as_parse_action()
srange()
token_map()
autoname_elements()
}
class ParseResults {
class List
{static}from_dict()
__getitem__()
__setitem__()
__contains__()
__len__()
__bool__()
__iter__()
__reversed__()
__getattr__()
__add__()
__getstate__()
__setstate__()
__getnewargs__()
__dir__()
as_dict()
as_list()
dump()
get_name()
items()
keys()
values()
haskeys()
pop()
get()
insert()
append()
extend()
clear()
copy()
get_name()
pprint()
}
class ParseBaseException #ffffff {
{static} explain_exception()
explain()
mark_input_line()
line
lineno
column
parser_element
}
class ParseException
class ParseFatalException
class ParseSyntaxException
ParseBaseException <|-- ParseException
ParseBaseException <|-- ParseFatalException
ParseFatalException <|-- ParseSyntaxException
class ParserElement {
name: str
results_name: str
---
{classifier} enable_packrat()
{classifier} enable_left_recursion()
{classifier} disable_memoization()
{classifier} set_default_whitespace_chars()
{classifier} inline_literals_using()
{classifier} reset_cache()
{static} verbose_stacktrace
suppress_warning()
operator + () -> And
operator - () -> And.ErrorStop
operator | () -> MatchFirst
operator ^ () -> Or
operator & () -> Each
operator ~ () -> NotAny
operator [] () -> _MultipleMatch
operator () () [set_results_name()]
add_condition()
add_parse_action()
set_parse_action()
copy()
ignore(expr)
leave_whitespace()
parse_with_tabs()
suppress()
set_break()
set_debug()
set_debug_actions()
set_name()
set_results_name()
parse_string()
scan_string()
search_string()
transform_string()
split()
run_tests()
recurse()
create_diagram()
}
class Token #ffffff
class ParseExpression #ffffff {
exprs: list[ParserElement]
}
class ParseElementEnhance #ffffff {
expr: ParserElement
}
class _PositionToken #ffffff
class Char
class White
class Word {
'Word(init_chars: str, body_chars: str, min: int, \nmax: int, exact: int, as_keyword: bool, exclude_chars: str)
}
class Keyword {
{static} set_default_keyword_chars(chars: str)
}
class CaselessKeyword
class Empty
class Literal
class Regex
class NoMatch
class CharsNotIn
class QuotedString
class And
class Or
class MatchFirst
class Each
class OneOrMore
class ZeroOrMore
class DelimitedList
class SkipTo
class Group
class Forward {
operator <<= ()
}
class LineStart
class LineEnd
class StringStart
class StringEnd
class WordStart
class WordEnd
class _MultipleMatch #ffffff
class FollowedBy
class PrecededBy
class AtLineStart
class AtStringStart
class TokenConverter #ffffff
class Located
class Opt
class Combine
class Group
class Dict
class Suppress
ParserElement <|-- Token
ParserElement <|----- ParseExpression
Token <|-- _PositionToken
ParserElement <|----- ParseElementEnhance
'ParseElementEnhance ---> ParserElement
'ParseExpression ---> "*" ParserElement
Token <|-- Empty
Token <|-- CloseMatch
Token <|-- NoMatch
Token <|-- Literal
Token <|-- Word
Token <|---- Keyword
Token <|--- Regex
Token <|--- CharsNotIn
Token <|-- White
Token <|---- QuotedString
Word <|-- Char
Literal <|-- CaselessLiteral
Keyword <|-- CaselessKeyword
ParseExpression <|-- And
ParseExpression <|-- Or
ParseExpression <|-- MatchFirst
ParseExpression <|-- Each
ParseElementEnhance <|-- SkipTo
ParseElementEnhance <|--- Forward
ParseElementEnhance <|-- Located
ParseElementEnhance <|--- _MultipleMatch
_MultipleMatch <|-- OneOrMore
_MultipleMatch <|-- ZeroOrMore
ParseElementEnhance <|-- DelimitedList
ParseElementEnhance <|--- NotAny
ParseElementEnhance <|--- FollowedBy
ParseElementEnhance <|--- PrecededBy
ParseElementEnhance <|-- Opt
ParseElementEnhance <|--- TokenConverter
ParseElementEnhance <|-- AtStringStart
ParseElementEnhance <|-- AtLineStart
TokenConverter <|-- Group
TokenConverter <|-- Dict
TokenConverter <|-- Suppress
TokenConverter <|-- Combine
_PositionToken <|-- LineStart
_PositionToken <|-- LineEnd
_PositionToken <|-- WordStart
_PositionToken <|-- WordEnd
_PositionToken <|-- StringStart
_PositionToken <|-- StringEnd
}
package common {
class " " {
comma_separated_list
convert_to_integer()
convert_to_float()
integer
hex_integer
signed_integer
fraction
mixed_integer
real
sci_real
number
fnumber
identifier
ipv4_address
ipv6_address
mac_address
convert_to_date()
convert_to_datetime()
iso8601_date
iso8601_datetime
uuid
strip_html_tags()
upcase_tokens()
downcase_tokens()
url
}
}
package unicode {
class unicode_set {
printables: str
alphas: str
nums: str
alphanums: str
identchars: str
identbodychars: str
}
class Latin1
class LatinA
class LatinB
class BasicMultilingualPlane
class Chinese
class Thai
class Japanese {
class Kanji
class Hiragana
class Katakana
}
class Greek
class Hangul
class Arabic
class Devanagari
class Hebrew
class Cyrillic
unicode_set <|-- Latin1
unicode_set <|--- LatinA
unicode_set <|-- LatinB
unicode_set <|---- BasicMultilingualPlane
unicode_set <|-- Greek
unicode_set <|--- Cyrillic
unicode_set <|--- Chinese
unicode_set <|--- Japanese
unicode_set <|--- Hangul
Chinese <|-- CJK
Japanese <|-- CJK
Hangul <|-- CJK
unicode_set <|-- Thai
unicode_set <|-- Arabic
unicode_set <|-- Hebrew
unicode_set <|--- Devanagari
}
ParserElement <-[hidden] ParseBaseException
'ParseBaseException <-[hidden] globals
'globals <-[hidden] ParserElement
CJK <-[hidden]-- common
@enduml

View File

@@ -0,0 +1,816 @@
=============================
What's New in Pyparsing 3.0.0
=============================
:author: Paul McGuire
:date: May, 2022
:abstract: This document summarizes the changes made
in the 3.0.0 release of pyparsing.
(Updated to reflect changes up to 3.0.10)
.. sectnum:: :depth: 4
.. contents:: :depth: 4
New Features
============
PEP-8 naming
------------
This release of pyparsing will (finally!) include PEP-8 compatible names and arguments.
Backward-compatibility is maintained by defining synonyms using the old camelCase names
pointing to the new snake_case names.
This code written using non-PEP8 names::
wd = pp.Word(pp.printables, excludeChars="$")
wd_list = pp.delimitedList(wd, delim="$")
print(wd_list.parseString("dkls$134lkjk$lsd$$").asList())
can now be written as::
wd = pp.Word(pp.printables, exclude_chars="$")
wd_list = pp.delimited_list(wd, delim="$")
print(wd_list.parse_string("dkls$134lkjk$lsd$$").as_list())
Pyparsing 3.0 will run both versions of this example.
New code should be written using the PEP-8 compatible names. The compatibility
synonyms will be removed in a future version of pyparsing.
Railroad diagramming
--------------------
An excellent new enhancement is the new railroad diagram
generator for documenting pyparsing parsers.::
import pyparsing as pp
# define a simple grammar for parsing street addresses such
# as "123 Main Street"
# number word...
number = pp.Word(pp.nums).set_name("number")
name = pp.Word(pp.alphas).set_name("word")[1, ...]
parser = number("house_number") + name("street")
parser.set_name("street address")
# construct railroad track diagram for this parser and
# save as HTML
parser.create_diagram('parser_rr_diag.html')
``create_diagram`` accepts these named arguments:
- ``vertical`` (int) - threshold for formatting multiple alternatives vertically
instead of horizontally (default=3)
- ``show_results_names`` - bool flag whether diagram should show annotations for
defined results names
- ``show_groups`` - bool flag whether groups should be highlighted with an unlabeled surrounding box
- ``embed`` - bool flag whether generated HTML should omit ``<HEAD>``, ``<BODY>``, and ``<DOCTYPE>`` tags to embed
the resulting HTML in an enclosing HTML source (new in 3.0.10)
- ``head`` - str containing additional HTML to insert into the ``<HEAD>`` section of the
generated code; can be used to insert custom CSS styling
- ``body`` - str containing additional HTML to insert at the beginning of the ``<BODY>`` section of the
generated code
To use this new feature, install the supporting diagramming packages using::
pip install pyparsing[diagrams]
See more in the examples directory: ``make_diagram.py`` and ``railroad_diagram_demo.py``.
(Railroad diagram enhancement contributed by Michael Milton)
Support for left-recursive parsers
----------------------------------
Another significant enhancement in 3.0 is support for left-recursive (LR)
parsers. Previously, given a left-recursive parser, pyparsing would
recurse repeatedly until hitting the Python recursion limit. Following
the methods of the Python PEG parser, pyparsing uses a variation of
packrat parsing to detect and handle left-recursion during parsing.::
import pyparsing as pp
pp.ParserElement.enable_left_recursion()
# a common left-recursion definition
# define a list of items as 'list + item | item'
# BNF:
# item_list := item_list item | item
# item := word of alphas
item_list = pp.Forward()
item = pp.Word(pp.alphas)
item_list <<= item_list + item | item
item_list.run_tests("""\
To parse or not to parse that is the question
""")
Prints::
['To', 'parse', 'or', 'not', 'to', 'parse', 'that', 'is', 'the', 'question']
See more examples in ``left_recursion.py`` in the pyparsing examples directory.
(LR parsing support contributed by Max Fischer)
Packrat/memoization enable and disable methods
----------------------------------------------
As part of the implementation of left-recursion support, new methods have been added
to enable and disable packrat parsing.
====================== =======================================================
Name Description
---------------------- -------------------------------------------------------
enable_packrat Enable packrat parsing (with specified cache size)
enable_left_recursion Enable left-recursion cache
disable_memoization Disable all internal parsing caches
====================== =======================================================
Type annotations on all public methods
--------------------------------------
Python 3.6 and upward compatible type annotations have been added to most of the
public methods in pyparsing. This should facilitate developing pyparsing-based
applications using IDEs for development-time type checking.
New string constants ``identchars`` and ``identbodychars`` to help in defining identifier Word expressions
----------------------------------------------------------------------------------------------------------
Two new module-level strings have been added to help when defining identifiers,
``identchars`` and ``identbodychars``.
Instead of writing::
import pyparsing as pp
identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_")
you will be able to write::
identifier = pp.Word(pp.identchars, pp.identbodychars)
Those constants have also been added to all the Unicode string classes::
import pyparsing as pp
ppu = pp.pyparsing_unicode
cjk_identifier = pp.Word(ppu.CJK.identchars, ppu.CJK.identbodychars)
greek_identifier = pp.Word(ppu.Greek.identchars, ppu.Greek.identbodychars)
Refactored/added diagnostic flags
---------------------------------
Expanded ``__diag__`` and ``__compat__`` to actual classes instead of
just namespaces, to add some helpful behavior:
- ``pyparsing.enable_diag()`` and ``pyparsing.disable_diag()`` methods to give extra
help when setting or clearing flags (detects invalid
flag names, detects when trying to set a ``__compat__`` flag
that is no longer settable). Use these methods now to
set or clear flags, instead of directly setting to ``True`` or
``False``::
import pyparsing as pp
pp.enable_diag(pp.Diagnostics.warn_multiple_tokens_in_named_alternation)
- ``pyparsing.enable_all_warnings()`` is another helper that sets
all "warn*" diagnostics to ``True``::
pp.enable_all_warnings()
- added support for calling ``enable_all_warnings()`` if warnings are enabled
using the Python ``-W`` switch, or setting a non-empty value to the environment
variable ``PYPARSINGENABLEALLWARNINGS``. (If using ``-Wd`` for testing, but
wishing to disable pyparsing warnings, add ``-Wi:::pyparsing``.)
- added new warning, ``warn_on_match_first_with_lshift_operator`` to
warn when using ``'<<'`` with a ``'|'`` ``MatchFirst`` operator,
which will
create an unintended expression due to precedence of operations.
Example: This statement will erroneously define the ``fwd`` expression
as just ``expr_a``, even though ``expr_a | expr_b`` was intended,
since ``'<<'`` operator has precedence over ``'|'``::
fwd << expr_a | expr_b
To correct this, use the ``'<<='`` operator (preferred) or parentheses
to override operator precedence::
fwd <<= expr_a | expr_b
or::
fwd << (expr_a | expr_b)
- ``warn_on_parse_using_empty_Forward`` - warns that a ``Forward``
has been included in a grammar, but no expression was
attached to it using ``'<<='`` or ``'<<'``
- ``warn_on_assignment_to_Forward`` - warns that a ``Forward`` has
been created, but was probably later overwritten by
erroneously using ``'='`` instead of ``'<<='`` (this is a common
mistake when using Forwards)
(**currently not working on PyPy**)
Support for yielding native Python ``list`` and ``dict`` types in place of ``ParseResults``
-------------------------------------------------------------------------------------------
To support parsers that are intended to generate native Python collection
types such as lists and dicts, the ``Group`` and ``Dict`` classes now accept an
additional boolean keyword argument ``aslist`` and ``asdict`` respectively. See
the ``jsonParser.py`` example in the ``pyparsing/examples`` source directory for
how to return types as ``ParseResults`` and as Python collection types, and the
distinctions in working with the different types.
In addition parse actions that must return a value of list type (which would
normally be converted internally to a ``ParseResults``) can override this default
behavior by returning their list wrapped in the new ``ParseResults.List`` class::
# this parse action tries to return a list, but pyparsing
# will convert to a ParseResults
def return_as_list_but_still_get_parse_results(tokens):
return tokens.asList()
# this parse action returns the tokens as a list, and pyparsing will
# maintain its list type in the final parsing results
def return_as_list(tokens):
return ParseResults.List(tokens.asList())
This is the mechanism used internally by the ``Group`` class when defined
using ``aslist=True``.
New Located class to replace ``locatedExpr`` helper method
----------------------------------------------------------
The new ``Located`` class will replace the current ``locatedExpr`` method for
marking parsed results with the start and end locations of the parsed data in
the input string. ``locatedExpr`` had several bugs, and returned its results
in a hard-to-use format (location data and results names were mixed in with
the located expression's parsed results, and wrapped in an unnecessary extra
nesting level).
For this code::
wd = Word(alphas)
for match in locatedExpr(wd).search_string("ljsdf123lksdjjf123lkkjj1222"):
print(match)
the docs for ``locatedExpr`` show this output::
[[0, 'ljsdf', 5]]
[[8, 'lksdjjf', 15]]
[[18, 'lkkjj', 23]]
The parsed values and the start and end locations are merged into a single
nested ``ParseResults`` (and any results names in the parsed values are also
merged in with the start and end location names).
Using ``Located``, the output is::
[0, ['ljsdf'], 5]
[8, ['lksdjjf'], 15]
[18, ['lkkjj'], 23]
With ``Located``, the parsed expression values and results names are kept
separate in the second parsed value, and there is no extra grouping level
on the whole result.
The existing ``locatedExpr`` is retained for backward-compatibility, but will be
deprecated in a future release.
New ``AtLineStart`` and ``AtStringStart`` classes
-------------------------------------------------
As part of fixing some matching behavior in ``LineStart`` and ``StringStart``, two new
classes have been added: ``AtLineStart`` and ``AtStringStart``.
``LineStart`` and ``StringStart`` can be treated as separate elements, including whitespace skipping.
``AtLineStart`` and ``AtStringStart`` enforce that an expression starts exactly at column 1, with no
leading whitespace.::
(LineStart() + Word(alphas)).parseString("ABC") # passes
(LineStart() + Word(alphas)).parseString(" ABC") # passes
AtLineStart(Word(alphas)).parseString(" ABC") # fails
[This is a fix to behavior that was added in 3.0.0, but was actually a regression from 2.4.x.]
New ``IndentedBlock`` class to replace ``indentedBlock`` helper method
----------------------------------------------------------------------
The new ``IndentedBlock`` class will replace the current ``indentedBlock`` method
for defining indented blocks of text, similar to Python source code. Using
``IndentedBlock``, the expression instance itself keeps track of the indent stack,
so a separate external ``indentStack`` variable is no longer required.
Here is a simple example of an expression containing an alphabetic key, followed
by an indented list of integers::
integer = pp.Word(pp.nums)
group = pp.Group(pp.Char(pp.alphas) + pp.IndentedBlock(integer))
parses::
A
100
101
B
200
201
as::
[['A', [100, 101]], ['B', [200, 201]]]
By default, the results returned from the ``IndentedBlock`` are grouped.
``IndentedBlock`` may also be used to define a recursive indented block (containing nested
indented blocks).
The existing ``indentedBlock`` is retained for backward-compatibility, but will be
deprecated in a future release.
Shortened tracebacks
--------------------
Cleaned up default tracebacks when getting a ``ParseException`` when calling
``parse_string``. Exception traces should now stop at the call in ``parse_string``,
and not include the internal pyparsing traceback frames. (If the full traceback
is desired, then set ``ParserElement.verbose_traceback`` to ``True``.)
Improved debug logging
----------------------
Debug logging has been improved by:
- Including ``try/match/fail`` logging when getting results from the
packrat cache (previously cache hits did not show debug logging).
Values returned from the packrat cache are marked with an '*'.
- Improved fail logging, showing the failed expression, text line, and marker where
the failure occurred.
- Adding ``with_line_numbers`` to ``pyparsing_testing``. Use ``with_line_numbers``
to visualize the data being parsed, with line and column numbers corresponding
to the values output when enabling ``set_debug()`` on an expression::
data = """\
A
100"""
expr = pp.Word(pp.alphanums).set_name("word").set_debug()
print(ppt.with_line_numbers(data))
expr[...].parseString(data)
prints::
. 1
1234567890
1: A
2: 100
Match word at loc 3(1,4)
A
^
Matched word -> ['A']
Match word at loc 11(2,7)
100
^
Matched word -> ['100']
New / improved examples
-----------------------
- ``number_words.py`` includes a parser/evaluator to parse ``"forty-two"``
and return ``42``. Also includes example code to generate a railroad
diagram for this parser.
- ``BigQueryViewParser.py`` added to examples directory, submitted
by Michael Smedberg.
- ``booleansearchparser.py`` added to examples directory, submitted
by xecgr. Builds on searchparser.py, adding support for '*'
wildcards and non-Western alphabets.
- Improvements in ``select_parser.py``, to include new SQL syntax
from SQLite, submitted by Robert Coup.
- Off-by-one bug found in the ``roman_numerals.py`` example, a bug
that has been there for about 14 years! Submitted by
Jay Pedersen.
- A simplified Lua parser has been added to the examples
(``lua_parser.py``).
- Demonstration of defining a custom Unicode set for cuneiform
symbols, as well as simple Cuneiform->Python conversion is included
in ``cuneiform_python.py``.
- Fixed bug in ``delta_time.py`` example, when using a quantity
of seconds/minutes/hours/days > 999.
Other new features
------------------
- ``url`` expression added to ``pyparsing_common``, with named fields for
common fields in URLs. See the updated ``urlExtractorNew.py`` file in the
``examples`` directory. Submitted by Wolfgang Fahl.
- ``DelimitedList`` now supports an additional flag ``allow_trailing_delim``,
to optionally parse an additional delimiter at the end of the list.
Submitted by Kazantcev Andrey.
- Added global method ``autoname_elements()`` to call ``set_name()`` on all locally
defined ``ParserElements`` that haven't been explicitly named using ``set_name()``, using
their local variable name. Useful for setting names on multiple elements when
creating a railroad diagram::
a = pp.Literal("a")
b = pp.Literal("b").set_name("bbb")
pp.autoname_elements()
``a`` will get named "a", while ``b`` will keep its name "bbb".
- Enhanced default strings created for ``Word`` expressions, now showing
string ranges if possible. ``Word(alphas)`` would formerly
print as ``W:(ABCD...)``, now prints as ``W:(A-Za-z)``.
- Better exception messages to show full word where an exception occurred.::
Word(alphas)[...].parse_string("abc 123", parse_all=True)
Was::
pyparsing.ParseException: Expected end of text, found '1' (at char 4), (line:1, col:5)
Now::
pyparsing.exceptions.ParseException: Expected end of text, found '123' (at char 4), (line:1, col:5)
- Using ``...`` for ``SkipTo`` can now be wrapped in ``Suppress`` to suppress
the skipped text from the returned parse results.::
source = "lead in START relevant text END trailing text"
start_marker = Keyword("START")
end_marker = Keyword("END")
find_body = Suppress(...) + start_marker + ... + end_marker
print(find_body.parse_string(source).dump())
Prints::
['START', 'relevant text ', 'END']
- _skipped: ['relevant text ']
- Added ``ignore_whitespace(recurse:bool = True)`` and added a
``recurse`` argument to ``leave_whitespace``, both added to provide finer
control over pyparsing's whitespace skipping. Contributed by
Michael Milton.
- Added ``ParserElement.recurse()`` method to make it simpler for
grammar utilities to navigate through the tree of expressions in
a pyparsing grammar.
- The ``repr()`` string for ``ParseResults`` is now of the form::
ParseResults([tokens], {named_results})
The previous form omitted the leading ``ParseResults`` class name,
and was easily misinterpreted as a ``tuple`` containing a ``list`` and
a ``dict``.
- Minor reformatting of output from ``run_tests`` to make embedded
comments more visible.
- New ``pyparsing_test`` namespace, assert methods and classes added to support writing
unit tests.
- ``assertParseResultsEquals``
- ``assertParseAndCheckList``
- ``assertParseAndCheckDict``
- ``assertRunTestResults``
- ``assertRaisesParseException``
- ``reset_pyparsing_context`` context manager, to restore pyparsing
config settings
- Enhanced error messages and error locations when parsing fails on
the ``Keyword`` or ``CaselessKeyword`` classes due to the presence of a
preceding or trailing keyword character.
- Enhanced the ``Regex`` class to be compatible with re's compiled with the
re-equivalent ``regex`` module. Individual expressions can be built with
regex compiled expressions using::
import pyparsing as pp
import regex
# would use regex for this expression
integer_parser = pp.Regex(regex.compile(r'\d+'))
- Fixed handling of ``ParseSyntaxExceptions`` raised as part of ``Each``
expressions, when sub-expressions contain ``'-'`` backtrack
suppression.
- Potential performance enhancement when parsing ``Word``
expressions built from ``pyparsing_unicode`` character sets. ``Word`` now
internally converts ranges of consecutive characters to regex
character ranges (converting ``"0123456789"`` to ``"0-9"`` for instance).
- Added a caseless parameter to the ``CloseMatch`` class to allow for casing to be
ignored when checking for close matches. Contributed by Adrian Edwards.
API Changes
===========
- [Note added in pyparsing 3.0.7, reflecting a change in 3.0.0]
Fixed a bug in the ``ParseResults`` class implementation of ``__bool__``, which
would formerly return ``False`` if the ``ParseResults`` item list was empty, even if it
contained named results. Now ``ParseResults`` will return ``True`` if either the item
list is not empty *or* if the named results list is not empty::
# generate an empty ParseResults by parsing a blank string with a ZeroOrMore
result = Word(alphas)[...].parse_string("")
print(result.as_list())
print(result.as_dict())
print(bool(result))
# add a results name to the result
result["name"] = "empty result"
print(result.as_list())
print(result.as_dict())
print(bool(result))
Prints::
[]
{}
False
[]
{'name': 'empty result'}
True
In previous versions, the second call to ``bool()`` would return ``False``.
- [Note added in pyparsing 3.0.4, reflecting a change in 3.0.0]
The ``ParseResults`` class now uses ``__slots__`` to pre-define instance attributes. This
means that code written like this (which was allowed in pyparsing 2.4.7)::
result = Word(alphas).parseString("abc")
result.xyz = 100
now raises this Python exception::
AttributeError: 'ParseResults' object has no attribute 'xyz'
To add new attribute values to ParseResults object in 3.0.0 and later, you must
assign them using indexed notation::
result["xyz"] = 100
You will still be able to access this new value as an attribute or as an
indexed item.
- ``enable_diag()`` and ``disable_diag()`` methods to
enable specific diagnostic values (instead of setting them
to ``True`` or ``False``). ``enable_all_warnings()`` has
also been added.
- ``counted_array`` formerly returned its list of items nested
within another list, so that accessing the items required
indexing the 0'th element to get the actual list. This
extra nesting has been removed. In addition, if there are
other metadata fields parsed between the count and the
list items, they can be preserved in the resulting list
if given results names.
- ``ParseException.explain()`` is now an instance method of
``ParseException``::
expr = pp.Word(pp.nums) * 3
try:
expr.parse_string("123 456 A789")
except pp.ParseException as pe:
print(pe.explain(depth=0))
prints::
123 456 A789
^
ParseException: Expected W:(0-9), found 'A789' (at char 8), (line:1, col:9)
To run explain against other exceptions, use
``ParseException.explain_exception()``.
- Debug actions now take an added keyword argument ``cache_hit``.
Now that debug actions are called for expressions matched in the
packrat parsing cache, debug actions are now called with this extra
flag, set to ``True``. For custom debug actions, it is necessary to add
support for this new argument.
- ``ZeroOrMore`` expressions that have results names will now
include empty lists for their name if no matches are found.
Previously, no named result would be present. Code that tested
for the presence of any expressions using ``"if name in results:"``
will now always return ``True``. This code will need to change to
``"if name in results and results[name]:"`` or just
``"if results[name]:"``. Also, any parser unit tests that check the
``as_dict()`` contents will now see additional entries for parsers
having named ``ZeroOrMore`` expressions, whose values will be ``[]``.
- ``ParserElement.set_default_whitespace_chars`` will now update
whitespace characters on all built-in expressions defined
in the pyparsing module.
- ``camelCase`` names have been converted to PEP-8 ``snake_case`` names.
Method names and arguments that were camel case (such as ``parseString``)
have been replaced with PEP-8 snake case versions (``parse_string``).
Backward-compatibility synonyms for all names and arguments have
been included, to allow parsers written using the old names to run
without change. The synonyms will be removed in a future release.
New parser code should be written using the new PEP-8 snake case names.
============================== ================================
Name Previous name
------------------------------ --------------------------------
ParserElement
- parse_string parseString
- scan_string scanString
- search_string searchString
- transform_string transformString
- add_condition addCondition
- add_parse_action addParseAction
- can_parse_next canParseNext
- default_name defaultName
- enable_left_recursion enableLeftRecursion
- enable_packrat enablePackrat
- ignore_whitespace ignoreWhitespace
- inline_literals_using inlineLiteralsUsing
- parse_file parseFile
- leave_whitespace leaveWhitespace
- parse_string parseString
- parse_with_tabs parseWithTabs
- reset_cache resetCache
- run_tests runTests
- scan_string scanString
- search_string searchString
- set_break setBreak
- set_debug setDebug
- set_debug_actions setDebugActions
- set_default_whitespace_chars setDefaultWhitespaceChars
- set_fail_action setFailAction
- set_name setName
- set_parse_action setParseAction
- set_results_name setResultsName
- set_whitespace_chars setWhitespaceChars
- transform_string transformString
- try_parse tryParse
ParseResults
- as_list asList
- as_dict asDict
- get_name getName
ParseBaseException
- parser_element parserElement
any_open_tag anyOpenTag
any_close_tag anyCloseTag
c_style_comment cStyleComment
common_html_entity commonHTMLEntity
condition_as_parse_action conditionAsParseAction
counted_array countedArray
cpp_style_comment cppStyleComment
dbl_quoted_string dblQuotedString
dbl_slash_comment dblSlashComment
DelimitedList delimitedList
DelimitedList delimited_list
dict_of dictOf
html_comment htmlComment
infix_notation infixNotation
java_style_comment javaStyleComment
line_end lineEnd
line_start lineStart
make_html_tags makeHTMLTags
make_xml_tags makeXMLTags
match_only_at_col matchOnlyAtCol
match_previous_expr matchPreviousExpr
match_previous_literal matchPreviousLiteral
nested_expr nestedExpr
null_debug_action nullDebugAction
one_of oneOf
OpAssoc opAssoc
original_text_for originalTextFor
python_style_comment pythonStyleComment
quoted_string quotedString
remove_quotes removeQuotes
replace_html_entity replaceHTMLEntity
replace_with replaceWith
rest_of_line restOfLine
sgl_quoted_string sglQuotedString
string_end stringEnd
string_start stringStart
token_map tokenMap
trace_parse_action traceParseAction
unicode_string unicodeString
with_attribute withAttribute
with_class withClass
============================== ================================
Discontinued Features
=====================
Python 2.x no longer supported
------------------------------
Removed Py2.x support and other deprecated features. Pyparsing
now requires Python 3.6.8 or later. If you are using an earlier
version of Python, you must use a Pyparsing 2.4.x version.
Other discontinued features
---------------------------
- ``ParseResults.asXML()`` - if used for debugging, switch
to using ``ParseResults.dump()``; if used for data transfer,
use ``ParseResults.as_dict()`` to convert to a nested Python
dict, which can then be converted to XML or JSON or
other transfer format
- ``operatorPrecedence`` synonym for ``infixNotation`` -
convert to calling ``infix_notation``
- ``commaSeparatedList`` - convert to using
``pyparsing_common.comma_separated_list``
- ``upcaseTokens`` and ``downcaseTokens`` - convert to using
``pyparsing_common.upcase_tokens`` and ``downcase_tokens``
- ``__compat__.collect_all_And_tokens`` will not be settable to
``False`` to revert to pre-2.3.1 results name behavior -
review use of names for ``MatchFirst`` and Or expressions
containing ``And`` expressions, as they will return the
complete list of parsed tokens, not just the first one.
Use ``pyparsing.enable_diag(pyparsing.Diagnostics.warn_multiple_tokens_in_named_alternation)``
to help identify those expressions in your parsers that
will have changed as a result.
- Removed support for running ``python setup.py test``. The setuptools
maintainers consider the ``test`` command deprecated (see
<https://github.com/pypa/setuptools/issues/1684>). To run the Pyparsing tests,
use the command ``tox``.
Fixed Bugs
==========
- [Reverted in 3.0.2]Fixed issue when ``LineStart()`` expressions would match input text that was not
necessarily at the beginning of a line.
[The previous behavior was the correct behavior, since it represents the ``LineStart`` as its own
matching expression. ``ParserElements`` that must start in column 1 can be wrapped in the new
``AtLineStart`` class.]
- Fixed bug in regex definitions for ``real`` and ``sci_real`` expressions in
``pyparsing_common``.
- Fixed ``FutureWarning`` raised beginning in Python 3.7 for ``Regex`` expressions
containing '[' within a regex set.
- Fixed bug in ``PrecededBy`` which caused infinite recursion.
- Fixed bug in ``CloseMatch`` where end location was incorrectly
computed; and updated ``partial_gene_match.py`` example.
- Fixed bug in ``indentedBlock`` with a parser using two different
types of nested indented blocks with different indent values,
but sharing the same indent stack.
- Fixed bug in ``Each`` when using ``Regex``, when ``Regex`` expression would
get parsed twice.
- Fixed bugs in ``Each`` when passed ``OneOrMore`` or ``ZeroOrMore`` expressions:
. first expression match could be enclosed in an extra nesting level
. out-of-order expressions now handled correctly if mixed with required expressions
. results names are maintained correctly for these expression
- Fixed ``FutureWarning`` that sometimes is raised when ``'['`` passed as a
character to ``Word``.
- Fixed debug logging to show failure location after whitespace skipping.
- Fixed ``ParseFatalExceptions`` failing to override normal exceptions or expression
matches in ``MatchFirst`` expressions.
- Fixed bug in which ``ParseResults`` replaces a collection type value with an invalid
type annotation (as a result of changed behavior in Python 3.9).
- Fixed bug in ``ParseResults`` when calling ``__getattr__`` for special double-underscored
methods. Now raises ``AttributeError`` for non-existent results when accessing a
name starting with '__'.
- Fixed bug in ``Located`` class when used with a results name.
- Fixed bug in ``QuotedString`` class when the escaped quote string is not a
repeated character.
Acknowledgments
===============
And finally, many thanks to those who helped in the restructuring
of the pyparsing code base as part of this release. Pyparsing now
has more standard package structure, more standard unit tests,
and more standard code formatting (using black). Special thanks
to jdufresne, klahnakoski, mattcarmody, ckeygusuz,
tmiguelt, and toonarmycaptain to name just a few.
Thanks also to Michael Milton and Max Fischer, who added some
significant new features to pyparsing.

View File

@@ -0,0 +1,313 @@
=============================
What's New in Pyparsing 3.1.0
=============================
:author: Paul McGuire
:date: October, 2024
:abstract: This document summarizes the changes made
in the 3.1.x releases of pyparsing.
.. sectnum:: :depth: 4
.. contents:: :depth: 4
Supported Python versions
=========================
- Added support for Python 3.12.
- All internal string expressions using '%' string interpolation and ``str.format()``
converted to f-strings.
New Features
============
- Added new ``Tag`` ParserElement, for inserting metadata into the parsed results.
This allows a parser to add metadata or annotations to the parsed tokens.
The ``Tag`` element also accepts an optional ``value`` parameter, defaulting to ``True``.
See the new ``tag_metadata.py`` example in the ``examples`` directory.
Example::
# add tag indicating mood
end_punc = "." | ("!" + Tag("enthusiastic")))
greeting = "Hello" + Word(alphas) + end_punc
result = greeting.parse_string("Hello World.")
print(result.dump())
result = greeting.parse_string("Hello World!")
print(result.dump())
prints::
['Hello', 'World', '.']
['Hello', 'World', '!']
- enthusiastic: True
- Extended ``expr[]`` notation for repetition of ``expr`` to accept a
slice, where the slice's stop value indicates a ``stop_on``
expression::
test = "BEGIN aaa bbb ccc END"
BEGIN, END = Keyword.using_each("BEGIN END".split())
body_word = Word(alphas)
# new slice syntax support
expr = BEGIN + Group(body_word[...:END]) + END
# equivalent to
# expr = BEGIN + Group(ZeroOrMore(body_word, stop_on=END)) + END
print(expr.parse_string(test))
Prints::
['BEGIN', ['aaa', 'bbb', 'ccc'], 'END']
- Added new class method ``ParserElement.using_each``, to simplify code
that creates a sequence of ``Literals``, ``Keywords``, or other ``ParserElement``
subclasses.
For instance, to define suppressible punctuation, you would previously
write::
LPAR, RPAR, LBRACE, RBRACE, SEMI = map(Suppress, "(){};")
You can now write::
LPAR, RPAR, LBRACE, RBRACE, SEMI = Suppress.using_each("(){};")
``using_each`` will also accept optional keyword args, which it will
pass through to the class initializer. Here is an expression for
single-letter variable names that might be used in an algebraic
expression::
algebra_var = MatchFirst(
Char.using_each(string.ascii_lowercase, as_keyword=True)
)
- Added new builtin ``python_quoted_string``, which will match any form
of single-line or multiline quoted strings defined in Python.
- ``Word`` arguments are now validated if ``min`` and ``max`` are both
given, that ``min`` <= ``max``; raises ``ValueError`` if values are invalid.
- Added '·' (Unicode MIDDLE DOT) to the set of ``Latin1.identbodychars``.
- Added ``ieee_float`` expression to ``pyparsing.common``, which parses float values,
plus "NaN", "Inf", "Infinity".
- Minor performance speedup in ``trim_arity``, to benefit any parsers using parse actions.
API Changes
===========
- ``Optional(expr)`` may now be written as ``expr | ""``
This will make this code::
"{" + Optional(Literal("A") | Literal("a")) + "}"
writable as::
"{" + (Literal("A") | Literal("a") | "") + "}"
Some related changes implemented as part of this work:
- ``Literal("")`` now internally generates an ``Empty()`` (and no longer raises an exception)
- ``Empty`` is now a subclass of ``Literal``
- Added new class property ``identifier`` to all Unicode set classes in ``pyparsing.unicode``,
using the class's values for ``cls.identchars`` and ``cls.identbodychars``. Now Unicode-aware
parsers that formerly wrote::
ppu = pyparsing.unicode
ident = Word(ppu.Greek.identchars, ppu.Greek.identbodychars)
can now write::
ident = ppu.Greek.identifier
# or
# ident = ppu.Ελληνικά.identifier
- Added bool ``embed`` argument to ``ParserElement.create_diagram()``.
When passed as True, the resulting diagram will omit the ``<DOCTYPE>``,
``<HEAD>``, and ``<BODY>`` tags so that it can be embedded in other
HTML source. (Useful when embedding a call to ``create_diagram()`` in
a PyScript HTML page.)
- Added ``recurse`` argument to ``ParserElement.set_debug`` to set the
debug flag on an expression and all of its sub-expressions.
- Reworked ``delimited_list`` function into the new ``DelimitedList`` class.
``DelimitedList`` has the same constructor interface as ``delimited_list``, and
in this release, ``delimited_list`` changes from a function to a synonym for
``DelimitedList``. ``delimited_list`` and the older ``delimitedList`` method will be
deprecated in a future release, in favor of ``DelimitedList``.
- ``ParseResults`` now has a new method ``deepcopy()``, in addition to the current
``copy()`` method. ``copy()`` only makes a shallow copy - any contained ``ParseResults``
are copied as references - changes in the copy will be seen as changes in the original.
In many cases, a shallow copy is sufficient, but some applications require a deep copy.
``deepcopy()`` makes a deeper copy: any contained ``ParseResults`` or other mappings or
containers are built with copies from the original, and do not get changed if the
original is later changed.
- Added named field "url" to ``pyparsing.common.url``, returning the entire
parsed URL string.
- Added exception type to ``trace_parse_action`` exception output.
- Added ``<META>`` tag to HTML generated for railroad diagrams to force UTF-8 encoding
with older browsers, to better display Unicode parser characters.
- To address a compatibility issue in RDFLib, added a property setter for the
``ParserElement.name`` property, to call ``ParserElement.set_name``.
- Modified ``ParserElement.set_name()`` to accept a None value, to clear the defined
name and corresponding error message for a ``ParserElement``.
- Updated railroad diagram generation for ``ZeroOrMore`` and ``OneOrMore`` expressions with
``stop_on`` expressions.
Discontinued Features
=====================
Python 2.x no longer supported
------------------------------
Removed Py2.x support and other deprecated features. Pyparsing
now requires Python 3.6.8 or later. If you are using an earlier
version of Python, you must use a Pyparsing 2.4.x version.
Other discontinued / deprecated features
----------------------------------------
- ``ParserElement.validate()`` is deprecated. It predates the support for left-recursive
parsers, and was prone to false positives (warning that a grammar was invalid when
it was in fact valid). It will be removed in a future pyparsing release. In its
place, developers should use debugging and analytical tools, such as ``ParserElement.set_debug()``
and ``ParserElement.create_diagram()``.
Fixed Bugs
==========
- Updated ``ci.yml`` permissions to limit default access to source.
- Updated ``create_diagram()`` code to be compatible with railroad-diagrams package
version 3.0.
- Fixed bug in ``pyparsing.common.url``, when input URL is not alone
on an input line.
- Fixed bug in srange, when parsing escaped '/' and '\' inside a
range set.
- Fixed exception messages for some ``ParserElements`` with custom names,
which instead showed their contained expression names.
- Fixed bug in ``Word`` when ``max=2``. Also added performance enhancement
when specifying ``exact`` argument.
- Fixed bug when parse actions returned an empty string for an expression that
had a results name, that the results name was not saved. That is::
expr = Literal("X").add_parse_action(lambda tokens: "")("value")
result = expr.parse_string("X")
print(result["value"])
would raise a ``KeyError``. Now empty strings will be saved with the associated
results name.
- Fixed bug in ``SkipTo`` where ignore expressions were not properly handled while
scanning for the target expression.
- Fixed bug in ``NotAny``, where parse actions on the negated expr were not being run.
This could cause ``NotAny`` to incorrectly fail if the expr would normally match,
but would fail to match if a condition used as a parse action returned False.
- Fixed ``create_diagram()`` to accept keyword args, to be passed through to the
``template.render()`` method to generate the output HTML.
- Fixed bug in ``python_quoted_string`` regex.
- Fixed regression in Word(min).
- Fixed bug in bad exception messages raised by Forward expressions.
- Fixed regression in SkipTo, where ignored expressions were not checked when looking
for the target expression.
- Updated pep8 synonym wrappers for better type checking compatibility.
- Fixed empty error message bug. This _should_ return
pyparsing's exception messages to a former, more helpful form. If you have code that
parses the exception messages returned by pyparsing, this may require some code
changes.
- Fixed issue where PEP8 compatibility names for ``ParserElement`` static methods were
not themselves defined as ``staticmethods``. When called using a ``ParserElement`` instance,
this resulted in a ``TypeError`` exception.
- Fixed some cosmetics/bugs in railroad diagrams:
- fixed groups being shown even when ``show_groups`` = False
- show results names as quoted strings when ``show_results_names`` = True
- only use integer loop counter if repetition > 2
New / Enhanced Examples
=======================
- Added example ``mongodb_query_expression.py``, to convert human-readable infix query
expressions, such as::
a==100 and b>=200
and transform them into an equivalent query argument for the pymongo package::
{'$and': [{'a': 100}, {'b': {'$gte': 200}}]}
Supports many equality and inequality operators - see the docstring for the
``transform_query`` function for many more examples.
- ``invRegex.py`` example renamed to ``inv_regex.py`` and updated to PEP-8
variable and method naming.
- Removed examples ``sparser.py`` and ``pymicko.py``, since each included its
own GPL license in the header. Since this conflicts with pyparsing's
MIT license, they were removed from the distribution to avoid
confusion among those making use of them in their own projects.
- Updated the ``lucene_grammar.py`` example (better support for '*' and '?' wildcards)
and corrected the test cases!
- Added ``bf.py`` Brainf*ck parser/executor example. Illustrates using
a pyparsing grammar to parse language syntax, and attach executable AST nodes to
the parsed results.
- Added ``tag_emitter.py`` to examples. This example demonstrates how to insert
tags into your parsed results that are not part of the original parsed text.
- Updated example ``select_parser.py`` to use PEP8 names and added Groups for better retrieval
of parsed values from multiple SELECT clauses.
- Added example ``email_address_parser.py``.
- Added example ``directx_x_file_parser.py`` to parse DirectX template definitions, and
generate a Pyparsing parser from a template to parse .x files.
- ``delta_time``, ``lua_parser``, ``decaf_parser``, and ``roman_numerals`` examples cleaned up
to use latest PEP8 names and add minor enhancements.
- Fixed bug (and corresponding test code) in ``delta_time`` example that did not handle
weekday references in time expressions (like "Monday at 4pm") when the weekday was
the same as the current weekday.
Acknowledgments
===============
Again, thanks to the many contributors who submitted issues, questions, suggestions,
and PRs.

View File

@@ -0,0 +1,129 @@
=============================
What's New in Pyparsing 3.2.0
=============================
:author: Paul McGuire
:date: October, 2024
:abstract: This document summarizes the changes made
in the 3.2.x releases of pyparsing.
.. sectnum:: :depth: 4
.. contents:: :depth: 4
Supported Python versions
=========================
- Added support for Python 3.13.
- Python versions before 3.9 are no longer supported.
Removed legacy Py2.x support and other deprecated features. Pyparsing
now requires Python 3.9 or later. If you are using an earlier 3.x
version of Python, use pyparsing 3.1; for Python 2.x, use Pyparsing
2.4.7.
New Features
============
- Added type annotations to remainder of ``pyparsing`` package, and added ``mypy``
run to ``tox.ini``, so that type annotations are now run as part of pyparsing's CI.
- Exception message format can now be customized, by overriding
``ParseBaseException.format_message``::
def custom_exception_message(exc) -> str:
found_phrase = f", found {exc.found}" if exc.found else ""
return f"{exc.lineno}:{exc.column} {exc.msg}{found_phrase}"
ParseBaseException.formatted_message = custom_exception_message
- ``run_tests`` now detects if an exception is raised in a parse action, and will
report it with an enhanced error message, with the exception type, string,
and parse action name.
- ``QuotedString`` now handles translation of escaped integer, hex, octal, and
Unicode sequences to their corresponding characters.
- Defined a more performant regular expression used internally by ``common_html_entity``.
- ``Regex`` instances can now be created using a callable that takes no arguments
and just returns a string or a compiled regular expression, so that creating complex
regular expression patterns can be deferred until they are actually used for the first
time in the parser.
- Fixed the displayed output of ``Regex`` terms to deduplicate repeated backslashes,
for easier reading in debugging, printing, and railroad diagrams.
- Fixed railroad diagrams that get generated with a parser containing a Regex element
defined using a verbose pattern - the pattern gets flattened and comments removed
before creating the corresponding diagram element.
API Changes
===========
Possible breaking changes
-------------------------
- Fixed code in ``ParseElementEnhance`` subclasses that
replaced detailed exception messages raised in contained expressions with a
less-specific and less-informative generic exception message and location.
If your code has conditional logic based on the message content in raised
``ParseExceptions``, this bugfix may require changes in your code.
- Fixed bug in ``transform_string()`` where whitespace
in the input string was not properly preserved in the output string.
If your code uses ``transform_string``, this bugfix may require changes in
your code.
- Fixed bug where an ``IndexError`` raised in a parse action was
incorrectly handled as an ``IndexError`` raised as part of the ``ParserElement``
parsing methods, and reraised as a ``ParseException``. Now an ``IndexError``
that raises inside a parse action will properly propagate out as an ``IndexError``.
If your code raises ``IndexError`` in parse actions, this bugfix may require
changes in your code.
Additional API changes
----------------------
- Added optional ``flatten`` Boolean argument to ``ParseResults.as_list()``, to
return the parsed values in a flattened list.
- Added ``indent`` and ``base_1`` arguments to ``pyparsing.testing.with_line_numbers``. When
using ``with_line_numbers`` inside a parse action, set ``base_1``=False, since the
reported ``loc`` value is 0-based. ``indent`` can be a leading string (typically of
spaces or tabs) to indent the numbered string passed to ``with_line_numbers``.
New / Enhanced Examples
=======================
- Added query syntax to ``mongodb_query_expression.py`` with:
- better support for array fields ("contains all",
"contains any", and "contains none")
- "like" and "not like" operators to support SQL "%" wildcard matching
and "=~" operator to support regex matching
- text search using "search for"
- dates and datetimes as query values
- ``a[0]`` style array referencing
- Added ``lox_parser.py`` example, a parser for the Lox language used as a tutorial in
Robert Nystrom's "Crafting Interpreters" (http://craftinginterpreters.com/).
- Added ``complex_chemical_formulas.py`` example, to add parsing capability for
formulas such as "Ba(BrO₃)₂·H₂O".
- Updated ``tag_emitter.py`` to use new ``Tag`` class, introduced in pyparsing
3.1.3.
Acknowledgments
===============
Again, thanks to the many contributors who submitted issues, questions, suggestions,
and PRs.

View File

@@ -0,0 +1,45 @@
=============================
What's New in Pyparsing 3.x.0
=============================
:author: Paul McGuire
:date: month, year
:abstract: This document summarizes the changes made
in the 3.x.x releases of pyparsing.
.. sectnum:: :depth: 4
.. contents:: :depth: 4
Supported Python versions
=========================
New Features
============
API Changes
===========
Discontinued Features
=====================
Other discontinued features
---------------------------
Fixed Bugs
==========
New / Enhanced Examples
=======================
Acknowledgments
===============
Again, thanks to the many contributors who submitted issues, questions, suggestions,
and PRs.