Instructions to use Qtn-Cls/LocalMeshEngine with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Trellis
How to use Qtn-Cls/LocalMeshEngine with Trellis:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
add the DA3 side measurer, packaged as the engine expects it
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- cameras/README-da3.md +145 -0
- cameras/config.json +60 -0
- cameras/deps/addict-2.4.0.dist-info/INSTALLER +1 -0
- cameras/deps/addict-2.4.0.dist-info/LICENSE +22 -0
- cameras/deps/addict-2.4.0.dist-info/METADATA +23 -0
- cameras/deps/addict-2.4.0.dist-info/RECORD +9 -0
- cameras/deps/addict-2.4.0.dist-info/REQUESTED +0 -0
- cameras/deps/addict-2.4.0.dist-info/WHEEL +5 -0
- cameras/deps/addict-2.4.0.dist-info/top_level.txt +1 -0
- cameras/deps/addict/__init__.py +10 -0
- cameras/deps/addict/addict.py +159 -0
- cameras/deps/antlr4/BufferedTokenStream.py +302 -0
- cameras/deps/antlr4/CommonTokenFactory.py +61 -0
- cameras/deps/antlr4/CommonTokenStream.py +87 -0
- cameras/deps/antlr4/FileStream.py +27 -0
- cameras/deps/antlr4/InputStream.py +87 -0
- cameras/deps/antlr4/IntervalSet.py +180 -0
- cameras/deps/antlr4/LL1Analyzer.py +173 -0
- cameras/deps/antlr4/Lexer.py +329 -0
- cameras/deps/antlr4/ListTokenSource.py +144 -0
- cameras/deps/antlr4/Parser.py +580 -0
- cameras/deps/antlr4/ParserInterpreter.py +170 -0
- cameras/deps/antlr4/ParserRuleContext.py +186 -0
- cameras/deps/antlr4/PredictionContext.py +623 -0
- cameras/deps/antlr4/Recognizer.py +147 -0
- cameras/deps/antlr4/RuleContext.py +227 -0
- cameras/deps/antlr4/StdinStream.py +11 -0
- cameras/deps/antlr4/Token.py +155 -0
- cameras/deps/antlr4/TokenStreamRewriter.py +255 -0
- cameras/deps/antlr4/Utils.py +33 -0
- cameras/deps/antlr4/__init__.py +21 -0
- cameras/deps/antlr4/atn/ATN.py +132 -0
- cameras/deps/antlr4/atn/ATNConfig.py +159 -0
- cameras/deps/antlr4/atn/ATNConfigSet.py +212 -0
- cameras/deps/antlr4/atn/ATNDeserializationOptions.py +24 -0
- cameras/deps/antlr4/atn/ATNDeserializer.py +529 -0
- cameras/deps/antlr4/atn/ATNSimulator.py +47 -0
- cameras/deps/antlr4/atn/ATNState.py +264 -0
- cameras/deps/antlr4/atn/ATNType.py +17 -0
- cameras/deps/antlr4/atn/LexerATNSimulator.py +570 -0
- cameras/deps/antlr4/atn/LexerAction.py +298 -0
- cameras/deps/antlr4/atn/LexerActionExecutor.py +143 -0
- cameras/deps/antlr4/atn/ParserATNSimulator.py +1649 -0
- cameras/deps/antlr4/atn/PredictionMode.py +499 -0
- cameras/deps/antlr4/atn/SemanticContext.py +323 -0
- cameras/deps/antlr4/atn/Transition.py +268 -0
- cameras/deps/antlr4/atn/__init__.py +1 -0
- cameras/deps/antlr4/dfa/DFA.py +133 -0
- cameras/deps/antlr4/dfa/DFASerializer.py +73 -0
- cameras/deps/antlr4/dfa/DFAState.py +126 -0
cameras/README-da3.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
pipeline_tag: image-to-3d
|
| 4 |
+
tags:
|
| 5 |
+
- depth-estimation
|
| 6 |
+
- computer-vision
|
| 7 |
+
- monocular-depth
|
| 8 |
+
- multi-view-geometry
|
| 9 |
+
- pose-estimation
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# Depth Anything 3: DA3-BASE
|
| 13 |
+
|
| 14 |
+
<div align="center">
|
| 15 |
+
|
| 16 |
+
[](https://depth-anything-3.github.io)
|
| 17 |
+
[](https://arxiv.org/abs/2511.10647)
|
| 18 |
+
[](https://huggingface.co/spaces/depth-anything/Depth-Anything-3) # noqa: E501
|
| 19 |
+
<!-- Benchmark badge removed as per request -->
|
| 20 |
+
|
| 21 |
+
</div>
|
| 22 |
+
|
| 23 |
+
## Abstract
|
| 24 |
+
|
| 25 |
+
We present Depth Anything 3 (DA3), a model that predicts spatially consistent geometry from an arbitrary number of visual inputs, with or without known camera poses. In pursuit of minimal modeling, DA3 yields two key insights: a single plain transformer (e.g., vanilla DINO encoder) is sufficient as a backbone without architectural specialization, and a singular depth-ray prediction target obviates the need for complex multi-task learning. Through our teacher-student training paradigm, the model achieves a level of detail and generalization on par with Depth Anything 2 (DA2). We establish a new visual geometry benchmark covering camera pose estimation, any-view geometry and visual rendering. On this benchmark, DA3 sets a new state-of-the-art across all tasks, surpassing prior SOTA VGGT by an average of 44.3% in camera pose accuracy and 25.1% in geometric accuracy. Moreover, it outperforms DA2 in monocular depth estimation. All models are trained exclusively on public academic datasets.
|
| 26 |
+
|
| 27 |
+
## Model Description
|
| 28 |
+
|
| 29 |
+
DA3 Base model for multi-view depth estimation and camera pose estimation. Compact foundation model with unified depth-ray representation.
|
| 30 |
+
|
| 31 |
+
| Property | Value |
|
| 32 |
+
|----------|-------|
|
| 33 |
+
| **Model Series** | Any-view Model |
|
| 34 |
+
| **Parameters** | 0.12B |
|
| 35 |
+
| **License** | Apache 2.0 |
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
## Capabilities
|
| 40 |
+
|
| 41 |
+
- ✅ Relative Depth
|
| 42 |
+
- ✅ Pose Estimation
|
| 43 |
+
- ✅ Pose Conditioning
|
| 44 |
+
|
| 45 |
+
## Quick Start
|
| 46 |
+
|
| 47 |
+
### Installation
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
git clone https://github.com/ByteDance-Seed/depth-anything-3
|
| 51 |
+
cd depth-anything-3
|
| 52 |
+
pip install -e .
|
| 53 |
+
```
|
| 54 |
+
|
| 55 |
+
### Basic Example
|
| 56 |
+
|
| 57 |
+
```python
|
| 58 |
+
import torch
|
| 59 |
+
from depth_anything_3.api import DepthAnything3
|
| 60 |
+
|
| 61 |
+
# Load model from Hugging Face Hub
|
| 62 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 63 |
+
model = DepthAnything3.from_pretrained("depth-anything/da3-base")
|
| 64 |
+
model = model.to(device=device)
|
| 65 |
+
|
| 66 |
+
# Run inference on images
|
| 67 |
+
images = ["image1.jpg", "image2.jpg"] # List of image paths, PIL Images, or numpy arrays
|
| 68 |
+
prediction = model.inference(
|
| 69 |
+
images,
|
| 70 |
+
export_dir="output",
|
| 71 |
+
export_format="glb" # Options: glb, npz, ply, mini_npz, gs_ply, gs_video
|
| 72 |
+
)
|
| 73 |
+
|
| 74 |
+
# Access results
|
| 75 |
+
print(prediction.depth.shape) # Depth maps: [N, H, W] float32
|
| 76 |
+
print(prediction.conf.shape) # Confidence maps: [N, H, W] float32
|
| 77 |
+
print(prediction.extrinsics.shape) # Camera poses (w2c): [N, 3, 4] float32
|
| 78 |
+
print(prediction.intrinsics.shape) # Camera intrinsics: [N, 3, 3] float32
|
| 79 |
+
```
|
| 80 |
+
|
| 81 |
+
### Command Line Interface
|
| 82 |
+
|
| 83 |
+
```bash
|
| 84 |
+
# Process images with auto mode
|
| 85 |
+
da3 auto path/to/images \
|
| 86 |
+
--export-format glb \
|
| 87 |
+
--export-dir output \
|
| 88 |
+
--model-dir depth-anything/da3-base
|
| 89 |
+
|
| 90 |
+
# Use backend for faster repeated inference
|
| 91 |
+
da3 backend --model-dir depth-anything/da3-base
|
| 92 |
+
da3 auto path/to/images --export-format glb --use-backend
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
## Model Details
|
| 96 |
+
|
| 97 |
+
- **Developed by:** ByteDance Seed Team
|
| 98 |
+
- **Model Type:** Vision Transformer for Visual Geometry
|
| 99 |
+
- **Architecture:** Plain transformer with unified depth-ray representation
|
| 100 |
+
- **Training Data:** Public academic datasets only
|
| 101 |
+
|
| 102 |
+
### Key Insights
|
| 103 |
+
|
| 104 |
+
💎 A **single plain transformer** (e.g., vanilla DINO encoder) is sufficient as a backbone without architectural specialization. # noqa: E501
|
| 105 |
+
|
| 106 |
+
✨ A singular **depth-ray representation** obviates the need for complex multi-task learning.
|
| 107 |
+
|
| 108 |
+
## Performance
|
| 109 |
+
|
| 110 |
+
🏆 Depth Anything 3 significantly outperforms:
|
| 111 |
+
- **Depth Anything 2** for monocular depth estimation
|
| 112 |
+
- **VGGT** for multi-view depth estimation and pose estimation
|
| 113 |
+
|
| 114 |
+
For detailed benchmarks, please refer to our [paper](https://arxiv.org/abs/2511.10647). # noqa: E501
|
| 115 |
+
|
| 116 |
+
## Limitations
|
| 117 |
+
|
| 118 |
+
- The model is trained on academic datasets and may have limitations on certain domain-specific images # noqa: E501
|
| 119 |
+
- Performance may vary depending on image quality, lighting conditions, and scene complexity
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
## Citation
|
| 123 |
+
|
| 124 |
+
If you find Depth Anything 3 useful in your research or projects, please cite:
|
| 125 |
+
|
| 126 |
+
```bibtex
|
| 127 |
+
@article{depthanything3,
|
| 128 |
+
title={Depth Anything 3: Recovering the visual space from any views},
|
| 129 |
+
author={Haotong Lin and Sili Chen and Jun Hao Liew and Donny Y. Chen and Zhenyu Li and Guang Shi and Jiashi Feng and Bingyi Kang}, # noqa: E501
|
| 130 |
+
journal={arXiv preprint arXiv:2511.10647},
|
| 131 |
+
year={2025}
|
| 132 |
+
}
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
## Links
|
| 136 |
+
|
| 137 |
+
- 🏠 [Project Page](https://depth-anything-3.github.io)
|
| 138 |
+
- 📄 [Paper](https://arxiv.org/abs/2511.10647)
|
| 139 |
+
- 💻 [GitHub Repository](https://github.com/ByteDance-Seed/depth-anything-3)
|
| 140 |
+
- 🤗 [Hugging Face Demo](https://huggingface.co/spaces/depth-anything/Depth-Anything-3)
|
| 141 |
+
- 📚 [Documentation](https://github.com/ByteDance-Seed/depth-anything-3#-useful-documentation)
|
| 142 |
+
|
| 143 |
+
## Authors
|
| 144 |
+
|
| 145 |
+
[Haotong Lin](https://haotongl.github.io/) · [Sili Chen](https://github.com/SiliChen321) · [Junhao Liew](https://liewjunhao.github.io/) · [Donny Y. Chen](https://donydchen.github.io) · [Zhenyu Li](https://zhyever.github.io/) · [Guang Shi](https://scholar.google.com/citations?user=MjXxWbUAAAAJ&hl=en) · [Jiashi Feng](https://scholar.google.com.sg/citations?user=Q8iay0gAAAAJ&hl=en) · [Bingyi Kang](https://bingykang.github.io/) # noqa: E501
|
cameras/config.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_name": "da3-base",
|
| 3 |
+
"config": {
|
| 4 |
+
"__object__": {
|
| 5 |
+
"path": "depth_anything_3.model.da3",
|
| 6 |
+
"name": "DepthAnything3Net",
|
| 7 |
+
"args": "as_params"
|
| 8 |
+
},
|
| 9 |
+
"net": {
|
| 10 |
+
"__object__": {
|
| 11 |
+
"path": "depth_anything_3.model.dinov2.dinov2",
|
| 12 |
+
"name": "DinoV2",
|
| 13 |
+
"args": "as_params"
|
| 14 |
+
},
|
| 15 |
+
"name": "vitb",
|
| 16 |
+
"out_layers": [
|
| 17 |
+
5,
|
| 18 |
+
7,
|
| 19 |
+
9,
|
| 20 |
+
11
|
| 21 |
+
],
|
| 22 |
+
"alt_start": 4,
|
| 23 |
+
"qknorm_start": 4,
|
| 24 |
+
"rope_start": 4,
|
| 25 |
+
"cat_token": true
|
| 26 |
+
},
|
| 27 |
+
"head": {
|
| 28 |
+
"__object__": {
|
| 29 |
+
"path": "depth_anything_3.model.dualdpt",
|
| 30 |
+
"name": "DualDPT",
|
| 31 |
+
"args": "as_params"
|
| 32 |
+
},
|
| 33 |
+
"dim_in": 1536,
|
| 34 |
+
"output_dim": 2,
|
| 35 |
+
"features": 128,
|
| 36 |
+
"out_channels": [
|
| 37 |
+
96,
|
| 38 |
+
192,
|
| 39 |
+
384,
|
| 40 |
+
768
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
"cam_enc": {
|
| 44 |
+
"__object__": {
|
| 45 |
+
"path": "depth_anything_3.model.cam_enc",
|
| 46 |
+
"name": "CameraEnc",
|
| 47 |
+
"args": "as_params"
|
| 48 |
+
},
|
| 49 |
+
"dim_out": 768
|
| 50 |
+
},
|
| 51 |
+
"cam_dec": {
|
| 52 |
+
"__object__": {
|
| 53 |
+
"path": "depth_anything_3.model.cam_dec",
|
| 54 |
+
"name": "CameraDec",
|
| 55 |
+
"args": "as_params"
|
| 56 |
+
},
|
| 57 |
+
"dim_in": 1536
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
}
|
cameras/deps/addict-2.4.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
cameras/deps/addict-2.4.0.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
The MIT License (MIT)
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2014 Mats Julian Olsen
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
| 22 |
+
|
cameras/deps/addict-2.4.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: addict
|
| 3 |
+
Version: 2.4.0
|
| 4 |
+
Summary: Addict is a dictionary whose items can be set using both attribute and item syntax.
|
| 5 |
+
Home-page: https://github.com/mewwts/addict
|
| 6 |
+
Author: Mats Julian Olsen
|
| 7 |
+
Author-email: mats@plysjbyen.net
|
| 8 |
+
License: UNKNOWN
|
| 9 |
+
Platform: UNKNOWN
|
| 10 |
+
Classifier: Programming Language :: Python
|
| 11 |
+
Classifier: Programming Language :: Python :: 2.7
|
| 12 |
+
Classifier: Programming Language :: Python :: 3.6
|
| 13 |
+
Classifier: Programming Language :: Python :: 3.7
|
| 14 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 15 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 16 |
+
Classifier: License :: OSI Approved :: MIT License
|
| 17 |
+
Classifier: Operating System :: OS Independent
|
| 18 |
+
Classifier: Intended Audience :: Developers
|
| 19 |
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
| 20 |
+
|
| 21 |
+
Addict is a module that exposes a dictionary subclass that allows items to be set like attributes. Values are gettable and settable using both attribute and item syntax. For more info check out the README at 'github.com/mewwts/addict'.
|
| 22 |
+
|
| 23 |
+
|
cameras/deps/addict-2.4.0.dist-info/RECORD
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
addict-2.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 2 |
+
addict-2.4.0.dist-info/LICENSE,sha256=ykiNM8US0LImFCCQr5DomuJmqQGik_if1kLf7JMeIsE,1085
|
| 3 |
+
addict-2.4.0.dist-info/METADATA,sha256=ZjIJZ5lvhfohHxIWp79fkh0TtBsN5duX84na3bxU6vQ,1028
|
| 4 |
+
addict-2.4.0.dist-info/RECORD,,
|
| 5 |
+
addict-2.4.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 6 |
+
addict-2.4.0.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92
|
| 7 |
+
addict-2.4.0.dist-info/top_level.txt,sha256=GGfQKsz1N-bSRYzNpyp8GY8uAEqh3SWaXRbAnBUKjHA,7
|
| 8 |
+
addict/__init__.py,sha256=xmlNiYYVoAD3_FfmgfOM2cc3wI17GSgsMBODbFRs_mY,233
|
| 9 |
+
addict/addict.py,sha256=ScOfclaAM7ugyZoXOW2HHL9gCXt_XPe-i5bTLiY8ufU,4901
|
cameras/deps/addict-2.4.0.dist-info/REQUESTED
ADDED
|
File without changes
|
cameras/deps/addict-2.4.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: bdist_wheel (0.35.1)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
cameras/deps/addict-2.4.0.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
addict
|
cameras/deps/addict/__init__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .addict import Dict
|
| 2 |
+
from .addict import Dict as Addict
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
__title__ = 'addict'
|
| 6 |
+
__version__ = '2.4.0'
|
| 7 |
+
__author__ = 'Mats Julian Olsen'
|
| 8 |
+
__license__ = 'MIT'
|
| 9 |
+
__copyright__ = 'Copyright 2014-2020 Mats Julian Olsen'
|
| 10 |
+
__all__ = ['Dict']
|
cameras/deps/addict/addict.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class Dict(dict):
|
| 5 |
+
|
| 6 |
+
def __init__(__self, *args, **kwargs):
|
| 7 |
+
object.__setattr__(__self, '__parent', kwargs.pop('__parent', None))
|
| 8 |
+
object.__setattr__(__self, '__key', kwargs.pop('__key', None))
|
| 9 |
+
object.__setattr__(__self, '__frozen', False)
|
| 10 |
+
for arg in args:
|
| 11 |
+
if not arg:
|
| 12 |
+
continue
|
| 13 |
+
elif isinstance(arg, dict):
|
| 14 |
+
for key, val in arg.items():
|
| 15 |
+
__self[key] = __self._hook(val)
|
| 16 |
+
elif isinstance(arg, tuple) and (not isinstance(arg[0], tuple)):
|
| 17 |
+
__self[arg[0]] = __self._hook(arg[1])
|
| 18 |
+
else:
|
| 19 |
+
for key, val in iter(arg):
|
| 20 |
+
__self[key] = __self._hook(val)
|
| 21 |
+
|
| 22 |
+
for key, val in kwargs.items():
|
| 23 |
+
__self[key] = __self._hook(val)
|
| 24 |
+
|
| 25 |
+
def __setattr__(self, name, value):
|
| 26 |
+
if hasattr(self.__class__, name):
|
| 27 |
+
raise AttributeError("'Dict' object attribute "
|
| 28 |
+
"'{0}' is read-only".format(name))
|
| 29 |
+
else:
|
| 30 |
+
self[name] = value
|
| 31 |
+
|
| 32 |
+
def __setitem__(self, name, value):
|
| 33 |
+
isFrozen = (hasattr(self, '__frozen') and
|
| 34 |
+
object.__getattribute__(self, '__frozen'))
|
| 35 |
+
if isFrozen and name not in super(Dict, self).keys():
|
| 36 |
+
raise KeyError(name)
|
| 37 |
+
super(Dict, self).__setitem__(name, value)
|
| 38 |
+
try:
|
| 39 |
+
p = object.__getattribute__(self, '__parent')
|
| 40 |
+
key = object.__getattribute__(self, '__key')
|
| 41 |
+
except AttributeError:
|
| 42 |
+
p = None
|
| 43 |
+
key = None
|
| 44 |
+
if p is not None:
|
| 45 |
+
p[key] = self
|
| 46 |
+
object.__delattr__(self, '__parent')
|
| 47 |
+
object.__delattr__(self, '__key')
|
| 48 |
+
|
| 49 |
+
def __add__(self, other):
|
| 50 |
+
if not self.keys():
|
| 51 |
+
return other
|
| 52 |
+
else:
|
| 53 |
+
self_type = type(self).__name__
|
| 54 |
+
other_type = type(other).__name__
|
| 55 |
+
msg = "unsupported operand type(s) for +: '{}' and '{}'"
|
| 56 |
+
raise TypeError(msg.format(self_type, other_type))
|
| 57 |
+
|
| 58 |
+
@classmethod
|
| 59 |
+
def _hook(cls, item):
|
| 60 |
+
if isinstance(item, dict):
|
| 61 |
+
return cls(item)
|
| 62 |
+
elif isinstance(item, (list, tuple)):
|
| 63 |
+
return type(item)(cls._hook(elem) for elem in item)
|
| 64 |
+
return item
|
| 65 |
+
|
| 66 |
+
def __getattr__(self, item):
|
| 67 |
+
return self.__getitem__(item)
|
| 68 |
+
|
| 69 |
+
def __missing__(self, name):
|
| 70 |
+
if object.__getattribute__(self, '__frozen'):
|
| 71 |
+
raise KeyError(name)
|
| 72 |
+
return self.__class__(__parent=self, __key=name)
|
| 73 |
+
|
| 74 |
+
def __delattr__(self, name):
|
| 75 |
+
del self[name]
|
| 76 |
+
|
| 77 |
+
def to_dict(self):
|
| 78 |
+
base = {}
|
| 79 |
+
for key, value in self.items():
|
| 80 |
+
if isinstance(value, type(self)):
|
| 81 |
+
base[key] = value.to_dict()
|
| 82 |
+
elif isinstance(value, (list, tuple)):
|
| 83 |
+
base[key] = type(value)(
|
| 84 |
+
item.to_dict() if isinstance(item, type(self)) else
|
| 85 |
+
item for item in value)
|
| 86 |
+
else:
|
| 87 |
+
base[key] = value
|
| 88 |
+
return base
|
| 89 |
+
|
| 90 |
+
def copy(self):
|
| 91 |
+
return copy.copy(self)
|
| 92 |
+
|
| 93 |
+
def deepcopy(self):
|
| 94 |
+
return copy.deepcopy(self)
|
| 95 |
+
|
| 96 |
+
def __deepcopy__(self, memo):
|
| 97 |
+
other = self.__class__()
|
| 98 |
+
memo[id(self)] = other
|
| 99 |
+
for key, value in self.items():
|
| 100 |
+
other[copy.deepcopy(key, memo)] = copy.deepcopy(value, memo)
|
| 101 |
+
return other
|
| 102 |
+
|
| 103 |
+
def update(self, *args, **kwargs):
|
| 104 |
+
other = {}
|
| 105 |
+
if args:
|
| 106 |
+
if len(args) > 1:
|
| 107 |
+
raise TypeError()
|
| 108 |
+
other.update(args[0])
|
| 109 |
+
other.update(kwargs)
|
| 110 |
+
for k, v in other.items():
|
| 111 |
+
if ((k not in self) or
|
| 112 |
+
(not isinstance(self[k], dict)) or
|
| 113 |
+
(not isinstance(v, dict))):
|
| 114 |
+
self[k] = v
|
| 115 |
+
else:
|
| 116 |
+
self[k].update(v)
|
| 117 |
+
|
| 118 |
+
def __getnewargs__(self):
|
| 119 |
+
return tuple(self.items())
|
| 120 |
+
|
| 121 |
+
def __getstate__(self):
|
| 122 |
+
return self
|
| 123 |
+
|
| 124 |
+
def __setstate__(self, state):
|
| 125 |
+
self.update(state)
|
| 126 |
+
|
| 127 |
+
def __or__(self, other):
|
| 128 |
+
if not isinstance(other, (Dict, dict)):
|
| 129 |
+
return NotImplemented
|
| 130 |
+
new = Dict(self)
|
| 131 |
+
new.update(other)
|
| 132 |
+
return new
|
| 133 |
+
|
| 134 |
+
def __ror__(self, other):
|
| 135 |
+
if not isinstance(other, (Dict, dict)):
|
| 136 |
+
return NotImplemented
|
| 137 |
+
new = Dict(other)
|
| 138 |
+
new.update(self)
|
| 139 |
+
return new
|
| 140 |
+
|
| 141 |
+
def __ior__(self, other):
|
| 142 |
+
self.update(other)
|
| 143 |
+
return self
|
| 144 |
+
|
| 145 |
+
def setdefault(self, key, default=None):
|
| 146 |
+
if key in self:
|
| 147 |
+
return self[key]
|
| 148 |
+
else:
|
| 149 |
+
self[key] = default
|
| 150 |
+
return default
|
| 151 |
+
|
| 152 |
+
def freeze(self, shouldFreeze=True):
|
| 153 |
+
object.__setattr__(self, '__frozen', shouldFreeze)
|
| 154 |
+
for key, val in self.items():
|
| 155 |
+
if isinstance(val, Dict):
|
| 156 |
+
val.freeze(shouldFreeze)
|
| 157 |
+
|
| 158 |
+
def unfreeze(self):
|
| 159 |
+
self.freeze(False)
|
cameras/deps/antlr4/BufferedTokenStream.py
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
|
| 6 |
+
# This implementation of {@link TokenStream} loads tokens from a
|
| 7 |
+
# {@link TokenSource} on-demand, and places the tokens in a buffer to provide
|
| 8 |
+
# access to any previous token by index.
|
| 9 |
+
#
|
| 10 |
+
# <p>
|
| 11 |
+
# This token stream ignores the value of {@link Token#getChannel}. If your
|
| 12 |
+
# parser requires the token stream filter tokens to only those on a particular
|
| 13 |
+
# channel, such as {@link Token#DEFAULT_CHANNEL} or
|
| 14 |
+
# {@link Token#HIDDEN_CHANNEL}, use a filtering token stream such a
|
| 15 |
+
# {@link CommonTokenStream}.</p>
|
| 16 |
+
from io import StringIO
|
| 17 |
+
from antlr4.Token import Token
|
| 18 |
+
from antlr4.error.Errors import IllegalStateException
|
| 19 |
+
|
| 20 |
+
# need forward declaration
|
| 21 |
+
Lexer = None
|
| 22 |
+
|
| 23 |
+
# this is just to keep meaningful parameter types to Parser
|
| 24 |
+
class TokenStream(object):
|
| 25 |
+
|
| 26 |
+
pass
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class BufferedTokenStream(TokenStream):
|
| 30 |
+
__slots__ = ('tokenSource', 'tokens', 'index', 'fetchedEOF')
|
| 31 |
+
|
| 32 |
+
def __init__(self, tokenSource:Lexer):
|
| 33 |
+
# The {@link TokenSource} from which tokens for this stream are fetched.
|
| 34 |
+
self.tokenSource = tokenSource
|
| 35 |
+
|
| 36 |
+
# A collection of all tokens fetched from the token source. The list is
|
| 37 |
+
# considered a complete view of the input once {@link #fetchedEOF} is set
|
| 38 |
+
# to {@code true}.
|
| 39 |
+
self.tokens = []
|
| 40 |
+
|
| 41 |
+
# The index into {@link #tokens} of the current token (next token to
|
| 42 |
+
# {@link #consume}). {@link #tokens}{@code [}{@link #p}{@code ]} should be
|
| 43 |
+
# {@link #LT LT(1)}.
|
| 44 |
+
#
|
| 45 |
+
# <p>This field is set to -1 when the stream is first constructed or when
|
| 46 |
+
# {@link #setTokenSource} is called, indicating that the first token has
|
| 47 |
+
# not yet been fetched from the token source. For additional information,
|
| 48 |
+
# see the documentation of {@link IntStream} for a description of
|
| 49 |
+
# Initializing Methods.</p>
|
| 50 |
+
self.index = -1
|
| 51 |
+
|
| 52 |
+
# Indicates whether the {@link Token#EOF} token has been fetched from
|
| 53 |
+
# {@link #tokenSource} and added to {@link #tokens}. This field improves
|
| 54 |
+
# performance for the following cases:
|
| 55 |
+
#
|
| 56 |
+
# <ul>
|
| 57 |
+
# <li>{@link #consume}: The lookahead check in {@link #consume} to prevent
|
| 58 |
+
# consuming the EOF symbol is optimized by checking the values of
|
| 59 |
+
# {@link #fetchedEOF} and {@link #p} instead of calling {@link #LA}.</li>
|
| 60 |
+
# <li>{@link #fetch}: The check to prevent adding multiple EOF symbols into
|
| 61 |
+
# {@link #tokens} is trivial with this field.</li>
|
| 62 |
+
# <ul>
|
| 63 |
+
self.fetchedEOF = False
|
| 64 |
+
|
| 65 |
+
def mark(self):
|
| 66 |
+
return 0
|
| 67 |
+
|
| 68 |
+
def release(self, marker:int):
|
| 69 |
+
# no resources to release
|
| 70 |
+
pass
|
| 71 |
+
|
| 72 |
+
def reset(self):
|
| 73 |
+
self.seek(0)
|
| 74 |
+
|
| 75 |
+
def seek(self, index:int):
|
| 76 |
+
self.lazyInit()
|
| 77 |
+
self.index = self.adjustSeekIndex(index)
|
| 78 |
+
|
| 79 |
+
def get(self, index:int):
|
| 80 |
+
self.lazyInit()
|
| 81 |
+
return self.tokens[index]
|
| 82 |
+
|
| 83 |
+
def consume(self):
|
| 84 |
+
skipEofCheck = False
|
| 85 |
+
if self.index >= 0:
|
| 86 |
+
if self.fetchedEOF:
|
| 87 |
+
# the last token in tokens is EOF. skip check if p indexes any
|
| 88 |
+
# fetched token except the last.
|
| 89 |
+
skipEofCheck = self.index < len(self.tokens) - 1
|
| 90 |
+
else:
|
| 91 |
+
# no EOF token in tokens. skip check if p indexes a fetched token.
|
| 92 |
+
skipEofCheck = self.index < len(self.tokens)
|
| 93 |
+
else:
|
| 94 |
+
# not yet initialized
|
| 95 |
+
skipEofCheck = False
|
| 96 |
+
|
| 97 |
+
if not skipEofCheck and self.LA(1) == Token.EOF:
|
| 98 |
+
raise IllegalStateException("cannot consume EOF")
|
| 99 |
+
|
| 100 |
+
if self.sync(self.index + 1):
|
| 101 |
+
self.index = self.adjustSeekIndex(self.index + 1)
|
| 102 |
+
|
| 103 |
+
# Make sure index {@code i} in tokens has a token.
|
| 104 |
+
#
|
| 105 |
+
# @return {@code true} if a token is located at index {@code i}, otherwise
|
| 106 |
+
# {@code false}.
|
| 107 |
+
# @see #get(int i)
|
| 108 |
+
#/
|
| 109 |
+
def sync(self, i:int):
|
| 110 |
+
n = i - len(self.tokens) + 1 # how many more elements we need?
|
| 111 |
+
if n > 0 :
|
| 112 |
+
fetched = self.fetch(n)
|
| 113 |
+
return fetched >= n
|
| 114 |
+
return True
|
| 115 |
+
|
| 116 |
+
# Add {@code n} elements to buffer.
|
| 117 |
+
#
|
| 118 |
+
# @return The actual number of elements added to the buffer.
|
| 119 |
+
#/
|
| 120 |
+
def fetch(self, n:int):
|
| 121 |
+
if self.fetchedEOF:
|
| 122 |
+
return 0
|
| 123 |
+
for i in range(0, n):
|
| 124 |
+
t = self.tokenSource.nextToken()
|
| 125 |
+
t.tokenIndex = len(self.tokens)
|
| 126 |
+
self.tokens.append(t)
|
| 127 |
+
if t.type==Token.EOF:
|
| 128 |
+
self.fetchedEOF = True
|
| 129 |
+
return i + 1
|
| 130 |
+
return n
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
# Get all tokens from start..stop inclusively#/
|
| 134 |
+
def getTokens(self, start:int, stop:int, types:set=None):
|
| 135 |
+
if start<0 or stop<0:
|
| 136 |
+
return None
|
| 137 |
+
self.lazyInit()
|
| 138 |
+
subset = []
|
| 139 |
+
if stop >= len(self.tokens):
|
| 140 |
+
stop = len(self.tokens)-1
|
| 141 |
+
for i in range(start, stop):
|
| 142 |
+
t = self.tokens[i]
|
| 143 |
+
if t.type==Token.EOF:
|
| 144 |
+
break
|
| 145 |
+
if types is None or t.type in types:
|
| 146 |
+
subset.append(t)
|
| 147 |
+
return subset
|
| 148 |
+
|
| 149 |
+
def LA(self, i:int):
|
| 150 |
+
return self.LT(i).type
|
| 151 |
+
|
| 152 |
+
def LB(self, k:int):
|
| 153 |
+
if (self.index-k) < 0:
|
| 154 |
+
return None
|
| 155 |
+
return self.tokens[self.index-k]
|
| 156 |
+
|
| 157 |
+
def LT(self, k:int):
|
| 158 |
+
self.lazyInit()
|
| 159 |
+
if k==0:
|
| 160 |
+
return None
|
| 161 |
+
if k < 0:
|
| 162 |
+
return self.LB(-k)
|
| 163 |
+
i = self.index + k - 1
|
| 164 |
+
self.sync(i)
|
| 165 |
+
if i >= len(self.tokens): # return EOF token
|
| 166 |
+
# EOF must be last token
|
| 167 |
+
return self.tokens[len(self.tokens)-1]
|
| 168 |
+
return self.tokens[i]
|
| 169 |
+
|
| 170 |
+
# Allowed derived classes to modify the behavior of operations which change
|
| 171 |
+
# the current stream position by adjusting the target token index of a seek
|
| 172 |
+
# operation. The default implementation simply returns {@code i}. If an
|
| 173 |
+
# exception is thrown in this method, the current stream index should not be
|
| 174 |
+
# changed.
|
| 175 |
+
#
|
| 176 |
+
# <p>For example, {@link CommonTokenStream} overrides this method to ensure that
|
| 177 |
+
# the seek target is always an on-channel token.</p>
|
| 178 |
+
#
|
| 179 |
+
# @param i The target token index.
|
| 180 |
+
# @return The adjusted target token index.
|
| 181 |
+
|
| 182 |
+
def adjustSeekIndex(self, i:int):
|
| 183 |
+
return i
|
| 184 |
+
|
| 185 |
+
def lazyInit(self):
|
| 186 |
+
if self.index == -1:
|
| 187 |
+
self.setup()
|
| 188 |
+
|
| 189 |
+
def setup(self):
|
| 190 |
+
self.sync(0)
|
| 191 |
+
self.index = self.adjustSeekIndex(0)
|
| 192 |
+
|
| 193 |
+
# Reset this token stream by setting its token source.#/
|
| 194 |
+
def setTokenSource(self, tokenSource:Lexer):
|
| 195 |
+
self.tokenSource = tokenSource
|
| 196 |
+
self.tokens = []
|
| 197 |
+
self.index = -1
|
| 198 |
+
self.fetchedEOF = False
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
# Given a starting index, return the index of the next token on channel.
|
| 202 |
+
# Return i if tokens[i] is on channel. Return the index of the EOF token
|
| 203 |
+
# if there are no tokens on channel between i and EOF.
|
| 204 |
+
#/
|
| 205 |
+
def nextTokenOnChannel(self, i:int, channel:int):
|
| 206 |
+
self.sync(i)
|
| 207 |
+
if i>=len(self.tokens):
|
| 208 |
+
return len(self.tokens) - 1
|
| 209 |
+
token = self.tokens[i]
|
| 210 |
+
while token.channel!=channel:
|
| 211 |
+
if token.type==Token.EOF:
|
| 212 |
+
return i
|
| 213 |
+
i += 1
|
| 214 |
+
self.sync(i)
|
| 215 |
+
token = self.tokens[i]
|
| 216 |
+
return i
|
| 217 |
+
|
| 218 |
+
# Given a starting index, return the index of the previous token on channel.
|
| 219 |
+
# Return i if tokens[i] is on channel. Return -1 if there are no tokens
|
| 220 |
+
# on channel between i and 0.
|
| 221 |
+
def previousTokenOnChannel(self, i:int, channel:int):
|
| 222 |
+
while i>=0 and self.tokens[i].channel!=channel:
|
| 223 |
+
i -= 1
|
| 224 |
+
return i
|
| 225 |
+
|
| 226 |
+
# Collect all tokens on specified channel to the right of
|
| 227 |
+
# the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
|
| 228 |
+
# EOF. If channel is -1, find any non default channel token.
|
| 229 |
+
def getHiddenTokensToRight(self, tokenIndex:int, channel:int=-1):
|
| 230 |
+
self.lazyInit()
|
| 231 |
+
if tokenIndex<0 or tokenIndex>=len(self.tokens):
|
| 232 |
+
raise Exception(str(tokenIndex) + " not in 0.." + str(len(self.tokens)-1))
|
| 233 |
+
from antlr4.Lexer import Lexer
|
| 234 |
+
nextOnChannel = self.nextTokenOnChannel(tokenIndex + 1, Lexer.DEFAULT_TOKEN_CHANNEL)
|
| 235 |
+
from_ = tokenIndex+1
|
| 236 |
+
# if none onchannel to right, nextOnChannel=-1 so set to = last token
|
| 237 |
+
to = (len(self.tokens)-1) if nextOnChannel==-1 else nextOnChannel
|
| 238 |
+
return self.filterForChannel(from_, to, channel)
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
# Collect all tokens on specified channel to the left of
|
| 242 |
+
# the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
| 243 |
+
# If channel is -1, find any non default channel token.
|
| 244 |
+
def getHiddenTokensToLeft(self, tokenIndex:int, channel:int=-1):
|
| 245 |
+
self.lazyInit()
|
| 246 |
+
if tokenIndex<0 or tokenIndex>=len(self.tokens):
|
| 247 |
+
raise Exception(str(tokenIndex) + " not in 0.." + str(len(self.tokens)-1))
|
| 248 |
+
from antlr4.Lexer import Lexer
|
| 249 |
+
prevOnChannel = self.previousTokenOnChannel(tokenIndex - 1, Lexer.DEFAULT_TOKEN_CHANNEL)
|
| 250 |
+
if prevOnChannel == tokenIndex - 1:
|
| 251 |
+
return None
|
| 252 |
+
# if none on channel to left, prevOnChannel=-1 then from=0
|
| 253 |
+
from_ = prevOnChannel+1
|
| 254 |
+
to = tokenIndex-1
|
| 255 |
+
return self.filterForChannel(from_, to, channel)
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
def filterForChannel(self, left:int, right:int, channel:int):
|
| 259 |
+
hidden = []
|
| 260 |
+
for i in range(left, right+1):
|
| 261 |
+
t = self.tokens[i]
|
| 262 |
+
if channel==-1:
|
| 263 |
+
from antlr4.Lexer import Lexer
|
| 264 |
+
if t.channel!= Lexer.DEFAULT_TOKEN_CHANNEL:
|
| 265 |
+
hidden.append(t)
|
| 266 |
+
elif t.channel==channel:
|
| 267 |
+
hidden.append(t)
|
| 268 |
+
if len(hidden)==0:
|
| 269 |
+
return None
|
| 270 |
+
return hidden
|
| 271 |
+
|
| 272 |
+
def getSourceName(self):
|
| 273 |
+
return self.tokenSource.getSourceName()
|
| 274 |
+
|
| 275 |
+
# Get the text of all tokens in this buffer.#/
|
| 276 |
+
def getText(self, start:int=None, stop:int=None):
|
| 277 |
+
self.lazyInit()
|
| 278 |
+
self.fill()
|
| 279 |
+
if isinstance(start, Token):
|
| 280 |
+
start = start.tokenIndex
|
| 281 |
+
elif start is None:
|
| 282 |
+
start = 0
|
| 283 |
+
if isinstance(stop, Token):
|
| 284 |
+
stop = stop.tokenIndex
|
| 285 |
+
elif stop is None or stop >= len(self.tokens):
|
| 286 |
+
stop = len(self.tokens) - 1
|
| 287 |
+
if start < 0 or stop < 0 or stop < start:
|
| 288 |
+
return ""
|
| 289 |
+
with StringIO() as buf:
|
| 290 |
+
for i in range(start, stop+1):
|
| 291 |
+
t = self.tokens[i]
|
| 292 |
+
if t.type==Token.EOF:
|
| 293 |
+
break
|
| 294 |
+
buf.write(t.text)
|
| 295 |
+
return buf.getvalue()
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
# Get all tokens from lexer until EOF#/
|
| 299 |
+
def fill(self):
|
| 300 |
+
self.lazyInit()
|
| 301 |
+
while self.fetch(1000)==1000:
|
| 302 |
+
pass
|
cameras/deps/antlr4/CommonTokenFactory.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
#
|
| 8 |
+
# This default implementation of {@link TokenFactory} creates
|
| 9 |
+
# {@link CommonToken} objects.
|
| 10 |
+
#
|
| 11 |
+
from antlr4.Token import CommonToken
|
| 12 |
+
|
| 13 |
+
class TokenFactory(object):
|
| 14 |
+
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
class CommonTokenFactory(TokenFactory):
|
| 18 |
+
__slots__ = 'copyText'
|
| 19 |
+
|
| 20 |
+
#
|
| 21 |
+
# The default {@link CommonTokenFactory} instance.
|
| 22 |
+
#
|
| 23 |
+
# <p>
|
| 24 |
+
# This token factory does not explicitly copy token text when constructing
|
| 25 |
+
# tokens.</p>
|
| 26 |
+
#
|
| 27 |
+
DEFAULT = None
|
| 28 |
+
|
| 29 |
+
def __init__(self, copyText:bool=False):
|
| 30 |
+
# Indicates whether {@link CommonToken#setText} should be called after
|
| 31 |
+
# constructing tokens to explicitly set the text. This is useful for cases
|
| 32 |
+
# where the input stream might not be able to provide arbitrary substrings
|
| 33 |
+
# of text from the input after the lexer creates a token (e.g. the
|
| 34 |
+
# implementation of {@link CharStream#getText} in
|
| 35 |
+
# {@link UnbufferedCharStream} throws an
|
| 36 |
+
# {@link UnsupportedOperationException}). Explicitly setting the token text
|
| 37 |
+
# allows {@link Token#getText} to be called at any time regardless of the
|
| 38 |
+
# input stream implementation.
|
| 39 |
+
#
|
| 40 |
+
# <p>
|
| 41 |
+
# The default value is {@code false} to avoid the performance and memory
|
| 42 |
+
# overhead of copying text for every token unless explicitly requested.</p>
|
| 43 |
+
#
|
| 44 |
+
self.copyText = copyText
|
| 45 |
+
|
| 46 |
+
def create(self, source, type:int, text:str, channel:int, start:int, stop:int, line:int, column:int):
|
| 47 |
+
t = CommonToken(source, type, channel, start, stop)
|
| 48 |
+
t.line = line
|
| 49 |
+
t.column = column
|
| 50 |
+
if text is not None:
|
| 51 |
+
t.text = text
|
| 52 |
+
elif self.copyText and source[1] is not None:
|
| 53 |
+
t.text = source[1].getText(start,stop)
|
| 54 |
+
return t
|
| 55 |
+
|
| 56 |
+
def createThin(self, type:int, text:str):
|
| 57 |
+
t = CommonToken(type=type)
|
| 58 |
+
t.text = text
|
| 59 |
+
return t
|
| 60 |
+
|
| 61 |
+
CommonTokenFactory.DEFAULT = CommonTokenFactory()
|
cameras/deps/antlr4/CommonTokenStream.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
#
|
| 8 |
+
# This class extends {@link BufferedTokenStream} with functionality to filter
|
| 9 |
+
# token streams to tokens on a particular channel (tokens where
|
| 10 |
+
# {@link Token#getChannel} returns a particular value).
|
| 11 |
+
#
|
| 12 |
+
# <p>
|
| 13 |
+
# This token stream provides access to all tokens by index or when calling
|
| 14 |
+
# methods like {@link #getText}. The channel filtering is only used for code
|
| 15 |
+
# accessing tokens via the lookahead methods {@link #LA}, {@link #LT}, and
|
| 16 |
+
# {@link #LB}.</p>
|
| 17 |
+
#
|
| 18 |
+
# <p>
|
| 19 |
+
# By default, tokens are placed on the default channel
|
| 20 |
+
# ({@link Token#DEFAULT_CHANNEL}), but may be reassigned by using the
|
| 21 |
+
# {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to
|
| 22 |
+
# call {@link Lexer#setChannel}.
|
| 23 |
+
# </p>
|
| 24 |
+
#
|
| 25 |
+
# <p>
|
| 26 |
+
# Note: lexer rules which use the {@code ->skip} lexer command or call
|
| 27 |
+
# {@link Lexer#skip} do not produce tokens at all, so input text matched by
|
| 28 |
+
# such a rule will not be available as part of the token stream, regardless of
|
| 29 |
+
# channel.</p>
|
| 30 |
+
#/
|
| 31 |
+
|
| 32 |
+
from antlr4.BufferedTokenStream import BufferedTokenStream
|
| 33 |
+
from antlr4.Lexer import Lexer
|
| 34 |
+
from antlr4.Token import Token
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class CommonTokenStream(BufferedTokenStream):
|
| 38 |
+
__slots__ = 'channel'
|
| 39 |
+
|
| 40 |
+
def __init__(self, lexer:Lexer, channel:int=Token.DEFAULT_CHANNEL):
|
| 41 |
+
super().__init__(lexer)
|
| 42 |
+
self.channel = channel
|
| 43 |
+
|
| 44 |
+
def adjustSeekIndex(self, i:int):
|
| 45 |
+
return self.nextTokenOnChannel(i, self.channel)
|
| 46 |
+
|
| 47 |
+
def LB(self, k:int):
|
| 48 |
+
if k==0 or (self.index-k)<0:
|
| 49 |
+
return None
|
| 50 |
+
i = self.index
|
| 51 |
+
n = 1
|
| 52 |
+
# find k good tokens looking backwards
|
| 53 |
+
while n <= k:
|
| 54 |
+
# skip off-channel tokens
|
| 55 |
+
i = self.previousTokenOnChannel(i - 1, self.channel)
|
| 56 |
+
n += 1
|
| 57 |
+
if i < 0:
|
| 58 |
+
return None
|
| 59 |
+
return self.tokens[i]
|
| 60 |
+
|
| 61 |
+
def LT(self, k:int):
|
| 62 |
+
self.lazyInit()
|
| 63 |
+
if k == 0:
|
| 64 |
+
return None
|
| 65 |
+
if k < 0:
|
| 66 |
+
return self.LB(-k)
|
| 67 |
+
i = self.index
|
| 68 |
+
n = 1 # we know tokens[pos] is a good one
|
| 69 |
+
# find k good tokens
|
| 70 |
+
while n < k:
|
| 71 |
+
# skip off-channel tokens, but make sure to not look past EOF
|
| 72 |
+
if self.sync(i + 1):
|
| 73 |
+
i = self.nextTokenOnChannel(i + 1, self.channel)
|
| 74 |
+
n += 1
|
| 75 |
+
return self.tokens[i]
|
| 76 |
+
|
| 77 |
+
# Count EOF just once.#/
|
| 78 |
+
def getNumberOfOnChannelTokens(self):
|
| 79 |
+
n = 0
|
| 80 |
+
self.fill()
|
| 81 |
+
for i in range(0, len(self.tokens)):
|
| 82 |
+
t = self.tokens[i]
|
| 83 |
+
if t.channel==self.channel:
|
| 84 |
+
n += 1
|
| 85 |
+
if t.type==Token.EOF:
|
| 86 |
+
break
|
| 87 |
+
return n
|
cameras/deps/antlr4/FileStream.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
#
|
| 8 |
+
# This is an InputStream that is loaded from a file all at once
|
| 9 |
+
# when you construct the object.
|
| 10 |
+
#
|
| 11 |
+
|
| 12 |
+
import codecs
|
| 13 |
+
from antlr4.InputStream import InputStream
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class FileStream(InputStream):
|
| 17 |
+
__slots__ = 'fileName'
|
| 18 |
+
|
| 19 |
+
def __init__(self, fileName:str, encoding:str='ascii', errors:str='strict'):
|
| 20 |
+
super().__init__(self.readDataFrom(fileName, encoding, errors))
|
| 21 |
+
self.fileName = fileName
|
| 22 |
+
|
| 23 |
+
def readDataFrom(self, fileName:str, encoding:str, errors:str='strict'):
|
| 24 |
+
# read binary to avoid line ending conversion
|
| 25 |
+
with open(fileName, 'rb') as file:
|
| 26 |
+
bytes = file.read()
|
| 27 |
+
return codecs.decode(bytes, encoding, errors)
|
cameras/deps/antlr4/InputStream.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
#
|
| 9 |
+
# Vacuum all input from a string and then treat it like a buffer.
|
| 10 |
+
#
|
| 11 |
+
from antlr4.Token import Token
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class InputStream (object):
|
| 15 |
+
__slots__ = ('name', 'strdata', '_index', 'data', '_size')
|
| 16 |
+
|
| 17 |
+
def __init__(self, data: str):
|
| 18 |
+
self.name = "<empty>"
|
| 19 |
+
self.strdata = data
|
| 20 |
+
self._loadString()
|
| 21 |
+
|
| 22 |
+
def _loadString(self):
|
| 23 |
+
self._index = 0
|
| 24 |
+
self.data = [ord(c) for c in self.strdata]
|
| 25 |
+
self._size = len(self.data)
|
| 26 |
+
|
| 27 |
+
@property
|
| 28 |
+
def index(self):
|
| 29 |
+
return self._index
|
| 30 |
+
|
| 31 |
+
@property
|
| 32 |
+
def size(self):
|
| 33 |
+
return self._size
|
| 34 |
+
|
| 35 |
+
# Reset the stream so that it's in the same state it was
|
| 36 |
+
# when the object was created *except* the data array is not
|
| 37 |
+
# touched.
|
| 38 |
+
#
|
| 39 |
+
def reset(self):
|
| 40 |
+
self._index = 0
|
| 41 |
+
|
| 42 |
+
def consume(self):
|
| 43 |
+
if self._index >= self._size:
|
| 44 |
+
assert self.LA(1) == Token.EOF
|
| 45 |
+
raise Exception("cannot consume EOF")
|
| 46 |
+
self._index += 1
|
| 47 |
+
|
| 48 |
+
def LA(self, offset: int):
|
| 49 |
+
if offset==0:
|
| 50 |
+
return 0 # undefined
|
| 51 |
+
if offset<0:
|
| 52 |
+
offset += 1 # e.g., translate LA(-1) to use offset=0
|
| 53 |
+
pos = self._index + offset - 1
|
| 54 |
+
if pos < 0 or pos >= self._size: # invalid
|
| 55 |
+
return Token.EOF
|
| 56 |
+
return self.data[pos]
|
| 57 |
+
|
| 58 |
+
def LT(self, offset: int):
|
| 59 |
+
return self.LA(offset)
|
| 60 |
+
|
| 61 |
+
# mark/release do nothing; we have entire buffer
|
| 62 |
+
def mark(self):
|
| 63 |
+
return -1
|
| 64 |
+
|
| 65 |
+
def release(self, marker: int):
|
| 66 |
+
pass
|
| 67 |
+
|
| 68 |
+
# consume() ahead until p==_index; can't just set p=_index as we must
|
| 69 |
+
# update line and column. If we seek backwards, just set p
|
| 70 |
+
#
|
| 71 |
+
def seek(self, _index: int):
|
| 72 |
+
if _index<=self._index:
|
| 73 |
+
self._index = _index # just jump; don't update stream state (line, ...)
|
| 74 |
+
return
|
| 75 |
+
# seek forward
|
| 76 |
+
self._index = min(_index, self._size)
|
| 77 |
+
|
| 78 |
+
def getText(self, start :int, stop: int):
|
| 79 |
+
if stop >= self._size:
|
| 80 |
+
stop = self._size-1
|
| 81 |
+
if start >= self._size:
|
| 82 |
+
return ""
|
| 83 |
+
else:
|
| 84 |
+
return self.strdata[start:stop+1]
|
| 85 |
+
|
| 86 |
+
def __str__(self):
|
| 87 |
+
return self.strdata
|
cameras/deps/antlr4/IntervalSet.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
from io import StringIO
|
| 8 |
+
from antlr4.Token import Token
|
| 9 |
+
|
| 10 |
+
# need forward declarations
|
| 11 |
+
IntervalSet = None
|
| 12 |
+
|
| 13 |
+
class IntervalSet(object):
|
| 14 |
+
__slots__ = ('intervals', 'readonly')
|
| 15 |
+
|
| 16 |
+
def __init__(self):
|
| 17 |
+
self.intervals = None
|
| 18 |
+
self.readonly = False
|
| 19 |
+
|
| 20 |
+
def __iter__(self):
|
| 21 |
+
if self.intervals is not None:
|
| 22 |
+
for i in self.intervals:
|
| 23 |
+
for c in i:
|
| 24 |
+
yield c
|
| 25 |
+
|
| 26 |
+
def __getitem__(self, item):
|
| 27 |
+
i = 0
|
| 28 |
+
for k in self:
|
| 29 |
+
if i==item:
|
| 30 |
+
return k
|
| 31 |
+
else:
|
| 32 |
+
i += 1
|
| 33 |
+
return Token.INVALID_TYPE
|
| 34 |
+
|
| 35 |
+
def addOne(self, v:int):
|
| 36 |
+
self.addRange(range(v, v+1))
|
| 37 |
+
|
| 38 |
+
def addRange(self, v:range):
|
| 39 |
+
if self.intervals is None:
|
| 40 |
+
self.intervals = list()
|
| 41 |
+
self.intervals.append(v)
|
| 42 |
+
else:
|
| 43 |
+
# find insert pos
|
| 44 |
+
k = 0
|
| 45 |
+
for i in self.intervals:
|
| 46 |
+
# distinct range -> insert
|
| 47 |
+
if v.stop<i.start:
|
| 48 |
+
self.intervals.insert(k, v)
|
| 49 |
+
return
|
| 50 |
+
# contiguous range -> adjust
|
| 51 |
+
elif v.stop==i.start:
|
| 52 |
+
self.intervals[k] = range(v.start, i.stop)
|
| 53 |
+
return
|
| 54 |
+
# overlapping range -> adjust and reduce
|
| 55 |
+
elif v.start<=i.stop:
|
| 56 |
+
self.intervals[k] = range(min(i.start,v.start), max(i.stop,v.stop))
|
| 57 |
+
self.reduce(k)
|
| 58 |
+
return
|
| 59 |
+
k += 1
|
| 60 |
+
# greater than any existing
|
| 61 |
+
self.intervals.append(v)
|
| 62 |
+
|
| 63 |
+
def addSet(self, other:IntervalSet):
|
| 64 |
+
if other.intervals is not None:
|
| 65 |
+
for i in other.intervals:
|
| 66 |
+
self.addRange(i)
|
| 67 |
+
return self
|
| 68 |
+
|
| 69 |
+
def reduce(self, k:int):
|
| 70 |
+
# only need to reduce if k is not the last
|
| 71 |
+
if k<len(self.intervals)-1:
|
| 72 |
+
l = self.intervals[k]
|
| 73 |
+
r = self.intervals[k+1]
|
| 74 |
+
# if r contained in l
|
| 75 |
+
if l.stop >= r.stop:
|
| 76 |
+
self.intervals.pop(k+1)
|
| 77 |
+
self.reduce(k)
|
| 78 |
+
elif l.stop >= r.start:
|
| 79 |
+
self.intervals[k] = range(l.start, r.stop)
|
| 80 |
+
self.intervals.pop(k+1)
|
| 81 |
+
|
| 82 |
+
def complement(self, start, stop):
|
| 83 |
+
result = IntervalSet()
|
| 84 |
+
result.addRange(range(start,stop+1))
|
| 85 |
+
for i in self.intervals:
|
| 86 |
+
result.removeRange(i)
|
| 87 |
+
return result
|
| 88 |
+
|
| 89 |
+
def __contains__(self, item):
|
| 90 |
+
if self.intervals is None:
|
| 91 |
+
return False
|
| 92 |
+
else:
|
| 93 |
+
return any(item in i for i in self.intervals)
|
| 94 |
+
|
| 95 |
+
def __len__(self):
|
| 96 |
+
return sum(len(i) for i in self.intervals)
|
| 97 |
+
|
| 98 |
+
def removeRange(self, v):
|
| 99 |
+
if v.start==v.stop-1:
|
| 100 |
+
self.removeOne(v.start)
|
| 101 |
+
elif self.intervals is not None:
|
| 102 |
+
k = 0
|
| 103 |
+
for i in self.intervals:
|
| 104 |
+
# intervals are ordered
|
| 105 |
+
if v.stop<=i.start:
|
| 106 |
+
return
|
| 107 |
+
# check for including range, split it
|
| 108 |
+
elif v.start>i.start and v.stop<i.stop:
|
| 109 |
+
self.intervals[k] = range(i.start, v.start)
|
| 110 |
+
x = range(v.stop, i.stop)
|
| 111 |
+
self.intervals.insert(k, x)
|
| 112 |
+
return
|
| 113 |
+
# check for included range, remove it
|
| 114 |
+
elif v.start<=i.start and v.stop>=i.stop:
|
| 115 |
+
self.intervals.pop(k)
|
| 116 |
+
k -= 1 # need another pass
|
| 117 |
+
# check for lower boundary
|
| 118 |
+
elif v.start<i.stop:
|
| 119 |
+
self.intervals[k] = range(i.start, v.start)
|
| 120 |
+
# check for upper boundary
|
| 121 |
+
elif v.stop<i.stop:
|
| 122 |
+
self.intervals[k] = range(v.stop, i.stop)
|
| 123 |
+
k += 1
|
| 124 |
+
|
| 125 |
+
def removeOne(self, v):
|
| 126 |
+
if self.intervals is not None:
|
| 127 |
+
k = 0
|
| 128 |
+
for i in self.intervals:
|
| 129 |
+
# intervals is ordered
|
| 130 |
+
if v<i.start:
|
| 131 |
+
return
|
| 132 |
+
# check for single value range
|
| 133 |
+
elif v==i.start and v==i.stop-1:
|
| 134 |
+
self.intervals.pop(k)
|
| 135 |
+
return
|
| 136 |
+
# check for lower boundary
|
| 137 |
+
elif v==i.start:
|
| 138 |
+
self.intervals[k] = range(i.start+1, i.stop)
|
| 139 |
+
return
|
| 140 |
+
# check for upper boundary
|
| 141 |
+
elif v==i.stop-1:
|
| 142 |
+
self.intervals[k] = range(i.start, i.stop-1)
|
| 143 |
+
return
|
| 144 |
+
# split existing range
|
| 145 |
+
elif v<i.stop-1:
|
| 146 |
+
x = range(i.start, v)
|
| 147 |
+
self.intervals[k] = range(v + 1, i.stop)
|
| 148 |
+
self.intervals.insert(k, x)
|
| 149 |
+
return
|
| 150 |
+
k += 1
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
def toString(self, literalNames:list, symbolicNames:list):
|
| 154 |
+
if self.intervals is None:
|
| 155 |
+
return "{}"
|
| 156 |
+
with StringIO() as buf:
|
| 157 |
+
if len(self)>1:
|
| 158 |
+
buf.write("{")
|
| 159 |
+
first = True
|
| 160 |
+
for i in self.intervals:
|
| 161 |
+
for j in i:
|
| 162 |
+
if not first:
|
| 163 |
+
buf.write(", ")
|
| 164 |
+
buf.write(self.elementName(literalNames, symbolicNames, j))
|
| 165 |
+
first = False
|
| 166 |
+
if len(self)>1:
|
| 167 |
+
buf.write("}")
|
| 168 |
+
return buf.getvalue()
|
| 169 |
+
|
| 170 |
+
def elementName(self, literalNames:list, symbolicNames:list, a:int):
|
| 171 |
+
if a==Token.EOF:
|
| 172 |
+
return "<EOF>"
|
| 173 |
+
elif a==Token.EPSILON:
|
| 174 |
+
return "<EPSILON>"
|
| 175 |
+
else:
|
| 176 |
+
if a<len(literalNames) and literalNames[a] != "<INVALID>":
|
| 177 |
+
return literalNames[a]
|
| 178 |
+
if a<len(symbolicNames):
|
| 179 |
+
return symbolicNames[a]
|
| 180 |
+
return "<UNKNOWN>"
|
cameras/deps/antlr4/LL1Analyzer.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
from antlr4.IntervalSet import IntervalSet
|
| 7 |
+
from antlr4.Token import Token
|
| 8 |
+
from antlr4.PredictionContext import PredictionContext, SingletonPredictionContext, PredictionContextFromRuleContext
|
| 9 |
+
from antlr4.RuleContext import RuleContext
|
| 10 |
+
from antlr4.atn.ATN import ATN
|
| 11 |
+
from antlr4.atn.ATNConfig import ATNConfig
|
| 12 |
+
from antlr4.atn.ATNState import ATNState, RuleStopState
|
| 13 |
+
from antlr4.atn.Transition import WildcardTransition, NotSetTransition, AbstractPredicateTransition, RuleTransition
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class LL1Analyzer (object):
|
| 17 |
+
__slots__ = 'atn'
|
| 18 |
+
|
| 19 |
+
#* Special value added to the lookahead sets to indicate that we hit
|
| 20 |
+
# a predicate during analysis if {@code seeThruPreds==false}.
|
| 21 |
+
#/
|
| 22 |
+
HIT_PRED = Token.INVALID_TYPE
|
| 23 |
+
|
| 24 |
+
def __init__(self, atn:ATN):
|
| 25 |
+
self.atn = atn
|
| 26 |
+
|
| 27 |
+
#*
|
| 28 |
+
# Calculates the SLL(1) expected lookahead set for each outgoing transition
|
| 29 |
+
# of an {@link ATNState}. The returned array has one element for each
|
| 30 |
+
# outgoing transition in {@code s}. If the closure from transition
|
| 31 |
+
# <em>i</em> leads to a semantic predicate before matching a symbol, the
|
| 32 |
+
# element at index <em>i</em> of the result will be {@code null}.
|
| 33 |
+
#
|
| 34 |
+
# @param s the ATN state
|
| 35 |
+
# @return the expected symbols for each outgoing transition of {@code s}.
|
| 36 |
+
#/
|
| 37 |
+
def getDecisionLookahead(self, s:ATNState):
|
| 38 |
+
if s is None:
|
| 39 |
+
return None
|
| 40 |
+
|
| 41 |
+
count = len(s.transitions)
|
| 42 |
+
look = [] * count
|
| 43 |
+
for alt in range(0, count):
|
| 44 |
+
look[alt] = set()
|
| 45 |
+
lookBusy = set()
|
| 46 |
+
seeThruPreds = False # fail to get lookahead upon pred
|
| 47 |
+
self._LOOK(s.transition(alt).target, None, PredictionContext.EMPTY,
|
| 48 |
+
look[alt], lookBusy, set(), seeThruPreds, False)
|
| 49 |
+
# Wipe out lookahead for this alternative if we found nothing
|
| 50 |
+
# or we had a predicate when we !seeThruPreds
|
| 51 |
+
if len(look[alt])==0 or self.HIT_PRED in look[alt]:
|
| 52 |
+
look[alt] = None
|
| 53 |
+
return look
|
| 54 |
+
|
| 55 |
+
#*
|
| 56 |
+
# Compute set of tokens that can follow {@code s} in the ATN in the
|
| 57 |
+
# specified {@code ctx}.
|
| 58 |
+
#
|
| 59 |
+
# <p>If {@code ctx} is {@code null} and the end of the rule containing
|
| 60 |
+
# {@code s} is reached, {@link Token#EPSILON} is added to the result set.
|
| 61 |
+
# If {@code ctx} is not {@code null} and the end of the outermost rule is
|
| 62 |
+
# reached, {@link Token#EOF} is added to the result set.</p>
|
| 63 |
+
#
|
| 64 |
+
# @param s the ATN state
|
| 65 |
+
# @param stopState the ATN state to stop at. This can be a
|
| 66 |
+
# {@link BlockEndState} to detect epsilon paths through a closure.
|
| 67 |
+
# @param ctx the complete parser context, or {@code null} if the context
|
| 68 |
+
# should be ignored
|
| 69 |
+
#
|
| 70 |
+
# @return The set of tokens that can follow {@code s} in the ATN in the
|
| 71 |
+
# specified {@code ctx}.
|
| 72 |
+
#/
|
| 73 |
+
def LOOK(self, s:ATNState, stopState:ATNState=None, ctx:RuleContext=None):
|
| 74 |
+
r = IntervalSet()
|
| 75 |
+
seeThruPreds = True # ignore preds; get all lookahead
|
| 76 |
+
lookContext = PredictionContextFromRuleContext(s.atn, ctx) if ctx is not None else None
|
| 77 |
+
self._LOOK(s, stopState, lookContext, r, set(), set(), seeThruPreds, True)
|
| 78 |
+
return r
|
| 79 |
+
|
| 80 |
+
#*
|
| 81 |
+
# Compute set of tokens that can follow {@code s} in the ATN in the
|
| 82 |
+
# specified {@code ctx}.
|
| 83 |
+
#
|
| 84 |
+
# <p>If {@code ctx} is {@code null} and {@code stopState} or the end of the
|
| 85 |
+
# rule containing {@code s} is reached, {@link Token#EPSILON} is added to
|
| 86 |
+
# the result set. If {@code ctx} is not {@code null} and {@code addEOF} is
|
| 87 |
+
# {@code true} and {@code stopState} or the end of the outermost rule is
|
| 88 |
+
# reached, {@link Token#EOF} is added to the result set.</p>
|
| 89 |
+
#
|
| 90 |
+
# @param s the ATN state.
|
| 91 |
+
# @param stopState the ATN state to stop at. This can be a
|
| 92 |
+
# {@link BlockEndState} to detect epsilon paths through a closure.
|
| 93 |
+
# @param ctx The outer context, or {@code null} if the outer context should
|
| 94 |
+
# not be used.
|
| 95 |
+
# @param look The result lookahead set.
|
| 96 |
+
# @param lookBusy A set used for preventing epsilon closures in the ATN
|
| 97 |
+
# from causing a stack overflow. Outside code should pass
|
| 98 |
+
# {@code new HashSet<ATNConfig>} for this argument.
|
| 99 |
+
# @param calledRuleStack A set used for preventing left recursion in the
|
| 100 |
+
# ATN from causing a stack overflow. Outside code should pass
|
| 101 |
+
# {@code new BitSet()} for this argument.
|
| 102 |
+
# @param seeThruPreds {@code true} to true semantic predicates as
|
| 103 |
+
# implicitly {@code true} and "see through them", otherwise {@code false}
|
| 104 |
+
# to treat semantic predicates as opaque and add {@link #HIT_PRED} to the
|
| 105 |
+
# result if one is encountered.
|
| 106 |
+
# @param addEOF Add {@link Token#EOF} to the result if the end of the
|
| 107 |
+
# outermost context is reached. This parameter has no effect if {@code ctx}
|
| 108 |
+
# is {@code null}.
|
| 109 |
+
#/
|
| 110 |
+
def _LOOK(self, s:ATNState, stopState:ATNState , ctx:PredictionContext, look:IntervalSet, lookBusy:set,
|
| 111 |
+
calledRuleStack:set, seeThruPreds:bool, addEOF:bool):
|
| 112 |
+
c = ATNConfig(s, 0, ctx)
|
| 113 |
+
|
| 114 |
+
if c in lookBusy:
|
| 115 |
+
return
|
| 116 |
+
lookBusy.add(c)
|
| 117 |
+
|
| 118 |
+
if s == stopState:
|
| 119 |
+
if ctx is None:
|
| 120 |
+
look.addOne(Token.EPSILON)
|
| 121 |
+
return
|
| 122 |
+
elif ctx.isEmpty() and addEOF:
|
| 123 |
+
look.addOne(Token.EOF)
|
| 124 |
+
return
|
| 125 |
+
|
| 126 |
+
if isinstance(s, RuleStopState ):
|
| 127 |
+
if ctx is None:
|
| 128 |
+
look.addOne(Token.EPSILON)
|
| 129 |
+
return
|
| 130 |
+
elif ctx.isEmpty() and addEOF:
|
| 131 |
+
look.addOne(Token.EOF)
|
| 132 |
+
return
|
| 133 |
+
|
| 134 |
+
if ctx != PredictionContext.EMPTY:
|
| 135 |
+
removed = s.ruleIndex in calledRuleStack
|
| 136 |
+
try:
|
| 137 |
+
calledRuleStack.discard(s.ruleIndex)
|
| 138 |
+
# run thru all possible stack tops in ctx
|
| 139 |
+
for i in range(0, len(ctx)):
|
| 140 |
+
returnState = self.atn.states[ctx.getReturnState(i)]
|
| 141 |
+
self._LOOK(returnState, stopState, ctx.getParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
| 142 |
+
finally:
|
| 143 |
+
if removed:
|
| 144 |
+
calledRuleStack.add(s.ruleIndex)
|
| 145 |
+
return
|
| 146 |
+
|
| 147 |
+
for t in s.transitions:
|
| 148 |
+
if type(t) == RuleTransition:
|
| 149 |
+
if t.target.ruleIndex in calledRuleStack:
|
| 150 |
+
continue
|
| 151 |
+
|
| 152 |
+
newContext = SingletonPredictionContext.create(ctx, t.followState.stateNumber)
|
| 153 |
+
|
| 154 |
+
try:
|
| 155 |
+
calledRuleStack.add(t.target.ruleIndex)
|
| 156 |
+
self._LOOK(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
| 157 |
+
finally:
|
| 158 |
+
calledRuleStack.remove(t.target.ruleIndex)
|
| 159 |
+
elif isinstance(t, AbstractPredicateTransition ):
|
| 160 |
+
if seeThruPreds:
|
| 161 |
+
self._LOOK(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
| 162 |
+
else:
|
| 163 |
+
look.addOne(self.HIT_PRED)
|
| 164 |
+
elif t.isEpsilon:
|
| 165 |
+
self._LOOK(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
| 166 |
+
elif type(t) == WildcardTransition:
|
| 167 |
+
look.addRange( range(Token.MIN_USER_TOKEN_TYPE, self.atn.maxTokenType + 1) )
|
| 168 |
+
else:
|
| 169 |
+
set_ = t.label
|
| 170 |
+
if set_ is not None:
|
| 171 |
+
if isinstance(t, NotSetTransition):
|
| 172 |
+
set_ = set_.complement(Token.MIN_USER_TOKEN_TYPE, self.atn.maxTokenType)
|
| 173 |
+
look.addSet(set_)
|
cameras/deps/antlr4/Lexer.py
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#/
|
| 5 |
+
|
| 6 |
+
# A lexer is recognizer that draws input symbols from a character stream.
|
| 7 |
+
# lexer grammars result in a subclass of self object. A Lexer object
|
| 8 |
+
# uses simplified match() and error recovery mechanisms in the interest
|
| 9 |
+
# of speed.
|
| 10 |
+
#/
|
| 11 |
+
from io import StringIO
|
| 12 |
+
|
| 13 |
+
import sys
|
| 14 |
+
if sys.version_info[1] > 5:
|
| 15 |
+
from typing import TextIO
|
| 16 |
+
else:
|
| 17 |
+
from typing.io import TextIO
|
| 18 |
+
from antlr4.CommonTokenFactory import CommonTokenFactory
|
| 19 |
+
from antlr4.atn.LexerATNSimulator import LexerATNSimulator
|
| 20 |
+
from antlr4.InputStream import InputStream
|
| 21 |
+
from antlr4.Recognizer import Recognizer
|
| 22 |
+
from antlr4.Token import Token
|
| 23 |
+
from antlr4.error.Errors import IllegalStateException, LexerNoViableAltException, RecognitionException
|
| 24 |
+
|
| 25 |
+
class TokenSource(object):
|
| 26 |
+
|
| 27 |
+
pass
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class Lexer(Recognizer, TokenSource):
|
| 31 |
+
__slots__ = (
|
| 32 |
+
'_input', '_output', '_factory', '_tokenFactorySourcePair', '_token',
|
| 33 |
+
'_tokenStartCharIndex', '_tokenStartLine', '_tokenStartColumn',
|
| 34 |
+
'_hitEOF', '_channel', '_type', '_modeStack', '_mode', '_text'
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
DEFAULT_MODE = 0
|
| 38 |
+
MORE = -2
|
| 39 |
+
SKIP = -3
|
| 40 |
+
|
| 41 |
+
DEFAULT_TOKEN_CHANNEL = Token.DEFAULT_CHANNEL
|
| 42 |
+
HIDDEN = Token.HIDDEN_CHANNEL
|
| 43 |
+
MIN_CHAR_VALUE = 0x0000
|
| 44 |
+
MAX_CHAR_VALUE = 0x10FFFF
|
| 45 |
+
|
| 46 |
+
def __init__(self, input:InputStream, output:TextIO = sys.stdout):
|
| 47 |
+
super().__init__()
|
| 48 |
+
self._input = input
|
| 49 |
+
self._output = output
|
| 50 |
+
self._factory = CommonTokenFactory.DEFAULT
|
| 51 |
+
self._tokenFactorySourcePair = (self, input)
|
| 52 |
+
|
| 53 |
+
self._interp = None # child classes must populate this
|
| 54 |
+
|
| 55 |
+
# The goal of all lexer rules/methods is to create a token object.
|
| 56 |
+
# self is an instance variable as multiple rules may collaborate to
|
| 57 |
+
# create a single token. nextToken will return self object after
|
| 58 |
+
# matching lexer rule(s). If you subclass to allow multiple token
|
| 59 |
+
# emissions, then set self to the last token to be matched or
|
| 60 |
+
# something nonnull so that the auto token emit mechanism will not
|
| 61 |
+
# emit another token.
|
| 62 |
+
self._token = None
|
| 63 |
+
|
| 64 |
+
# What character index in the stream did the current token start at?
|
| 65 |
+
# Needed, for example, to get the text for current token. Set at
|
| 66 |
+
# the start of nextToken.
|
| 67 |
+
self._tokenStartCharIndex = -1
|
| 68 |
+
|
| 69 |
+
# The line on which the first character of the token resides#/
|
| 70 |
+
self._tokenStartLine = -1
|
| 71 |
+
|
| 72 |
+
# The character position of first character within the line#/
|
| 73 |
+
self._tokenStartColumn = -1
|
| 74 |
+
|
| 75 |
+
# Once we see EOF on char stream, next token will be EOF.
|
| 76 |
+
# If you have DONE : EOF ; then you see DONE EOF.
|
| 77 |
+
self._hitEOF = False
|
| 78 |
+
|
| 79 |
+
# The channel number for the current token#/
|
| 80 |
+
self._channel = Token.DEFAULT_CHANNEL
|
| 81 |
+
|
| 82 |
+
# The token type for the current token#/
|
| 83 |
+
self._type = Token.INVALID_TYPE
|
| 84 |
+
|
| 85 |
+
self._modeStack = []
|
| 86 |
+
self._mode = self.DEFAULT_MODE
|
| 87 |
+
|
| 88 |
+
# You can set the text for the current token to override what is in
|
| 89 |
+
# the input char buffer. Use setText() or can set self instance var.
|
| 90 |
+
#/
|
| 91 |
+
self._text = None
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def reset(self):
|
| 95 |
+
# wack Lexer state variables
|
| 96 |
+
if self._input is not None:
|
| 97 |
+
self._input.seek(0) # rewind the input
|
| 98 |
+
self._token = None
|
| 99 |
+
self._type = Token.INVALID_TYPE
|
| 100 |
+
self._channel = Token.DEFAULT_CHANNEL
|
| 101 |
+
self._tokenStartCharIndex = -1
|
| 102 |
+
self._tokenStartColumn = -1
|
| 103 |
+
self._tokenStartLine = -1
|
| 104 |
+
self._text = None
|
| 105 |
+
|
| 106 |
+
self._hitEOF = False
|
| 107 |
+
self._mode = Lexer.DEFAULT_MODE
|
| 108 |
+
self._modeStack = []
|
| 109 |
+
|
| 110 |
+
self._interp.reset()
|
| 111 |
+
|
| 112 |
+
# Return a token from self source; i.e., match a token on the char
|
| 113 |
+
# stream.
|
| 114 |
+
def nextToken(self):
|
| 115 |
+
if self._input is None:
|
| 116 |
+
raise IllegalStateException("nextToken requires a non-null input stream.")
|
| 117 |
+
|
| 118 |
+
# Mark start location in char stream so unbuffered streams are
|
| 119 |
+
# guaranteed at least have text of current token
|
| 120 |
+
tokenStartMarker = self._input.mark()
|
| 121 |
+
try:
|
| 122 |
+
while True:
|
| 123 |
+
if self._hitEOF:
|
| 124 |
+
self.emitEOF()
|
| 125 |
+
return self._token
|
| 126 |
+
self._token = None
|
| 127 |
+
self._channel = Token.DEFAULT_CHANNEL
|
| 128 |
+
self._tokenStartCharIndex = self._input.index
|
| 129 |
+
self._tokenStartColumn = self._interp.column
|
| 130 |
+
self._tokenStartLine = self._interp.line
|
| 131 |
+
self._text = None
|
| 132 |
+
continueOuter = False
|
| 133 |
+
while True:
|
| 134 |
+
self._type = Token.INVALID_TYPE
|
| 135 |
+
ttype = self.SKIP
|
| 136 |
+
try:
|
| 137 |
+
ttype = self._interp.match(self._input, self._mode)
|
| 138 |
+
except LexerNoViableAltException as e:
|
| 139 |
+
self.notifyListeners(e) # report error
|
| 140 |
+
self.recover(e)
|
| 141 |
+
if self._input.LA(1)==Token.EOF:
|
| 142 |
+
self._hitEOF = True
|
| 143 |
+
if self._type == Token.INVALID_TYPE:
|
| 144 |
+
self._type = ttype
|
| 145 |
+
if self._type == self.SKIP:
|
| 146 |
+
continueOuter = True
|
| 147 |
+
break
|
| 148 |
+
if self._type!=self.MORE:
|
| 149 |
+
break
|
| 150 |
+
if continueOuter:
|
| 151 |
+
continue
|
| 152 |
+
if self._token is None:
|
| 153 |
+
self.emit()
|
| 154 |
+
return self._token
|
| 155 |
+
finally:
|
| 156 |
+
# make sure we release marker after match or
|
| 157 |
+
# unbuffered char stream will keep buffering
|
| 158 |
+
self._input.release(tokenStartMarker)
|
| 159 |
+
|
| 160 |
+
# Instruct the lexer to skip creating a token for current lexer rule
|
| 161 |
+
# and look for another token. nextToken() knows to keep looking when
|
| 162 |
+
# a lexer rule finishes with token set to SKIP_TOKEN. Recall that
|
| 163 |
+
# if token==null at end of any token rule, it creates one for you
|
| 164 |
+
# and emits it.
|
| 165 |
+
#/
|
| 166 |
+
def skip(self):
|
| 167 |
+
self._type = self.SKIP
|
| 168 |
+
|
| 169 |
+
def more(self):
|
| 170 |
+
self._type = self.MORE
|
| 171 |
+
|
| 172 |
+
def mode(self, m:int):
|
| 173 |
+
self._mode = m
|
| 174 |
+
|
| 175 |
+
def pushMode(self, m:int):
|
| 176 |
+
if self._interp.debug:
|
| 177 |
+
print("pushMode " + str(m), file=self._output)
|
| 178 |
+
self._modeStack.append(self._mode)
|
| 179 |
+
self.mode(m)
|
| 180 |
+
|
| 181 |
+
def popMode(self):
|
| 182 |
+
if len(self._modeStack)==0:
|
| 183 |
+
raise Exception("Empty Stack")
|
| 184 |
+
if self._interp.debug:
|
| 185 |
+
print("popMode back to "+ self._modeStack[:-1], file=self._output)
|
| 186 |
+
self.mode( self._modeStack.pop() )
|
| 187 |
+
return self._mode
|
| 188 |
+
|
| 189 |
+
# Set the char stream and reset the lexer#/
|
| 190 |
+
@property
|
| 191 |
+
def inputStream(self):
|
| 192 |
+
return self._input
|
| 193 |
+
|
| 194 |
+
@inputStream.setter
|
| 195 |
+
def inputStream(self, input:InputStream):
|
| 196 |
+
self._input = None
|
| 197 |
+
self._tokenFactorySourcePair = (self, self._input)
|
| 198 |
+
self.reset()
|
| 199 |
+
self._input = input
|
| 200 |
+
self._tokenFactorySourcePair = (self, self._input)
|
| 201 |
+
|
| 202 |
+
@property
|
| 203 |
+
def sourceName(self):
|
| 204 |
+
return self._input.sourceName
|
| 205 |
+
|
| 206 |
+
# By default does not support multiple emits per nextToken invocation
|
| 207 |
+
# for efficiency reasons. Subclass and override self method, nextToken,
|
| 208 |
+
# and getToken (to push tokens into a list and pull from that list
|
| 209 |
+
# rather than a single variable as self implementation does).
|
| 210 |
+
#/
|
| 211 |
+
def emitToken(self, token:Token):
|
| 212 |
+
self._token = token
|
| 213 |
+
|
| 214 |
+
# The standard method called to automatically emit a token at the
|
| 215 |
+
# outermost lexical rule. The token object should point into the
|
| 216 |
+
# char buffer start..stop. If there is a text override in 'text',
|
| 217 |
+
# use that to set the token's text. Override self method to emit
|
| 218 |
+
# custom Token objects or provide a new factory.
|
| 219 |
+
#/
|
| 220 |
+
def emit(self):
|
| 221 |
+
t = self._factory.create(self._tokenFactorySourcePair, self._type, self._text, self._channel, self._tokenStartCharIndex,
|
| 222 |
+
self.getCharIndex()-1, self._tokenStartLine, self._tokenStartColumn)
|
| 223 |
+
self.emitToken(t)
|
| 224 |
+
return t
|
| 225 |
+
|
| 226 |
+
def emitEOF(self):
|
| 227 |
+
cpos = self.column
|
| 228 |
+
lpos = self.line
|
| 229 |
+
eof = self._factory.create(self._tokenFactorySourcePair, Token.EOF, None, Token.DEFAULT_CHANNEL, self._input.index,
|
| 230 |
+
self._input.index-1, lpos, cpos)
|
| 231 |
+
self.emitToken(eof)
|
| 232 |
+
return eof
|
| 233 |
+
|
| 234 |
+
@property
|
| 235 |
+
def type(self):
|
| 236 |
+
return self._type
|
| 237 |
+
|
| 238 |
+
@type.setter
|
| 239 |
+
def type(self, type:int):
|
| 240 |
+
self._type = type
|
| 241 |
+
|
| 242 |
+
@property
|
| 243 |
+
def line(self):
|
| 244 |
+
return self._interp.line
|
| 245 |
+
|
| 246 |
+
@line.setter
|
| 247 |
+
def line(self, line:int):
|
| 248 |
+
self._interp.line = line
|
| 249 |
+
|
| 250 |
+
@property
|
| 251 |
+
def column(self):
|
| 252 |
+
return self._interp.column
|
| 253 |
+
|
| 254 |
+
@column.setter
|
| 255 |
+
def column(self, column:int):
|
| 256 |
+
self._interp.column = column
|
| 257 |
+
|
| 258 |
+
# What is the index of the current character of lookahead?#/
|
| 259 |
+
def getCharIndex(self):
|
| 260 |
+
return self._input.index
|
| 261 |
+
|
| 262 |
+
# Return the text matched so far for the current token or any
|
| 263 |
+
# text override.
|
| 264 |
+
@property
|
| 265 |
+
def text(self):
|
| 266 |
+
if self._text is not None:
|
| 267 |
+
return self._text
|
| 268 |
+
else:
|
| 269 |
+
return self._interp.getText(self._input)
|
| 270 |
+
|
| 271 |
+
# Set the complete text of self token; it wipes any previous
|
| 272 |
+
# changes to the text.
|
| 273 |
+
@text.setter
|
| 274 |
+
def text(self, txt:str):
|
| 275 |
+
self._text = txt
|
| 276 |
+
|
| 277 |
+
# Return a list of all Token objects in input char stream.
|
| 278 |
+
# Forces load of all tokens. Does not include EOF token.
|
| 279 |
+
#/
|
| 280 |
+
def getAllTokens(self):
|
| 281 |
+
tokens = []
|
| 282 |
+
t = self.nextToken()
|
| 283 |
+
while t.type!=Token.EOF:
|
| 284 |
+
tokens.append(t)
|
| 285 |
+
t = self.nextToken()
|
| 286 |
+
return tokens
|
| 287 |
+
|
| 288 |
+
def notifyListeners(self, e:LexerNoViableAltException):
|
| 289 |
+
start = self._tokenStartCharIndex
|
| 290 |
+
stop = self._input.index
|
| 291 |
+
text = self._input.getText(start, stop)
|
| 292 |
+
msg = "token recognition error at: '" + self.getErrorDisplay(text) + "'"
|
| 293 |
+
listener = self.getErrorListenerDispatch()
|
| 294 |
+
listener.syntaxError(self, None, self._tokenStartLine, self._tokenStartColumn, msg, e)
|
| 295 |
+
|
| 296 |
+
def getErrorDisplay(self, s:str):
|
| 297 |
+
with StringIO() as buf:
|
| 298 |
+
for c in s:
|
| 299 |
+
buf.write(self.getErrorDisplayForChar(c))
|
| 300 |
+
return buf.getvalue()
|
| 301 |
+
|
| 302 |
+
def getErrorDisplayForChar(self, c:str):
|
| 303 |
+
if ord(c[0])==Token.EOF:
|
| 304 |
+
return "<EOF>"
|
| 305 |
+
elif c=='\n':
|
| 306 |
+
return "\\n"
|
| 307 |
+
elif c=='\t':
|
| 308 |
+
return "\\t"
|
| 309 |
+
elif c=='\r':
|
| 310 |
+
return "\\r"
|
| 311 |
+
else:
|
| 312 |
+
return c
|
| 313 |
+
|
| 314 |
+
def getCharErrorDisplay(self, c:str):
|
| 315 |
+
return "'" + self.getErrorDisplayForChar(c) + "'"
|
| 316 |
+
|
| 317 |
+
# Lexers can normally match any char in it's vocabulary after matching
|
| 318 |
+
# a token, so do the easy thing and just kill a character and hope
|
| 319 |
+
# it all works out. You can instead use the rule invocation stack
|
| 320 |
+
# to do sophisticated error recovery if you are in a fragment rule.
|
| 321 |
+
#/
|
| 322 |
+
def recover(self, re:RecognitionException):
|
| 323 |
+
if self._input.LA(1) != Token.EOF:
|
| 324 |
+
if isinstance(re, LexerNoViableAltException):
|
| 325 |
+
# skip a char and try again
|
| 326 |
+
self._interp.consume(self._input)
|
| 327 |
+
else:
|
| 328 |
+
# TODO: Do we lose character or line position information?
|
| 329 |
+
self._input.consume()
|
cameras/deps/antlr4/ListTokenSource.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
#
|
| 8 |
+
# Provides an implementation of {@link TokenSource} as a wrapper around a list
|
| 9 |
+
# of {@link Token} objects.
|
| 10 |
+
#
|
| 11 |
+
# <p>If the final token in the list is an {@link Token#EOF} token, it will be used
|
| 12 |
+
# as the EOF token for every call to {@link #nextToken} after the end of the
|
| 13 |
+
# list is reached. Otherwise, an EOF token will be created.</p>
|
| 14 |
+
#
|
| 15 |
+
from antlr4.CommonTokenFactory import CommonTokenFactory
|
| 16 |
+
from antlr4.Lexer import TokenSource
|
| 17 |
+
from antlr4.Token import Token
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class ListTokenSource(TokenSource):
|
| 21 |
+
__slots__ = ('tokens', 'sourceName', 'pos', 'eofToken', '_factory')
|
| 22 |
+
|
| 23 |
+
# Constructs a new {@link ListTokenSource} instance from the specified
|
| 24 |
+
# collection of {@link Token} objects and source name.
|
| 25 |
+
#
|
| 26 |
+
# @param tokens The collection of {@link Token} objects to provide as a
|
| 27 |
+
# {@link TokenSource}.
|
| 28 |
+
# @param sourceName The name of the {@link TokenSource}. If this value is
|
| 29 |
+
# {@code null}, {@link #getSourceName} will attempt to infer the name from
|
| 30 |
+
# the next {@link Token} (or the previous token if the end of the input has
|
| 31 |
+
# been reached).
|
| 32 |
+
#
|
| 33 |
+
# @exception NullPointerException if {@code tokens} is {@code null}
|
| 34 |
+
#
|
| 35 |
+
def __init__(self, tokens:list, sourceName:str=None):
|
| 36 |
+
if tokens is None:
|
| 37 |
+
raise ReferenceError("tokens cannot be null")
|
| 38 |
+
self.tokens = tokens
|
| 39 |
+
self.sourceName = sourceName
|
| 40 |
+
# The index into {@link #tokens} of token to return by the next call to
|
| 41 |
+
# {@link #nextToken}. The end of the input is indicated by this value
|
| 42 |
+
# being greater than or equal to the number of items in {@link #tokens}.
|
| 43 |
+
self.pos = 0
|
| 44 |
+
# This field caches the EOF token for the token source.
|
| 45 |
+
self.eofToken = None
|
| 46 |
+
# This is the backing field for {@link #getTokenFactory} and
|
| 47 |
+
self._factory = CommonTokenFactory.DEFAULT
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
#
|
| 51 |
+
# {@inheritDoc}
|
| 52 |
+
#
|
| 53 |
+
@property
|
| 54 |
+
def column(self):
|
| 55 |
+
if self.pos < len(self.tokens):
|
| 56 |
+
return self.tokens[self.pos].column
|
| 57 |
+
elif self.eofToken is not None:
|
| 58 |
+
return self.eofToken.column
|
| 59 |
+
elif len(self.tokens) > 0:
|
| 60 |
+
# have to calculate the result from the line/column of the previous
|
| 61 |
+
# token, along with the text of the token.
|
| 62 |
+
lastToken = self.tokens[len(self.tokens) - 1]
|
| 63 |
+
tokenText = lastToken.text
|
| 64 |
+
if tokenText is not None:
|
| 65 |
+
lastNewLine = tokenText.rfind('\n')
|
| 66 |
+
if lastNewLine >= 0:
|
| 67 |
+
return len(tokenText) - lastNewLine - 1
|
| 68 |
+
return lastToken.column + lastToken.stop - lastToken.start + 1
|
| 69 |
+
|
| 70 |
+
# only reach this if tokens is empty, meaning EOF occurs at the first
|
| 71 |
+
# position in the input
|
| 72 |
+
return 0
|
| 73 |
+
|
| 74 |
+
#
|
| 75 |
+
# {@inheritDoc}
|
| 76 |
+
#
|
| 77 |
+
def nextToken(self):
|
| 78 |
+
if self.pos >= len(self.tokens):
|
| 79 |
+
if self.eofToken is None:
|
| 80 |
+
start = -1
|
| 81 |
+
if len(self.tokens) > 0:
|
| 82 |
+
previousStop = self.tokens[len(self.tokens) - 1].stop
|
| 83 |
+
if previousStop != -1:
|
| 84 |
+
start = previousStop + 1
|
| 85 |
+
stop = max(-1, start - 1)
|
| 86 |
+
self.eofToken = self._factory.create((self, self.getInputStream()),
|
| 87 |
+
Token.EOF, "EOF", Token.DEFAULT_CHANNEL, start, stop, self.line, self.column)
|
| 88 |
+
return self.eofToken
|
| 89 |
+
t = self.tokens[self.pos]
|
| 90 |
+
if self.pos == len(self.tokens) - 1 and t.type == Token.EOF:
|
| 91 |
+
self.eofToken = t
|
| 92 |
+
self.pos += 1
|
| 93 |
+
return t
|
| 94 |
+
|
| 95 |
+
#
|
| 96 |
+
# {@inheritDoc}
|
| 97 |
+
#
|
| 98 |
+
@property
|
| 99 |
+
def line(self):
|
| 100 |
+
if self.pos < len(self.tokens):
|
| 101 |
+
return self.tokens[self.pos].line
|
| 102 |
+
elif self.eofToken is not None:
|
| 103 |
+
return self.eofToken.line
|
| 104 |
+
elif len(self.tokens) > 0:
|
| 105 |
+
# have to calculate the result from the line/column of the previous
|
| 106 |
+
# token, along with the text of the token.
|
| 107 |
+
lastToken = self.tokens[len(self.tokens) - 1]
|
| 108 |
+
line = lastToken.line
|
| 109 |
+
tokenText = lastToken.text
|
| 110 |
+
if tokenText is not None:
|
| 111 |
+
line += tokenText.count('\n')
|
| 112 |
+
|
| 113 |
+
# if no text is available, assume the token did not contain any newline characters.
|
| 114 |
+
return line
|
| 115 |
+
|
| 116 |
+
# only reach this if tokens is empty, meaning EOF occurs at the first
|
| 117 |
+
# position in the input
|
| 118 |
+
return 1
|
| 119 |
+
|
| 120 |
+
#
|
| 121 |
+
# {@inheritDoc}
|
| 122 |
+
#
|
| 123 |
+
def getInputStream(self):
|
| 124 |
+
if self.pos < len(self.tokens):
|
| 125 |
+
return self.tokens[self.pos].getInputStream()
|
| 126 |
+
elif self.eofToken is not None:
|
| 127 |
+
return self.eofToken.getInputStream()
|
| 128 |
+
elif len(self.tokens) > 0:
|
| 129 |
+
return self.tokens[len(self.tokens) - 1].getInputStream()
|
| 130 |
+
else:
|
| 131 |
+
# no input stream information is available
|
| 132 |
+
return None
|
| 133 |
+
|
| 134 |
+
#
|
| 135 |
+
# {@inheritDoc}
|
| 136 |
+
#
|
| 137 |
+
def getSourceName(self):
|
| 138 |
+
if self.sourceName is not None:
|
| 139 |
+
return self.sourceName
|
| 140 |
+
inputStream = self.getInputStream()
|
| 141 |
+
if inputStream is not None:
|
| 142 |
+
return inputStream.getSourceName()
|
| 143 |
+
else:
|
| 144 |
+
return "List"
|
cameras/deps/antlr4/Parser.py
ADDED
|
@@ -0,0 +1,580 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
import sys
|
| 6 |
+
if sys.version_info[1] > 5:
|
| 7 |
+
from typing import TextIO
|
| 8 |
+
else:
|
| 9 |
+
from typing.io import TextIO
|
| 10 |
+
from antlr4.BufferedTokenStream import TokenStream
|
| 11 |
+
from antlr4.CommonTokenFactory import TokenFactory
|
| 12 |
+
from antlr4.error.ErrorStrategy import DefaultErrorStrategy
|
| 13 |
+
from antlr4.InputStream import InputStream
|
| 14 |
+
from antlr4.Recognizer import Recognizer
|
| 15 |
+
from antlr4.RuleContext import RuleContext
|
| 16 |
+
from antlr4.ParserRuleContext import ParserRuleContext
|
| 17 |
+
from antlr4.Token import Token
|
| 18 |
+
from antlr4.Lexer import Lexer
|
| 19 |
+
from antlr4.atn.ATNDeserializer import ATNDeserializer
|
| 20 |
+
from antlr4.atn.ATNDeserializationOptions import ATNDeserializationOptions
|
| 21 |
+
from antlr4.error.Errors import UnsupportedOperationException, RecognitionException
|
| 22 |
+
from antlr4.tree.ParseTreePatternMatcher import ParseTreePatternMatcher
|
| 23 |
+
from antlr4.tree.Tree import ParseTreeListener, TerminalNode, ErrorNode
|
| 24 |
+
|
| 25 |
+
class TraceListener(ParseTreeListener):
|
| 26 |
+
__slots__ = '_parser'
|
| 27 |
+
|
| 28 |
+
def __init__(self, parser):
|
| 29 |
+
self._parser = parser
|
| 30 |
+
|
| 31 |
+
def enterEveryRule(self, ctx):
|
| 32 |
+
print("enter " + self._parser.ruleNames[ctx.getRuleIndex()] + ", LT(1)=" + self._parser._input.LT(1).text, file=self._parser._output)
|
| 33 |
+
|
| 34 |
+
def visitTerminal(self, node):
|
| 35 |
+
|
| 36 |
+
print("consume " + str(node.symbol) + " rule " + self._parser.ruleNames[self._parser._ctx.getRuleIndex()], file=self._parser._output)
|
| 37 |
+
|
| 38 |
+
def visitErrorNode(self, node):
|
| 39 |
+
pass
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def exitEveryRule(self, ctx):
|
| 43 |
+
print("exit " + self._parser.ruleNames[ctx.getRuleIndex()] + ", LT(1)=" + self._parser._input.LT(1).text, file=self._parser._output)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
# self is all the parsing support code essentially; most of it is error recovery stuff.#
|
| 47 |
+
class Parser (Recognizer):
|
| 48 |
+
__slots__ = (
|
| 49 |
+
'_input', '_output', '_errHandler', '_precedenceStack', '_ctx',
|
| 50 |
+
'buildParseTrees', '_tracer', '_parseListeners', '_syntaxErrors'
|
| 51 |
+
|
| 52 |
+
)
|
| 53 |
+
# self field maps from the serialized ATN string to the deserialized {@link ATN} with
|
| 54 |
+
# bypass alternatives.
|
| 55 |
+
#
|
| 56 |
+
# @see ATNDeserializationOptions#isGenerateRuleBypassTransitions()
|
| 57 |
+
#
|
| 58 |
+
bypassAltsAtnCache = dict()
|
| 59 |
+
|
| 60 |
+
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
| 61 |
+
super().__init__()
|
| 62 |
+
# The input stream.
|
| 63 |
+
self._input = None
|
| 64 |
+
self._output = output
|
| 65 |
+
# The error handling strategy for the parser. The default value is a new
|
| 66 |
+
# instance of {@link DefaultErrorStrategy}.
|
| 67 |
+
self._errHandler = DefaultErrorStrategy()
|
| 68 |
+
self._precedenceStack = list()
|
| 69 |
+
self._precedenceStack.append(0)
|
| 70 |
+
# The {@link ParserRuleContext} object for the currently executing rule.
|
| 71 |
+
# self is always non-null during the parsing process.
|
| 72 |
+
self._ctx = None
|
| 73 |
+
# Specifies whether or not the parser should construct a parse tree during
|
| 74 |
+
# the parsing process. The default value is {@code true}.
|
| 75 |
+
self.buildParseTrees = True
|
| 76 |
+
# When {@link #setTrace}{@code (true)} is called, a reference to the
|
| 77 |
+
# {@link TraceListener} is stored here so it can be easily removed in a
|
| 78 |
+
# later call to {@link #setTrace}{@code (false)}. The listener itself is
|
| 79 |
+
# implemented as a parser listener so self field is not directly used by
|
| 80 |
+
# other parser methods.
|
| 81 |
+
self._tracer = None
|
| 82 |
+
# The list of {@link ParseTreeListener} listeners registered to receive
|
| 83 |
+
# events during the parse.
|
| 84 |
+
self._parseListeners = None
|
| 85 |
+
# The number of syntax errors reported during parsing. self value is
|
| 86 |
+
# incremented each time {@link #notifyErrorListeners} is called.
|
| 87 |
+
self._syntaxErrors = 0
|
| 88 |
+
self.setInputStream(input)
|
| 89 |
+
|
| 90 |
+
# reset the parser's state#
|
| 91 |
+
def reset(self):
|
| 92 |
+
if self._input is not None:
|
| 93 |
+
self._input.seek(0)
|
| 94 |
+
self._errHandler.reset(self)
|
| 95 |
+
self._ctx = None
|
| 96 |
+
self._syntaxErrors = 0
|
| 97 |
+
self.setTrace(False)
|
| 98 |
+
self._precedenceStack = list()
|
| 99 |
+
self._precedenceStack.append(0)
|
| 100 |
+
if self._interp is not None:
|
| 101 |
+
self._interp.reset()
|
| 102 |
+
|
| 103 |
+
# Match current input symbol against {@code ttype}. If the symbol type
|
| 104 |
+
# matches, {@link ANTLRErrorStrategy#reportMatch} and {@link #consume} are
|
| 105 |
+
# called to complete the match process.
|
| 106 |
+
#
|
| 107 |
+
# <p>If the symbol type does not match,
|
| 108 |
+
# {@link ANTLRErrorStrategy#recoverInline} is called on the current error
|
| 109 |
+
# strategy to attempt recovery. If {@link #getBuildParseTree} is
|
| 110 |
+
# {@code true} and the token index of the symbol returned by
|
| 111 |
+
# {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
|
| 112 |
+
# the parse tree by calling {@link ParserRuleContext#addErrorNode}.</p>
|
| 113 |
+
#
|
| 114 |
+
# @param ttype the token type to match
|
| 115 |
+
# @return the matched symbol
|
| 116 |
+
# @throws RecognitionException if the current input symbol did not match
|
| 117 |
+
# {@code ttype} and the error strategy could not recover from the
|
| 118 |
+
# mismatched symbol
|
| 119 |
+
|
| 120 |
+
def match(self, ttype:int):
|
| 121 |
+
t = self.getCurrentToken()
|
| 122 |
+
if t.type==ttype:
|
| 123 |
+
self._errHandler.reportMatch(self)
|
| 124 |
+
self.consume()
|
| 125 |
+
else:
|
| 126 |
+
t = self._errHandler.recoverInline(self)
|
| 127 |
+
if self.buildParseTrees and t.tokenIndex==-1:
|
| 128 |
+
# we must have conjured up a new token during single token insertion
|
| 129 |
+
# if it's not the current symbol
|
| 130 |
+
self._ctx.addErrorNode(t)
|
| 131 |
+
return t
|
| 132 |
+
|
| 133 |
+
# Match current input symbol as a wildcard. If the symbol type matches
|
| 134 |
+
# (i.e. has a value greater than 0), {@link ANTLRErrorStrategy#reportMatch}
|
| 135 |
+
# and {@link #consume} are called to complete the match process.
|
| 136 |
+
#
|
| 137 |
+
# <p>If the symbol type does not match,
|
| 138 |
+
# {@link ANTLRErrorStrategy#recoverInline} is called on the current error
|
| 139 |
+
# strategy to attempt recovery. If {@link #getBuildParseTree} is
|
| 140 |
+
# {@code true} and the token index of the symbol returned by
|
| 141 |
+
# {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
|
| 142 |
+
# the parse tree by calling {@link ParserRuleContext#addErrorNode}.</p>
|
| 143 |
+
#
|
| 144 |
+
# @return the matched symbol
|
| 145 |
+
# @throws RecognitionException if the current input symbol did not match
|
| 146 |
+
# a wildcard and the error strategy could not recover from the mismatched
|
| 147 |
+
# symbol
|
| 148 |
+
|
| 149 |
+
def matchWildcard(self):
|
| 150 |
+
t = self.getCurrentToken()
|
| 151 |
+
if t.type > 0:
|
| 152 |
+
self._errHandler.reportMatch(self)
|
| 153 |
+
self.consume()
|
| 154 |
+
else:
|
| 155 |
+
t = self._errHandler.recoverInline(self)
|
| 156 |
+
if self.buildParseTrees and t.tokenIndex == -1:
|
| 157 |
+
# we must have conjured up a new token during single token insertion
|
| 158 |
+
# if it's not the current symbol
|
| 159 |
+
self._ctx.addErrorNode(t)
|
| 160 |
+
|
| 161 |
+
return t
|
| 162 |
+
|
| 163 |
+
def getParseListeners(self):
|
| 164 |
+
return list() if self._parseListeners is None else self._parseListeners
|
| 165 |
+
|
| 166 |
+
# Registers {@code listener} to receive events during the parsing process.
|
| 167 |
+
#
|
| 168 |
+
# <p>To support output-preserving grammar transformations (including but not
|
| 169 |
+
# limited to left-recursion removal, automated left-factoring, and
|
| 170 |
+
# optimized code generation), calls to listener methods during the parse
|
| 171 |
+
# may differ substantially from calls made by
|
| 172 |
+
# {@link ParseTreeWalker#DEFAULT} used after the parse is complete. In
|
| 173 |
+
# particular, rule entry and exit events may occur in a different order
|
| 174 |
+
# during the parse than after the parser. In addition, calls to certain
|
| 175 |
+
# rule entry methods may be omitted.</p>
|
| 176 |
+
#
|
| 177 |
+
# <p>With the following specific exceptions, calls to listener events are
|
| 178 |
+
# <em>deterministic</em>, i.e. for identical input the calls to listener
|
| 179 |
+
# methods will be the same.</p>
|
| 180 |
+
#
|
| 181 |
+
# <ul>
|
| 182 |
+
# <li>Alterations to the grammar used to generate code may change the
|
| 183 |
+
# behavior of the listener calls.</li>
|
| 184 |
+
# <li>Alterations to the command line options passed to ANTLR 4 when
|
| 185 |
+
# generating the parser may change the behavior of the listener calls.</li>
|
| 186 |
+
# <li>Changing the version of the ANTLR Tool used to generate the parser
|
| 187 |
+
# may change the behavior of the listener calls.</li>
|
| 188 |
+
# </ul>
|
| 189 |
+
#
|
| 190 |
+
# @param listener the listener to add
|
| 191 |
+
#
|
| 192 |
+
# @throws NullPointerException if {@code} listener is {@code null}
|
| 193 |
+
#
|
| 194 |
+
def addParseListener(self, listener:ParseTreeListener):
|
| 195 |
+
if listener is None:
|
| 196 |
+
raise ReferenceError("listener")
|
| 197 |
+
if self._parseListeners is None:
|
| 198 |
+
self._parseListeners = []
|
| 199 |
+
self._parseListeners.append(listener)
|
| 200 |
+
|
| 201 |
+
#
|
| 202 |
+
# Remove {@code listener} from the list of parse listeners.
|
| 203 |
+
#
|
| 204 |
+
# <p>If {@code listener} is {@code null} or has not been added as a parse
|
| 205 |
+
# listener, self method does nothing.</p>
|
| 206 |
+
# @param listener the listener to remove
|
| 207 |
+
#
|
| 208 |
+
def removeParseListener(self, listener:ParseTreeListener):
|
| 209 |
+
if self._parseListeners is not None:
|
| 210 |
+
self._parseListeners.remove(listener)
|
| 211 |
+
if len(self._parseListeners)==0:
|
| 212 |
+
self._parseListeners = None
|
| 213 |
+
|
| 214 |
+
# Remove all parse listeners.
|
| 215 |
+
def removeParseListeners(self):
|
| 216 |
+
self._parseListeners = None
|
| 217 |
+
|
| 218 |
+
# Notify any parse listeners of an enter rule event.
|
| 219 |
+
def triggerEnterRuleEvent(self):
|
| 220 |
+
if self._parseListeners is not None:
|
| 221 |
+
for listener in self._parseListeners:
|
| 222 |
+
listener.enterEveryRule(self._ctx)
|
| 223 |
+
self._ctx.enterRule(listener)
|
| 224 |
+
|
| 225 |
+
#
|
| 226 |
+
# Notify any parse listeners of an exit rule event.
|
| 227 |
+
#
|
| 228 |
+
# @see #addParseListener
|
| 229 |
+
#
|
| 230 |
+
def triggerExitRuleEvent(self):
|
| 231 |
+
if self._parseListeners is not None:
|
| 232 |
+
# reverse order walk of listeners
|
| 233 |
+
for listener in reversed(self._parseListeners):
|
| 234 |
+
self._ctx.exitRule(listener)
|
| 235 |
+
listener.exitEveryRule(self._ctx)
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
# Gets the number of syntax errors reported during parsing. This value is
|
| 239 |
+
# incremented each time {@link #notifyErrorListeners} is called.
|
| 240 |
+
#
|
| 241 |
+
# @see #notifyErrorListeners
|
| 242 |
+
#
|
| 243 |
+
def getNumberOfSyntaxErrors(self):
|
| 244 |
+
return self._syntaxErrors
|
| 245 |
+
|
| 246 |
+
def getTokenFactory(self):
|
| 247 |
+
return self._input.tokenSource._factory
|
| 248 |
+
|
| 249 |
+
# Tell our token source and error strategy about a new way to create tokens.#
|
| 250 |
+
def setTokenFactory(self, factory:TokenFactory):
|
| 251 |
+
self._input.tokenSource._factory = factory
|
| 252 |
+
|
| 253 |
+
# The ATN with bypass alternatives is expensive to create so we create it
|
| 254 |
+
# lazily.
|
| 255 |
+
#
|
| 256 |
+
# @throws UnsupportedOperationException if the current parser does not
|
| 257 |
+
# implement the {@link #getSerializedATN()} method.
|
| 258 |
+
#
|
| 259 |
+
def getATNWithBypassAlts(self):
|
| 260 |
+
serializedAtn = self.getSerializedATN()
|
| 261 |
+
if serializedAtn is None:
|
| 262 |
+
raise UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.")
|
| 263 |
+
result = self.bypassAltsAtnCache.get(serializedAtn, None)
|
| 264 |
+
if result is None:
|
| 265 |
+
deserializationOptions = ATNDeserializationOptions()
|
| 266 |
+
deserializationOptions.generateRuleBypassTransitions = True
|
| 267 |
+
result = ATNDeserializer(deserializationOptions).deserialize(serializedAtn)
|
| 268 |
+
self.bypassAltsAtnCache[serializedAtn] = result
|
| 269 |
+
return result
|
| 270 |
+
|
| 271 |
+
# The preferred method of getting a tree pattern. For example, here's a
|
| 272 |
+
# sample use:
|
| 273 |
+
#
|
| 274 |
+
# <pre>
|
| 275 |
+
# ParseTree t = parser.expr();
|
| 276 |
+
# ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
|
| 277 |
+
# ParseTreeMatch m = p.match(t);
|
| 278 |
+
# String id = m.get("ID");
|
| 279 |
+
# </pre>
|
| 280 |
+
#
|
| 281 |
+
def compileParseTreePattern(self, pattern:str, patternRuleIndex:int, lexer:Lexer = None):
|
| 282 |
+
if lexer is None:
|
| 283 |
+
if self.getTokenStream() is not None:
|
| 284 |
+
tokenSource = self.getTokenStream().tokenSource
|
| 285 |
+
if isinstance( tokenSource, Lexer ):
|
| 286 |
+
lexer = tokenSource
|
| 287 |
+
if lexer is None:
|
| 288 |
+
raise UnsupportedOperationException("Parser can't discover a lexer to use")
|
| 289 |
+
|
| 290 |
+
m = ParseTreePatternMatcher(lexer, self)
|
| 291 |
+
return m.compile(pattern, patternRuleIndex)
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
def getInputStream(self):
|
| 295 |
+
return self.getTokenStream()
|
| 296 |
+
|
| 297 |
+
def setInputStream(self, input:InputStream):
|
| 298 |
+
self.setTokenStream(input)
|
| 299 |
+
|
| 300 |
+
def getTokenStream(self):
|
| 301 |
+
return self._input
|
| 302 |
+
|
| 303 |
+
# Set the token stream and reset the parser.#
|
| 304 |
+
def setTokenStream(self, input:TokenStream):
|
| 305 |
+
self._input = None
|
| 306 |
+
self.reset()
|
| 307 |
+
self._input = input
|
| 308 |
+
|
| 309 |
+
# Match needs to return the current input symbol, which gets put
|
| 310 |
+
# into the label for the associated token ref; e.g., x=ID.
|
| 311 |
+
#
|
| 312 |
+
def getCurrentToken(self):
|
| 313 |
+
return self._input.LT(1)
|
| 314 |
+
|
| 315 |
+
def notifyErrorListeners(self, msg:str, offendingToken:Token = None, e:RecognitionException = None):
|
| 316 |
+
if offendingToken is None:
|
| 317 |
+
offendingToken = self.getCurrentToken()
|
| 318 |
+
self._syntaxErrors += 1
|
| 319 |
+
line = offendingToken.line
|
| 320 |
+
column = offendingToken.column
|
| 321 |
+
listener = self.getErrorListenerDispatch()
|
| 322 |
+
listener.syntaxError(self, offendingToken, line, column, msg, e)
|
| 323 |
+
|
| 324 |
+
#
|
| 325 |
+
# Consume and return the {@linkplain #getCurrentToken current symbol}.
|
| 326 |
+
#
|
| 327 |
+
# <p>E.g., given the following input with {@code A} being the current
|
| 328 |
+
# lookahead symbol, self function moves the cursor to {@code B} and returns
|
| 329 |
+
# {@code A}.</p>
|
| 330 |
+
#
|
| 331 |
+
# <pre>
|
| 332 |
+
# A B
|
| 333 |
+
# ^
|
| 334 |
+
# </pre>
|
| 335 |
+
#
|
| 336 |
+
# If the parser is not in error recovery mode, the consumed symbol is added
|
| 337 |
+
# to the parse tree using {@link ParserRuleContext#addChild(Token)}, and
|
| 338 |
+
# {@link ParseTreeListener#visitTerminal} is called on any parse listeners.
|
| 339 |
+
# If the parser <em>is</em> in error recovery mode, the consumed symbol is
|
| 340 |
+
# added to the parse tree using
|
| 341 |
+
# {@link ParserRuleContext#addErrorNode(Token)}, and
|
| 342 |
+
# {@link ParseTreeListener#visitErrorNode} is called on any parse
|
| 343 |
+
# listeners.
|
| 344 |
+
#
|
| 345 |
+
def consume(self):
|
| 346 |
+
o = self.getCurrentToken()
|
| 347 |
+
if o.type != Token.EOF:
|
| 348 |
+
self.getInputStream().consume()
|
| 349 |
+
hasListener = self._parseListeners is not None and len(self._parseListeners)>0
|
| 350 |
+
if self.buildParseTrees or hasListener:
|
| 351 |
+
if self._errHandler.inErrorRecoveryMode(self):
|
| 352 |
+
node = self._ctx.addErrorNode(o)
|
| 353 |
+
else:
|
| 354 |
+
node = self._ctx.addTokenNode(o)
|
| 355 |
+
if hasListener:
|
| 356 |
+
for listener in self._parseListeners:
|
| 357 |
+
if isinstance(node, ErrorNode):
|
| 358 |
+
listener.visitErrorNode(node)
|
| 359 |
+
elif isinstance(node, TerminalNode):
|
| 360 |
+
listener.visitTerminal(node)
|
| 361 |
+
return o
|
| 362 |
+
|
| 363 |
+
def addContextToParseTree(self):
|
| 364 |
+
# add current context to parent if we have a parent
|
| 365 |
+
if self._ctx.parentCtx is not None:
|
| 366 |
+
self._ctx.parentCtx.addChild(self._ctx)
|
| 367 |
+
|
| 368 |
+
# Always called by generated parsers upon entry to a rule. Access field
|
| 369 |
+
# {@link #_ctx} get the current context.
|
| 370 |
+
#
|
| 371 |
+
def enterRule(self, localctx:ParserRuleContext , state:int , ruleIndex:int):
|
| 372 |
+
self.state = state
|
| 373 |
+
self._ctx = localctx
|
| 374 |
+
self._ctx.start = self._input.LT(1)
|
| 375 |
+
if self.buildParseTrees:
|
| 376 |
+
self.addContextToParseTree()
|
| 377 |
+
if self._parseListeners is not None:
|
| 378 |
+
self.triggerEnterRuleEvent()
|
| 379 |
+
|
| 380 |
+
def exitRule(self):
|
| 381 |
+
self._ctx.stop = self._input.LT(-1)
|
| 382 |
+
# trigger event on _ctx, before it reverts to parent
|
| 383 |
+
if self._parseListeners is not None:
|
| 384 |
+
self.triggerExitRuleEvent()
|
| 385 |
+
self.state = self._ctx.invokingState
|
| 386 |
+
self._ctx = self._ctx.parentCtx
|
| 387 |
+
|
| 388 |
+
def enterOuterAlt(self, localctx:ParserRuleContext, altNum:int):
|
| 389 |
+
localctx.setAltNumber(altNum)
|
| 390 |
+
# if we have new localctx, make sure we replace existing ctx
|
| 391 |
+
# that is previous child of parse tree
|
| 392 |
+
if self.buildParseTrees and self._ctx != localctx:
|
| 393 |
+
if self._ctx.parentCtx is not None:
|
| 394 |
+
self._ctx.parentCtx.removeLastChild()
|
| 395 |
+
self._ctx.parentCtx.addChild(localctx)
|
| 396 |
+
self._ctx = localctx
|
| 397 |
+
|
| 398 |
+
# Get the precedence level for the top-most precedence rule.
|
| 399 |
+
#
|
| 400 |
+
# @return The precedence level for the top-most precedence rule, or -1 if
|
| 401 |
+
# the parser context is not nested within a precedence rule.
|
| 402 |
+
#
|
| 403 |
+
def getPrecedence(self):
|
| 404 |
+
if len(self._precedenceStack)==0:
|
| 405 |
+
return -1
|
| 406 |
+
else:
|
| 407 |
+
return self._precedenceStack[-1]
|
| 408 |
+
|
| 409 |
+
def enterRecursionRule(self, localctx:ParserRuleContext, state:int, ruleIndex:int, precedence:int):
|
| 410 |
+
self.state = state
|
| 411 |
+
self._precedenceStack.append(precedence)
|
| 412 |
+
self._ctx = localctx
|
| 413 |
+
self._ctx.start = self._input.LT(1)
|
| 414 |
+
if self._parseListeners is not None:
|
| 415 |
+
self.triggerEnterRuleEvent() # simulates rule entry for left-recursive rules
|
| 416 |
+
|
| 417 |
+
#
|
| 418 |
+
# Like {@link #enterRule} but for recursive rules.
|
| 419 |
+
#
|
| 420 |
+
def pushNewRecursionContext(self, localctx:ParserRuleContext, state:int, ruleIndex:int):
|
| 421 |
+
previous = self._ctx
|
| 422 |
+
previous.parentCtx = localctx
|
| 423 |
+
previous.invokingState = state
|
| 424 |
+
previous.stop = self._input.LT(-1)
|
| 425 |
+
|
| 426 |
+
self._ctx = localctx
|
| 427 |
+
self._ctx.start = previous.start
|
| 428 |
+
if self.buildParseTrees:
|
| 429 |
+
self._ctx.addChild(previous)
|
| 430 |
+
|
| 431 |
+
if self._parseListeners is not None:
|
| 432 |
+
self.triggerEnterRuleEvent() # simulates rule entry for left-recursive rules
|
| 433 |
+
|
| 434 |
+
def unrollRecursionContexts(self, parentCtx:ParserRuleContext):
|
| 435 |
+
self._precedenceStack.pop()
|
| 436 |
+
self._ctx.stop = self._input.LT(-1)
|
| 437 |
+
retCtx = self._ctx # save current ctx (return value)
|
| 438 |
+
# unroll so _ctx is as it was before call to recursive method
|
| 439 |
+
if self._parseListeners is not None:
|
| 440 |
+
while self._ctx is not parentCtx:
|
| 441 |
+
self.triggerExitRuleEvent()
|
| 442 |
+
self._ctx = self._ctx.parentCtx
|
| 443 |
+
else:
|
| 444 |
+
self._ctx = parentCtx
|
| 445 |
+
|
| 446 |
+
# hook into tree
|
| 447 |
+
retCtx.parentCtx = parentCtx
|
| 448 |
+
|
| 449 |
+
if self.buildParseTrees and parentCtx is not None:
|
| 450 |
+
# add return ctx into invoking rule's tree
|
| 451 |
+
parentCtx.addChild(retCtx)
|
| 452 |
+
|
| 453 |
+
def getInvokingContext(self, ruleIndex:int):
|
| 454 |
+
ctx = self._ctx
|
| 455 |
+
while ctx is not None:
|
| 456 |
+
if ctx.getRuleIndex() == ruleIndex:
|
| 457 |
+
return ctx
|
| 458 |
+
ctx = ctx.parentCtx
|
| 459 |
+
return None
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
def precpred(self, localctx:RuleContext , precedence:int):
|
| 463 |
+
return precedence >= self._precedenceStack[-1]
|
| 464 |
+
|
| 465 |
+
def inContext(self, context:str):
|
| 466 |
+
# TODO: useful in parser?
|
| 467 |
+
return False
|
| 468 |
+
|
| 469 |
+
#
|
| 470 |
+
# Checks whether or not {@code symbol} can follow the current state in the
|
| 471 |
+
# ATN. The behavior of self method is equivalent to the following, but is
|
| 472 |
+
# implemented such that the complete context-sensitive follow set does not
|
| 473 |
+
# need to be explicitly constructed.
|
| 474 |
+
#
|
| 475 |
+
# <pre>
|
| 476 |
+
# return getExpectedTokens().contains(symbol);
|
| 477 |
+
# </pre>
|
| 478 |
+
#
|
| 479 |
+
# @param symbol the symbol type to check
|
| 480 |
+
# @return {@code true} if {@code symbol} can follow the current state in
|
| 481 |
+
# the ATN, otherwise {@code false}.
|
| 482 |
+
#
|
| 483 |
+
def isExpectedToken(self, symbol:int):
|
| 484 |
+
atn = self._interp.atn
|
| 485 |
+
ctx = self._ctx
|
| 486 |
+
s = atn.states[self.state]
|
| 487 |
+
following = atn.nextTokens(s)
|
| 488 |
+
if symbol in following:
|
| 489 |
+
return True
|
| 490 |
+
if not Token.EPSILON in following:
|
| 491 |
+
return False
|
| 492 |
+
|
| 493 |
+
while ctx is not None and ctx.invokingState>=0 and Token.EPSILON in following:
|
| 494 |
+
invokingState = atn.states[ctx.invokingState]
|
| 495 |
+
rt = invokingState.transitions[0]
|
| 496 |
+
following = atn.nextTokens(rt.followState)
|
| 497 |
+
if symbol in following:
|
| 498 |
+
return True
|
| 499 |
+
ctx = ctx.parentCtx
|
| 500 |
+
|
| 501 |
+
if Token.EPSILON in following and symbol == Token.EOF:
|
| 502 |
+
return True
|
| 503 |
+
else:
|
| 504 |
+
return False
|
| 505 |
+
|
| 506 |
+
# Computes the set of input symbols which could follow the current parser
|
| 507 |
+
# state and context, as given by {@link #getState} and {@link #getContext},
|
| 508 |
+
# respectively.
|
| 509 |
+
#
|
| 510 |
+
# @see ATN#getExpectedTokens(int, RuleContext)
|
| 511 |
+
#
|
| 512 |
+
def getExpectedTokens(self):
|
| 513 |
+
return self._interp.atn.getExpectedTokens(self.state, self._ctx)
|
| 514 |
+
|
| 515 |
+
def getExpectedTokensWithinCurrentRule(self):
|
| 516 |
+
atn = self._interp.atn
|
| 517 |
+
s = atn.states[self.state]
|
| 518 |
+
return atn.nextTokens(s)
|
| 519 |
+
|
| 520 |
+
# Get a rule's index (i.e., {@code RULE_ruleName} field) or -1 if not found.#
|
| 521 |
+
def getRuleIndex(self, ruleName:str):
|
| 522 |
+
ruleIndex = self.getRuleIndexMap().get(ruleName, None)
|
| 523 |
+
if ruleIndex is not None:
|
| 524 |
+
return ruleIndex
|
| 525 |
+
else:
|
| 526 |
+
return -1
|
| 527 |
+
|
| 528 |
+
# Return List<String> of the rule names in your parser instance
|
| 529 |
+
# leading up to a call to the current rule. You could override if
|
| 530 |
+
# you want more details such as the file/line info of where
|
| 531 |
+
# in the ATN a rule is invoked.
|
| 532 |
+
#
|
| 533 |
+
# this is very useful for error messages.
|
| 534 |
+
#
|
| 535 |
+
def getRuleInvocationStack(self, p:RuleContext=None):
|
| 536 |
+
if p is None:
|
| 537 |
+
p = self._ctx
|
| 538 |
+
stack = list()
|
| 539 |
+
while p is not None:
|
| 540 |
+
# compute what follows who invoked us
|
| 541 |
+
ruleIndex = p.getRuleIndex()
|
| 542 |
+
if ruleIndex<0:
|
| 543 |
+
stack.append("n/a")
|
| 544 |
+
else:
|
| 545 |
+
stack.append(self.ruleNames[ruleIndex])
|
| 546 |
+
p = p.parentCtx
|
| 547 |
+
return stack
|
| 548 |
+
|
| 549 |
+
# For debugging and other purposes.#
|
| 550 |
+
def getDFAStrings(self):
|
| 551 |
+
return [ str(dfa) for dfa in self._interp.decisionToDFA]
|
| 552 |
+
|
| 553 |
+
# For debugging and other purposes.#
|
| 554 |
+
def dumpDFA(self):
|
| 555 |
+
seenOne = False
|
| 556 |
+
for i in range(0, len(self._interp.decisionToDFA)):
|
| 557 |
+
dfa = self._interp.decisionToDFA[i]
|
| 558 |
+
if len(dfa.states)>0:
|
| 559 |
+
if seenOne:
|
| 560 |
+
print(file=self._output)
|
| 561 |
+
print("Decision " + str(dfa.decision) + ":", file=self._output)
|
| 562 |
+
print(dfa.toString(self.literalNames, self.symbolicNames), end='', file=self._output)
|
| 563 |
+
seenOne = True
|
| 564 |
+
|
| 565 |
+
|
| 566 |
+
def getSourceName(self):
|
| 567 |
+
return self._input.sourceName
|
| 568 |
+
|
| 569 |
+
# During a parse is sometimes useful to listen in on the rule entry and exit
|
| 570 |
+
# events as well as token matches. self is for quick and dirty debugging.
|
| 571 |
+
#
|
| 572 |
+
def setTrace(self, trace:bool):
|
| 573 |
+
if not trace:
|
| 574 |
+
self.removeParseListener(self._tracer)
|
| 575 |
+
self._tracer = None
|
| 576 |
+
else:
|
| 577 |
+
if self._tracer is not None:
|
| 578 |
+
self.removeParseListener(self._tracer)
|
| 579 |
+
self._tracer = TraceListener(self)
|
| 580 |
+
self.addParseListener(self._tracer)
|
cameras/deps/antlr4/ParserInterpreter.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
# A parser simulator that mimics what ANTLR's generated
|
| 8 |
+
# parser code does. A ParserATNSimulator is used to make
|
| 9 |
+
# predictions via adaptivePredict but this class moves a pointer through the
|
| 10 |
+
# ATN to simulate parsing. ParserATNSimulator just
|
| 11 |
+
# makes us efficient rather than having to backtrack, for example.
|
| 12 |
+
#
|
| 13 |
+
# This properly creates parse trees even for left recursive rules.
|
| 14 |
+
#
|
| 15 |
+
# We rely on the left recursive rule invocation and special predicate
|
| 16 |
+
# transitions to make left recursive rules work.
|
| 17 |
+
#
|
| 18 |
+
# See TestParserInterpreter for examples.
|
| 19 |
+
#
|
| 20 |
+
from antlr4.dfa.DFA import DFA
|
| 21 |
+
from antlr4.BufferedTokenStream import TokenStream
|
| 22 |
+
from antlr4.Lexer import Lexer
|
| 23 |
+
from antlr4.Parser import Parser
|
| 24 |
+
from antlr4.ParserRuleContext import InterpreterRuleContext, ParserRuleContext
|
| 25 |
+
from antlr4.Token import Token
|
| 26 |
+
from antlr4.atn.ATN import ATN
|
| 27 |
+
from antlr4.atn.ATNState import StarLoopEntryState, ATNState, LoopEndState
|
| 28 |
+
from antlr4.atn.ParserATNSimulator import ParserATNSimulator
|
| 29 |
+
from antlr4.PredictionContext import PredictionContextCache
|
| 30 |
+
from antlr4.atn.Transition import Transition
|
| 31 |
+
from antlr4.error.Errors import RecognitionException, UnsupportedOperationException, FailedPredicateException
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class ParserInterpreter(Parser):
|
| 35 |
+
__slots__ = (
|
| 36 |
+
'grammarFileName', 'atn', 'tokenNames', 'ruleNames', 'decisionToDFA',
|
| 37 |
+
'sharedContextCache', '_parentContextStack',
|
| 38 |
+
'pushRecursionContextStates'
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
def __init__(self, grammarFileName:str, tokenNames:list, ruleNames:list, atn:ATN, input:TokenStream):
|
| 42 |
+
super().__init__(input)
|
| 43 |
+
self.grammarFileName = grammarFileName
|
| 44 |
+
self.atn = atn
|
| 45 |
+
self.tokenNames = tokenNames
|
| 46 |
+
self.ruleNames = ruleNames
|
| 47 |
+
self.decisionToDFA = [ DFA(state) for state in atn.decisionToState ]
|
| 48 |
+
self.sharedContextCache = PredictionContextCache()
|
| 49 |
+
self._parentContextStack = list()
|
| 50 |
+
# identify the ATN states where pushNewRecursionContext must be called
|
| 51 |
+
self.pushRecursionContextStates = set()
|
| 52 |
+
for state in atn.states:
|
| 53 |
+
if not isinstance(state, StarLoopEntryState):
|
| 54 |
+
continue
|
| 55 |
+
if state.isPrecedenceDecision:
|
| 56 |
+
self.pushRecursionContextStates.add(state.stateNumber)
|
| 57 |
+
# get atn simulator that knows how to do predictions
|
| 58 |
+
self._interp = ParserATNSimulator(self, atn, self.decisionToDFA, self.sharedContextCache)
|
| 59 |
+
|
| 60 |
+
# Begin parsing at startRuleIndex#
|
| 61 |
+
def parse(self, startRuleIndex:int):
|
| 62 |
+
startRuleStartState = self.atn.ruleToStartState[startRuleIndex]
|
| 63 |
+
rootContext = InterpreterRuleContext(None, ATNState.INVALID_STATE_NUMBER, startRuleIndex)
|
| 64 |
+
if startRuleStartState.isPrecedenceRule:
|
| 65 |
+
self.enterRecursionRule(rootContext, startRuleStartState.stateNumber, startRuleIndex, 0)
|
| 66 |
+
else:
|
| 67 |
+
self.enterRule(rootContext, startRuleStartState.stateNumber, startRuleIndex)
|
| 68 |
+
while True:
|
| 69 |
+
p = self.getATNState()
|
| 70 |
+
if p.stateType==ATNState.RULE_STOP :
|
| 71 |
+
# pop; return from rule
|
| 72 |
+
if len(self._ctx)==0:
|
| 73 |
+
if startRuleStartState.isPrecedenceRule:
|
| 74 |
+
result = self._ctx
|
| 75 |
+
parentContext = self._parentContextStack.pop()
|
| 76 |
+
self.unrollRecursionContexts(parentContext.a)
|
| 77 |
+
return result
|
| 78 |
+
else:
|
| 79 |
+
self.exitRule()
|
| 80 |
+
return rootContext
|
| 81 |
+
self.visitRuleStopState(p)
|
| 82 |
+
|
| 83 |
+
else:
|
| 84 |
+
try:
|
| 85 |
+
self.visitState(p)
|
| 86 |
+
except RecognitionException as e:
|
| 87 |
+
self.state = self.atn.ruleToStopState[p.ruleIndex].stateNumber
|
| 88 |
+
self._ctx.exception = e
|
| 89 |
+
self._errHandler.reportError(self, e)
|
| 90 |
+
self._errHandler.recover(self, e)
|
| 91 |
+
|
| 92 |
+
def enterRecursionRule(self, localctx:ParserRuleContext, state:int, ruleIndex:int, precedence:int):
|
| 93 |
+
self._parentContextStack.append((self._ctx, localctx.invokingState))
|
| 94 |
+
super().enterRecursionRule(localctx, state, ruleIndex, precedence)
|
| 95 |
+
|
| 96 |
+
def getATNState(self):
|
| 97 |
+
return self.atn.states[self.state]
|
| 98 |
+
|
| 99 |
+
def visitState(self, p:ATNState):
|
| 100 |
+
edge = 0
|
| 101 |
+
if len(p.transitions) > 1:
|
| 102 |
+
self._errHandler.sync(self)
|
| 103 |
+
edge = self._interp.adaptivePredict(self._input, p.decision, self._ctx)
|
| 104 |
+
else:
|
| 105 |
+
edge = 1
|
| 106 |
+
|
| 107 |
+
transition = p.transitions[edge - 1]
|
| 108 |
+
tt = transition.serializationType
|
| 109 |
+
if tt==Transition.EPSILON:
|
| 110 |
+
|
| 111 |
+
if self.pushRecursionContextStates[p.stateNumber] and not isinstance(transition.target, LoopEndState):
|
| 112 |
+
t = self._parentContextStack[-1]
|
| 113 |
+
ctx = InterpreterRuleContext(t[0], t[1], self._ctx.ruleIndex)
|
| 114 |
+
self.pushNewRecursionContext(ctx, self.atn.ruleToStartState[p.ruleIndex].stateNumber, self._ctx.ruleIndex)
|
| 115 |
+
|
| 116 |
+
elif tt==Transition.ATOM:
|
| 117 |
+
|
| 118 |
+
self.match(transition.label)
|
| 119 |
+
|
| 120 |
+
elif tt in [ Transition.RANGE, Transition.SET, Transition.NOT_SET]:
|
| 121 |
+
|
| 122 |
+
if not transition.matches(self._input.LA(1), Token.MIN_USER_TOKEN_TYPE, Lexer.MAX_CHAR_VALUE):
|
| 123 |
+
self._errHandler.recoverInline(self)
|
| 124 |
+
self.matchWildcard()
|
| 125 |
+
|
| 126 |
+
elif tt==Transition.WILDCARD:
|
| 127 |
+
|
| 128 |
+
self.matchWildcard()
|
| 129 |
+
|
| 130 |
+
elif tt==Transition.RULE:
|
| 131 |
+
|
| 132 |
+
ruleStartState = transition.target
|
| 133 |
+
ruleIndex = ruleStartState.ruleIndex
|
| 134 |
+
ctx = InterpreterRuleContext(self._ctx, p.stateNumber, ruleIndex)
|
| 135 |
+
if ruleStartState.isPrecedenceRule:
|
| 136 |
+
self.enterRecursionRule(ctx, ruleStartState.stateNumber, ruleIndex, transition.precedence)
|
| 137 |
+
else:
|
| 138 |
+
self.enterRule(ctx, transition.target.stateNumber, ruleIndex)
|
| 139 |
+
|
| 140 |
+
elif tt==Transition.PREDICATE:
|
| 141 |
+
|
| 142 |
+
if not self.sempred(self._ctx, transition.ruleIndex, transition.predIndex):
|
| 143 |
+
raise FailedPredicateException(self)
|
| 144 |
+
|
| 145 |
+
elif tt==Transition.ACTION:
|
| 146 |
+
|
| 147 |
+
self.action(self._ctx, transition.ruleIndex, transition.actionIndex)
|
| 148 |
+
|
| 149 |
+
elif tt==Transition.PRECEDENCE:
|
| 150 |
+
|
| 151 |
+
if not self.precpred(self._ctx, transition.precedence):
|
| 152 |
+
msg = "precpred(_ctx, " + str(transition.precedence) + ")"
|
| 153 |
+
raise FailedPredicateException(self, msg)
|
| 154 |
+
|
| 155 |
+
else:
|
| 156 |
+
raise UnsupportedOperationException("Unrecognized ATN transition type.")
|
| 157 |
+
|
| 158 |
+
self.state = transition.target.stateNumber
|
| 159 |
+
|
| 160 |
+
def visitRuleStopState(self, p:ATNState):
|
| 161 |
+
ruleStartState = self.atn.ruleToStartState[p.ruleIndex]
|
| 162 |
+
if ruleStartState.isPrecedenceRule:
|
| 163 |
+
parentContext = self._parentContextStack.pop()
|
| 164 |
+
self.unrollRecursionContexts(parentContext.a)
|
| 165 |
+
self.state = parentContext[1]
|
| 166 |
+
else:
|
| 167 |
+
self.exitRule()
|
| 168 |
+
|
| 169 |
+
ruleTransition = self.atn.states[self.state].transitions[0]
|
| 170 |
+
self.state = ruleTransition.followState.stateNumber
|
cameras/deps/antlr4/ParserRuleContext.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
|
| 5 |
+
#* A rule invocation record for parsing.
|
| 6 |
+
#
|
| 7 |
+
# Contains all of the information about the current rule not stored in the
|
| 8 |
+
# RuleContext. It handles parse tree children list, Any ATN state
|
| 9 |
+
# tracing, and the default values available for rule indications:
|
| 10 |
+
# start, stop, rule index, current alt number, current
|
| 11 |
+
# ATN state.
|
| 12 |
+
#
|
| 13 |
+
# Subclasses made for each rule and grammar track the parameters,
|
| 14 |
+
# return values, locals, and labels specific to that rule. These
|
| 15 |
+
# are the objects that are returned from rules.
|
| 16 |
+
#
|
| 17 |
+
# Note text is not an actual field of a rule return value; it is computed
|
| 18 |
+
# from start and stop using the input stream's toString() method. I
|
| 19 |
+
# could add a ctor to this so that we can pass in and store the input
|
| 20 |
+
# stream, but I'm not sure we want to do that. It would seem to be undefined
|
| 21 |
+
# to get the .text property anyway if the rule matches tokens from multiple
|
| 22 |
+
# input streams.
|
| 23 |
+
#
|
| 24 |
+
# I do not use getters for fields of objects that are used simply to
|
| 25 |
+
# group values such as this aggregate. The getters/setters are there to
|
| 26 |
+
# satisfy the superclass interface.
|
| 27 |
+
|
| 28 |
+
from antlr4.RuleContext import RuleContext
|
| 29 |
+
from antlr4.Token import Token
|
| 30 |
+
from antlr4.tree.Tree import ParseTreeListener, ParseTree, TerminalNodeImpl, ErrorNodeImpl, TerminalNode, \
|
| 31 |
+
INVALID_INTERVAL
|
| 32 |
+
|
| 33 |
+
# need forward declaration
|
| 34 |
+
ParserRuleContext = None
|
| 35 |
+
|
| 36 |
+
class ParserRuleContext(RuleContext):
|
| 37 |
+
__slots__ = ('children', 'start', 'stop', 'exception')
|
| 38 |
+
def __init__(self, parent:ParserRuleContext = None, invokingStateNumber:int = None ):
|
| 39 |
+
super().__init__(parent, invokingStateNumber)
|
| 40 |
+
#* If we are debugging or building a parse tree for a visitor,
|
| 41 |
+
# we need to track all of the tokens and rule invocations associated
|
| 42 |
+
# with this rule's context. This is empty for parsing w/o tree constr.
|
| 43 |
+
# operation because we don't the need to track the details about
|
| 44 |
+
# how we parse this rule.
|
| 45 |
+
#/
|
| 46 |
+
self.children = None
|
| 47 |
+
self.start = None
|
| 48 |
+
self.stop = None
|
| 49 |
+
# The exception that forced this rule to return. If the rule successfully
|
| 50 |
+
# completed, this is {@code null}.
|
| 51 |
+
self.exception = None
|
| 52 |
+
|
| 53 |
+
#* COPY a ctx (I'm deliberately not using copy constructor)#/
|
| 54 |
+
#
|
| 55 |
+
# This is used in the generated parser code to flip a generic XContext
|
| 56 |
+
# node for rule X to a YContext for alt label Y. In that sense, it is
|
| 57 |
+
# not really a generic copy function.
|
| 58 |
+
#
|
| 59 |
+
# If we do an error sync() at start of a rule, we might add error nodes
|
| 60 |
+
# to the generic XContext so this function must copy those nodes to
|
| 61 |
+
# the YContext as well else they are lost!
|
| 62 |
+
#/
|
| 63 |
+
def copyFrom(self, ctx:ParserRuleContext):
|
| 64 |
+
# from RuleContext
|
| 65 |
+
self.parentCtx = ctx.parentCtx
|
| 66 |
+
self.invokingState = ctx.invokingState
|
| 67 |
+
self.children = None
|
| 68 |
+
self.start = ctx.start
|
| 69 |
+
self.stop = ctx.stop
|
| 70 |
+
|
| 71 |
+
# copy any error nodes to alt label node
|
| 72 |
+
if ctx.children is not None:
|
| 73 |
+
self.children = []
|
| 74 |
+
# reset parent pointer for any error nodes
|
| 75 |
+
for child in ctx.children:
|
| 76 |
+
if isinstance(child, ErrorNodeImpl):
|
| 77 |
+
self.children.append(child)
|
| 78 |
+
child.parentCtx = self
|
| 79 |
+
|
| 80 |
+
# Double dispatch methods for listeners
|
| 81 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 82 |
+
pass
|
| 83 |
+
|
| 84 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 85 |
+
pass
|
| 86 |
+
|
| 87 |
+
#* Does not set parent link; other add methods do that#/
|
| 88 |
+
def addChild(self, child:ParseTree):
|
| 89 |
+
if self.children is None:
|
| 90 |
+
self.children = []
|
| 91 |
+
self.children.append(child)
|
| 92 |
+
return child
|
| 93 |
+
|
| 94 |
+
#* Used by enterOuterAlt to toss out a RuleContext previously added as
|
| 95 |
+
# we entered a rule. If we have # label, we will need to remove
|
| 96 |
+
# generic ruleContext object.
|
| 97 |
+
#/
|
| 98 |
+
def removeLastChild(self):
|
| 99 |
+
if self.children is not None:
|
| 100 |
+
del self.children[len(self.children)-1]
|
| 101 |
+
|
| 102 |
+
def addTokenNode(self, token:Token):
|
| 103 |
+
node = TerminalNodeImpl(token)
|
| 104 |
+
self.addChild(node)
|
| 105 |
+
node.parentCtx = self
|
| 106 |
+
return node
|
| 107 |
+
|
| 108 |
+
def addErrorNode(self, badToken:Token):
|
| 109 |
+
node = ErrorNodeImpl(badToken)
|
| 110 |
+
self.addChild(node)
|
| 111 |
+
node.parentCtx = self
|
| 112 |
+
return node
|
| 113 |
+
|
| 114 |
+
def getChild(self, i:int, ttype:type = None):
|
| 115 |
+
if ttype is None:
|
| 116 |
+
return self.children[i] if len(self.children)>i else None
|
| 117 |
+
else:
|
| 118 |
+
for child in self.getChildren():
|
| 119 |
+
if not isinstance(child, ttype):
|
| 120 |
+
continue
|
| 121 |
+
if i==0:
|
| 122 |
+
return child
|
| 123 |
+
i -= 1
|
| 124 |
+
return None
|
| 125 |
+
|
| 126 |
+
def getChildren(self, predicate = None):
|
| 127 |
+
if self.children is not None:
|
| 128 |
+
for child in self.children:
|
| 129 |
+
if predicate is not None and not predicate(child):
|
| 130 |
+
continue
|
| 131 |
+
yield child
|
| 132 |
+
|
| 133 |
+
def getToken(self, ttype:int, i:int):
|
| 134 |
+
for child in self.getChildren():
|
| 135 |
+
if not isinstance(child, TerminalNode):
|
| 136 |
+
continue
|
| 137 |
+
if child.symbol.type != ttype:
|
| 138 |
+
continue
|
| 139 |
+
if i==0:
|
| 140 |
+
return child
|
| 141 |
+
i -= 1
|
| 142 |
+
return None
|
| 143 |
+
|
| 144 |
+
def getTokens(self, ttype:int ):
|
| 145 |
+
if self.getChildren() is None:
|
| 146 |
+
return []
|
| 147 |
+
tokens = []
|
| 148 |
+
for child in self.getChildren():
|
| 149 |
+
if not isinstance(child, TerminalNode):
|
| 150 |
+
continue
|
| 151 |
+
if child.symbol.type != ttype:
|
| 152 |
+
continue
|
| 153 |
+
tokens.append(child)
|
| 154 |
+
return tokens
|
| 155 |
+
|
| 156 |
+
def getTypedRuleContext(self, ctxType:type, i:int):
|
| 157 |
+
return self.getChild(i, ctxType)
|
| 158 |
+
|
| 159 |
+
def getTypedRuleContexts(self, ctxType:type):
|
| 160 |
+
children = self.getChildren()
|
| 161 |
+
if children is None:
|
| 162 |
+
return []
|
| 163 |
+
contexts = []
|
| 164 |
+
for child in children:
|
| 165 |
+
if not isinstance(child, ctxType):
|
| 166 |
+
continue
|
| 167 |
+
contexts.append(child)
|
| 168 |
+
return contexts
|
| 169 |
+
|
| 170 |
+
def getChildCount(self):
|
| 171 |
+
return len(self.children) if self.children else 0
|
| 172 |
+
|
| 173 |
+
def getSourceInterval(self):
|
| 174 |
+
if self.start is None or self.stop is None:
|
| 175 |
+
return INVALID_INTERVAL
|
| 176 |
+
else:
|
| 177 |
+
return (self.start.tokenIndex, self.stop.tokenIndex)
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
RuleContext.EMPTY = ParserRuleContext()
|
| 181 |
+
|
| 182 |
+
class InterpreterRuleContext(ParserRuleContext):
|
| 183 |
+
|
| 184 |
+
def __init__(self, parent:ParserRuleContext, invokingStateNumber:int, ruleIndex:int):
|
| 185 |
+
super().__init__(parent, invokingStateNumber)
|
| 186 |
+
self.ruleIndex = ruleIndex
|
cameras/deps/antlr4/PredictionContext.py
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
from io import StringIO
|
| 7 |
+
|
| 8 |
+
from antlr4.error.Errors import IllegalStateException
|
| 9 |
+
|
| 10 |
+
from antlr4.RuleContext import RuleContext
|
| 11 |
+
from antlr4.atn.ATN import ATN
|
| 12 |
+
from antlr4.atn.ATNState import ATNState
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class PredictionContext(object):
|
| 16 |
+
|
| 17 |
+
# Represents {@code $} in local context prediction, which means wildcard.
|
| 18 |
+
# {@code#+x =#}.
|
| 19 |
+
#/
|
| 20 |
+
EMPTY = None
|
| 21 |
+
|
| 22 |
+
# Represents {@code $} in an array in full context mode, when {@code $}
|
| 23 |
+
# doesn't mean wildcard: {@code $ + x = [$,x]}. Here,
|
| 24 |
+
# {@code $} = {@link #EMPTY_RETURN_STATE}.
|
| 25 |
+
#/
|
| 26 |
+
EMPTY_RETURN_STATE = 0x7FFFFFFF
|
| 27 |
+
|
| 28 |
+
globalNodeCount = 1
|
| 29 |
+
id = globalNodeCount
|
| 30 |
+
|
| 31 |
+
# Stores the computed hash code of this {@link PredictionContext}. The hash
|
| 32 |
+
# code is computed in parts to match the following reference algorithm.
|
| 33 |
+
#
|
| 34 |
+
# <pre>
|
| 35 |
+
# private int referenceHashCode() {
|
| 36 |
+
# int hash = {@link MurmurHash#initialize MurmurHash.initialize}({@link #INITIAL_HASH});
|
| 37 |
+
#
|
| 38 |
+
# for (int i = 0; i < {@link #size()}; i++) {
|
| 39 |
+
# hash = {@link MurmurHash#update MurmurHash.update}(hash, {@link #getParent getParent}(i));
|
| 40 |
+
# }
|
| 41 |
+
#
|
| 42 |
+
# for (int i = 0; i < {@link #size()}; i++) {
|
| 43 |
+
# hash = {@link MurmurHash#update MurmurHash.update}(hash, {@link #getReturnState getReturnState}(i));
|
| 44 |
+
# }
|
| 45 |
+
#
|
| 46 |
+
# hash = {@link MurmurHash#finish MurmurHash.finish}(hash, 2# {@link #size()});
|
| 47 |
+
# return hash;
|
| 48 |
+
# }
|
| 49 |
+
# </pre>
|
| 50 |
+
#/
|
| 51 |
+
|
| 52 |
+
def __init__(self, cachedHashCode:int):
|
| 53 |
+
self.cachedHashCode = cachedHashCode
|
| 54 |
+
|
| 55 |
+
def __len__(self):
|
| 56 |
+
return 0
|
| 57 |
+
|
| 58 |
+
# This means only the {@link #EMPTY} context is in set.
|
| 59 |
+
def isEmpty(self):
|
| 60 |
+
return self is self.EMPTY
|
| 61 |
+
|
| 62 |
+
def hasEmptyPath(self):
|
| 63 |
+
return self.getReturnState(len(self) - 1) == self.EMPTY_RETURN_STATE
|
| 64 |
+
|
| 65 |
+
def getReturnState(self, index:int):
|
| 66 |
+
raise IllegalStateException("illegal!")
|
| 67 |
+
|
| 68 |
+
def __hash__(self):
|
| 69 |
+
return self.cachedHashCode
|
| 70 |
+
|
| 71 |
+
def calculateHashCode(parent:PredictionContext, returnState:int):
|
| 72 |
+
return hash("") if parent is None else hash((hash(parent), returnState))
|
| 73 |
+
|
| 74 |
+
def calculateListsHashCode(parents:[], returnStates:[] ):
|
| 75 |
+
h = 0
|
| 76 |
+
for parent, returnState in zip(parents, returnStates):
|
| 77 |
+
h = hash((h, calculateHashCode(parent, returnState)))
|
| 78 |
+
return h
|
| 79 |
+
|
| 80 |
+
# Used to cache {@link PredictionContext} objects. Its used for the shared
|
| 81 |
+
# context cash associated with contexts in DFA states. This cache
|
| 82 |
+
# can be used for both lexers and parsers.
|
| 83 |
+
|
| 84 |
+
class PredictionContextCache(object):
|
| 85 |
+
|
| 86 |
+
def __init__(self):
|
| 87 |
+
self.cache = dict()
|
| 88 |
+
|
| 89 |
+
# Add a context to the cache and return it. If the context already exists,
|
| 90 |
+
# return that one instead and do not add a new context to the cache.
|
| 91 |
+
# Protect shared cache from unsafe thread access.
|
| 92 |
+
#
|
| 93 |
+
def add(self, ctx:PredictionContext):
|
| 94 |
+
if ctx==PredictionContext.EMPTY:
|
| 95 |
+
return PredictionContext.EMPTY
|
| 96 |
+
existing = self.cache.get(ctx, None)
|
| 97 |
+
if existing is not None:
|
| 98 |
+
return existing
|
| 99 |
+
self.cache[ctx] = ctx
|
| 100 |
+
return ctx
|
| 101 |
+
|
| 102 |
+
def get(self, ctx:PredictionContext):
|
| 103 |
+
return self.cache.get(ctx, None)
|
| 104 |
+
|
| 105 |
+
def __len__(self):
|
| 106 |
+
return len(self.cache)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
class SingletonPredictionContext(PredictionContext):
|
| 110 |
+
|
| 111 |
+
@staticmethod
|
| 112 |
+
def create(parent:PredictionContext , returnState:int ):
|
| 113 |
+
if returnState == PredictionContext.EMPTY_RETURN_STATE and parent is None:
|
| 114 |
+
# someone can pass in the bits of an array ctx that mean $
|
| 115 |
+
return SingletonPredictionContext.EMPTY
|
| 116 |
+
else:
|
| 117 |
+
return SingletonPredictionContext(parent, returnState)
|
| 118 |
+
|
| 119 |
+
def __init__(self, parent:PredictionContext, returnState:int):
|
| 120 |
+
hashCode = calculateHashCode(parent, returnState)
|
| 121 |
+
super().__init__(hashCode)
|
| 122 |
+
self.parentCtx = parent
|
| 123 |
+
self.returnState = returnState
|
| 124 |
+
|
| 125 |
+
def __len__(self):
|
| 126 |
+
return 1
|
| 127 |
+
|
| 128 |
+
def getParent(self, index:int):
|
| 129 |
+
return self.parentCtx
|
| 130 |
+
|
| 131 |
+
def getReturnState(self, index:int):
|
| 132 |
+
return self.returnState
|
| 133 |
+
|
| 134 |
+
def __eq__(self, other):
|
| 135 |
+
if self is other:
|
| 136 |
+
return True
|
| 137 |
+
elif other is None:
|
| 138 |
+
return False
|
| 139 |
+
elif not isinstance(other, SingletonPredictionContext):
|
| 140 |
+
return False
|
| 141 |
+
else:
|
| 142 |
+
return self.returnState == other.returnState and self.parentCtx == other.parentCtx
|
| 143 |
+
|
| 144 |
+
def __hash__(self):
|
| 145 |
+
return self.cachedHashCode
|
| 146 |
+
|
| 147 |
+
def __str__(self):
|
| 148 |
+
up = "" if self.parentCtx is None else str(self.parentCtx)
|
| 149 |
+
if len(up)==0:
|
| 150 |
+
if self.returnState == self.EMPTY_RETURN_STATE:
|
| 151 |
+
return "$"
|
| 152 |
+
else:
|
| 153 |
+
return str(self.returnState)
|
| 154 |
+
else:
|
| 155 |
+
return str(self.returnState) + " " + up
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
class EmptyPredictionContext(SingletonPredictionContext):
|
| 159 |
+
|
| 160 |
+
def __init__(self):
|
| 161 |
+
super().__init__(None, PredictionContext.EMPTY_RETURN_STATE)
|
| 162 |
+
|
| 163 |
+
def isEmpty(self):
|
| 164 |
+
return True
|
| 165 |
+
|
| 166 |
+
def __eq__(self, other):
|
| 167 |
+
return self is other
|
| 168 |
+
|
| 169 |
+
def __hash__(self):
|
| 170 |
+
return self.cachedHashCode
|
| 171 |
+
|
| 172 |
+
def __str__(self):
|
| 173 |
+
return "$"
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
PredictionContext.EMPTY = EmptyPredictionContext()
|
| 177 |
+
|
| 178 |
+
class ArrayPredictionContext(PredictionContext):
|
| 179 |
+
# Parent can be null only if full ctx mode and we make an array
|
| 180 |
+
# from {@link #EMPTY} and non-empty. We merge {@link #EMPTY} by using null parent and
|
| 181 |
+
# returnState == {@link #EMPTY_RETURN_STATE}.
|
| 182 |
+
|
| 183 |
+
def __init__(self, parents:list, returnStates:list):
|
| 184 |
+
super().__init__(calculateListsHashCode(parents, returnStates))
|
| 185 |
+
self.parents = parents
|
| 186 |
+
self.returnStates = returnStates
|
| 187 |
+
|
| 188 |
+
def isEmpty(self):
|
| 189 |
+
# since EMPTY_RETURN_STATE can only appear in the last position, we
|
| 190 |
+
# don't need to verify that size==1
|
| 191 |
+
return self.returnStates[0]==PredictionContext.EMPTY_RETURN_STATE
|
| 192 |
+
|
| 193 |
+
def __len__(self):
|
| 194 |
+
return len(self.returnStates)
|
| 195 |
+
|
| 196 |
+
def getParent(self, index:int):
|
| 197 |
+
return self.parents[index]
|
| 198 |
+
|
| 199 |
+
def getReturnState(self, index:int):
|
| 200 |
+
return self.returnStates[index]
|
| 201 |
+
|
| 202 |
+
def __eq__(self, other):
|
| 203 |
+
if self is other:
|
| 204 |
+
return True
|
| 205 |
+
elif not isinstance(other, ArrayPredictionContext):
|
| 206 |
+
return False
|
| 207 |
+
elif hash(self) != hash(other):
|
| 208 |
+
return False # can't be same if hash is different
|
| 209 |
+
else:
|
| 210 |
+
return self.returnStates==other.returnStates and self.parents==other.parents
|
| 211 |
+
|
| 212 |
+
def __str__(self):
|
| 213 |
+
if self.isEmpty():
|
| 214 |
+
return "[]"
|
| 215 |
+
with StringIO() as buf:
|
| 216 |
+
buf.write("[")
|
| 217 |
+
for i in range(0,len(self.returnStates)):
|
| 218 |
+
if i>0:
|
| 219 |
+
buf.write(", ")
|
| 220 |
+
if self.returnStates[i]==PredictionContext.EMPTY_RETURN_STATE:
|
| 221 |
+
buf.write("$")
|
| 222 |
+
continue
|
| 223 |
+
buf.write(str(self.returnStates[i]))
|
| 224 |
+
if self.parents[i] is not None:
|
| 225 |
+
buf.write(' ')
|
| 226 |
+
buf.write(str(self.parents[i]))
|
| 227 |
+
else:
|
| 228 |
+
buf.write("null")
|
| 229 |
+
buf.write("]")
|
| 230 |
+
return buf.getvalue()
|
| 231 |
+
|
| 232 |
+
def __hash__(self):
|
| 233 |
+
return self.cachedHashCode
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
# Convert a {@link RuleContext} tree to a {@link PredictionContext} graph.
|
| 238 |
+
# Return {@link #EMPTY} if {@code outerContext} is empty or null.
|
| 239 |
+
#/
|
| 240 |
+
def PredictionContextFromRuleContext(atn:ATN, outerContext:RuleContext=None):
|
| 241 |
+
if outerContext is None:
|
| 242 |
+
outerContext = RuleContext.EMPTY
|
| 243 |
+
|
| 244 |
+
# if we are in RuleContext of start rule, s, then PredictionContext
|
| 245 |
+
# is EMPTY. Nobody called us. (if we are empty, return empty)
|
| 246 |
+
if outerContext.parentCtx is None or outerContext is RuleContext.EMPTY:
|
| 247 |
+
return PredictionContext.EMPTY
|
| 248 |
+
|
| 249 |
+
# If we have a parent, convert it to a PredictionContext graph
|
| 250 |
+
parent = PredictionContextFromRuleContext(atn, outerContext.parentCtx)
|
| 251 |
+
state = atn.states[outerContext.invokingState]
|
| 252 |
+
transition = state.transitions[0]
|
| 253 |
+
return SingletonPredictionContext.create(parent, transition.followState.stateNumber)
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def merge(a:PredictionContext, b:PredictionContext, rootIsWildcard:bool, mergeCache:dict):
|
| 257 |
+
|
| 258 |
+
# share same graph if both same
|
| 259 |
+
if a==b:
|
| 260 |
+
return a
|
| 261 |
+
|
| 262 |
+
if isinstance(a, SingletonPredictionContext) and isinstance(b, SingletonPredictionContext):
|
| 263 |
+
return mergeSingletons(a, b, rootIsWildcard, mergeCache)
|
| 264 |
+
|
| 265 |
+
# At least one of a or b is array
|
| 266 |
+
# If one is $ and rootIsWildcard, return $ as# wildcard
|
| 267 |
+
if rootIsWildcard:
|
| 268 |
+
if isinstance( a, EmptyPredictionContext ):
|
| 269 |
+
return a
|
| 270 |
+
if isinstance( b, EmptyPredictionContext ):
|
| 271 |
+
return b
|
| 272 |
+
|
| 273 |
+
# convert singleton so both are arrays to normalize
|
| 274 |
+
if isinstance( a, SingletonPredictionContext ):
|
| 275 |
+
a = ArrayPredictionContext([a.parentCtx], [a.returnState])
|
| 276 |
+
if isinstance( b, SingletonPredictionContext):
|
| 277 |
+
b = ArrayPredictionContext([b.parentCtx], [b.returnState])
|
| 278 |
+
return mergeArrays(a, b, rootIsWildcard, mergeCache)
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
#
|
| 282 |
+
# Merge two {@link SingletonPredictionContext} instances.
|
| 283 |
+
#
|
| 284 |
+
# <p>Stack tops equal, parents merge is same; return left graph.<br>
|
| 285 |
+
# <embed src="images/SingletonMerge_SameRootSamePar.svg" type="image/svg+xml"/></p>
|
| 286 |
+
#
|
| 287 |
+
# <p>Same stack top, parents differ; merge parents giving array node, then
|
| 288 |
+
# remainders of those graphs. A new root node is created to point to the
|
| 289 |
+
# merged parents.<br>
|
| 290 |
+
# <embed src="images/SingletonMerge_SameRootDiffPar.svg" type="image/svg+xml"/></p>
|
| 291 |
+
#
|
| 292 |
+
# <p>Different stack tops pointing to same parent. Make array node for the
|
| 293 |
+
# root where both element in the root point to the same (original)
|
| 294 |
+
# parent.<br>
|
| 295 |
+
# <embed src="images/SingletonMerge_DiffRootSamePar.svg" type="image/svg+xml"/></p>
|
| 296 |
+
#
|
| 297 |
+
# <p>Different stack tops pointing to different parents. Make array node for
|
| 298 |
+
# the root where each element points to the corresponding original
|
| 299 |
+
# parent.<br>
|
| 300 |
+
# <embed src="images/SingletonMerge_DiffRootDiffPar.svg" type="image/svg+xml"/></p>
|
| 301 |
+
#
|
| 302 |
+
# @param a the first {@link SingletonPredictionContext}
|
| 303 |
+
# @param b the second {@link SingletonPredictionContext}
|
| 304 |
+
# @param rootIsWildcard {@code true} if this is a local-context merge,
|
| 305 |
+
# otherwise false to indicate a full-context merge
|
| 306 |
+
# @param mergeCache
|
| 307 |
+
#/
|
| 308 |
+
def mergeSingletons(a:SingletonPredictionContext, b:SingletonPredictionContext, rootIsWildcard:bool, mergeCache:dict):
|
| 309 |
+
if mergeCache is not None:
|
| 310 |
+
previous = mergeCache.get((a,b), None)
|
| 311 |
+
if previous is not None:
|
| 312 |
+
return previous
|
| 313 |
+
previous = mergeCache.get((b,a), None)
|
| 314 |
+
if previous is not None:
|
| 315 |
+
return previous
|
| 316 |
+
|
| 317 |
+
merged = mergeRoot(a, b, rootIsWildcard)
|
| 318 |
+
if merged is not None:
|
| 319 |
+
if mergeCache is not None:
|
| 320 |
+
mergeCache[(a, b)] = merged
|
| 321 |
+
return merged
|
| 322 |
+
|
| 323 |
+
if a.returnState==b.returnState:
|
| 324 |
+
parent = merge(a.parentCtx, b.parentCtx, rootIsWildcard, mergeCache)
|
| 325 |
+
# if parent is same as existing a or b parent or reduced to a parent, return it
|
| 326 |
+
if parent == a.parentCtx:
|
| 327 |
+
return a # ax + bx = ax, if a=b
|
| 328 |
+
if parent == b.parentCtx:
|
| 329 |
+
return b # ax + bx = bx, if a=b
|
| 330 |
+
# else: ax + ay = a'[x,y]
|
| 331 |
+
# merge parents x and y, giving array node with x,y then remainders
|
| 332 |
+
# of those graphs. dup a, a' points at merged array
|
| 333 |
+
# new joined parent so create new singleton pointing to it, a'
|
| 334 |
+
merged = SingletonPredictionContext.create(parent, a.returnState)
|
| 335 |
+
if mergeCache is not None:
|
| 336 |
+
mergeCache[(a, b)] = merged
|
| 337 |
+
return merged
|
| 338 |
+
else: # a != b payloads differ
|
| 339 |
+
# see if we can collapse parents due to $+x parents if local ctx
|
| 340 |
+
singleParent = None
|
| 341 |
+
if a is b or (a.parentCtx is not None and a.parentCtx==b.parentCtx): # ax + bx = [a,b]x
|
| 342 |
+
singleParent = a.parentCtx
|
| 343 |
+
if singleParent is not None: # parents are same
|
| 344 |
+
# sort payloads and use same parent
|
| 345 |
+
payloads = [ a.returnState, b.returnState ]
|
| 346 |
+
if a.returnState > b.returnState:
|
| 347 |
+
payloads = [ b.returnState, a.returnState ]
|
| 348 |
+
parents = [singleParent, singleParent]
|
| 349 |
+
merged = ArrayPredictionContext(parents, payloads)
|
| 350 |
+
if mergeCache is not None:
|
| 351 |
+
mergeCache[(a, b)] = merged
|
| 352 |
+
return merged
|
| 353 |
+
# parents differ and can't merge them. Just pack together
|
| 354 |
+
# into array; can't merge.
|
| 355 |
+
# ax + by = [ax,by]
|
| 356 |
+
payloads = [ a.returnState, b.returnState ]
|
| 357 |
+
parents = [ a.parentCtx, b.parentCtx ]
|
| 358 |
+
if a.returnState > b.returnState: # sort by payload
|
| 359 |
+
payloads = [ b.returnState, a.returnState ]
|
| 360 |
+
parents = [ b.parentCtx, a.parentCtx ]
|
| 361 |
+
merged = ArrayPredictionContext(parents, payloads)
|
| 362 |
+
if mergeCache is not None:
|
| 363 |
+
mergeCache[(a, b)] = merged
|
| 364 |
+
return merged
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
#
|
| 368 |
+
# Handle case where at least one of {@code a} or {@code b} is
|
| 369 |
+
# {@link #EMPTY}. In the following diagrams, the symbol {@code $} is used
|
| 370 |
+
# to represent {@link #EMPTY}.
|
| 371 |
+
#
|
| 372 |
+
# <h2>Local-Context Merges</h2>
|
| 373 |
+
#
|
| 374 |
+
# <p>These local-context merge operations are used when {@code rootIsWildcard}
|
| 375 |
+
# is true.</p>
|
| 376 |
+
#
|
| 377 |
+
# <p>{@link #EMPTY} is superset of any graph; return {@link #EMPTY}.<br>
|
| 378 |
+
# <embed src="images/LocalMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
|
| 379 |
+
#
|
| 380 |
+
# <p>{@link #EMPTY} and anything is {@code #EMPTY}, so merged parent is
|
| 381 |
+
# {@code #EMPTY}; return left graph.<br>
|
| 382 |
+
# <embed src="images/LocalMerge_EmptyParent.svg" type="image/svg+xml"/></p>
|
| 383 |
+
#
|
| 384 |
+
# <p>Special case of last merge if local context.<br>
|
| 385 |
+
# <embed src="images/LocalMerge_DiffRoots.svg" type="image/svg+xml"/></p>
|
| 386 |
+
#
|
| 387 |
+
# <h2>Full-Context Merges</h2>
|
| 388 |
+
#
|
| 389 |
+
# <p>These full-context merge operations are used when {@code rootIsWildcard}
|
| 390 |
+
# is false.</p>
|
| 391 |
+
#
|
| 392 |
+
# <p><embed src="images/FullMerge_EmptyRoots.svg" type="image/svg+xml"/></p>
|
| 393 |
+
#
|
| 394 |
+
# <p>Must keep all contexts; {@link #EMPTY} in array is a special value (and
|
| 395 |
+
# null parent).<br>
|
| 396 |
+
# <embed src="images/FullMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
|
| 397 |
+
#
|
| 398 |
+
# <p><embed src="images/FullMerge_SameRoot.svg" type="image/svg+xml"/></p>
|
| 399 |
+
#
|
| 400 |
+
# @param a the first {@link SingletonPredictionContext}
|
| 401 |
+
# @param b the second {@link SingletonPredictionContext}
|
| 402 |
+
# @param rootIsWildcard {@code true} if this is a local-context merge,
|
| 403 |
+
# otherwise false to indicate a full-context merge
|
| 404 |
+
#/
|
| 405 |
+
def mergeRoot(a:SingletonPredictionContext, b:SingletonPredictionContext, rootIsWildcard:bool):
|
| 406 |
+
if rootIsWildcard:
|
| 407 |
+
if a == PredictionContext.EMPTY:
|
| 408 |
+
return PredictionContext.EMPTY ## + b =#
|
| 409 |
+
if b == PredictionContext.EMPTY:
|
| 410 |
+
return PredictionContext.EMPTY # a +# =#
|
| 411 |
+
else:
|
| 412 |
+
if a == PredictionContext.EMPTY and b == PredictionContext.EMPTY:
|
| 413 |
+
return PredictionContext.EMPTY # $ + $ = $
|
| 414 |
+
elif a == PredictionContext.EMPTY: # $ + x = [$,x]
|
| 415 |
+
payloads = [ b.returnState, PredictionContext.EMPTY_RETURN_STATE ]
|
| 416 |
+
parents = [ b.parentCtx, None ]
|
| 417 |
+
return ArrayPredictionContext(parents, payloads)
|
| 418 |
+
elif b == PredictionContext.EMPTY: # x + $ = [$,x] ($ is always first if present)
|
| 419 |
+
payloads = [ a.returnState, PredictionContext.EMPTY_RETURN_STATE ]
|
| 420 |
+
parents = [ a.parentCtx, None ]
|
| 421 |
+
return ArrayPredictionContext(parents, payloads)
|
| 422 |
+
return None
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
#
|
| 426 |
+
# Merge two {@link ArrayPredictionContext} instances.
|
| 427 |
+
#
|
| 428 |
+
# <p>Different tops, different parents.<br>
|
| 429 |
+
# <embed src="images/ArrayMerge_DiffTopDiffPar.svg" type="image/svg+xml"/></p>
|
| 430 |
+
#
|
| 431 |
+
# <p>Shared top, same parents.<br>
|
| 432 |
+
# <embed src="images/ArrayMerge_ShareTopSamePar.svg" type="image/svg+xml"/></p>
|
| 433 |
+
#
|
| 434 |
+
# <p>Shared top, different parents.<br>
|
| 435 |
+
# <embed src="images/ArrayMerge_ShareTopDiffPar.svg" type="image/svg+xml"/></p>
|
| 436 |
+
#
|
| 437 |
+
# <p>Shared top, all shared parents.<br>
|
| 438 |
+
# <embed src="images/ArrayMerge_ShareTopSharePar.svg" type="image/svg+xml"/></p>
|
| 439 |
+
#
|
| 440 |
+
# <p>Equal tops, merge parents and reduce top to
|
| 441 |
+
# {@link SingletonPredictionContext}.<br>
|
| 442 |
+
# <embed src="images/ArrayMerge_EqualTop.svg" type="image/svg+xml"/></p>
|
| 443 |
+
#/
|
| 444 |
+
def mergeArrays(a:ArrayPredictionContext, b:ArrayPredictionContext, rootIsWildcard:bool, mergeCache:dict):
|
| 445 |
+
if mergeCache is not None:
|
| 446 |
+
previous = mergeCache.get((a,b), None)
|
| 447 |
+
if previous is not None:
|
| 448 |
+
return previous
|
| 449 |
+
previous = mergeCache.get((b,a), None)
|
| 450 |
+
if previous is not None:
|
| 451 |
+
return previous
|
| 452 |
+
|
| 453 |
+
# merge sorted payloads a + b => M
|
| 454 |
+
i = 0 # walks a
|
| 455 |
+
j = 0 # walks b
|
| 456 |
+
k = 0 # walks target M array
|
| 457 |
+
|
| 458 |
+
mergedReturnStates = [None] * (len(a.returnStates) + len( b.returnStates))
|
| 459 |
+
mergedParents = [None] * len(mergedReturnStates)
|
| 460 |
+
# walk and merge to yield mergedParents, mergedReturnStates
|
| 461 |
+
while i<len(a.returnStates) and j<len(b.returnStates):
|
| 462 |
+
a_parent = a.parents[i]
|
| 463 |
+
b_parent = b.parents[j]
|
| 464 |
+
if a.returnStates[i]==b.returnStates[j]:
|
| 465 |
+
# same payload (stack tops are equal), must yield merged singleton
|
| 466 |
+
payload = a.returnStates[i]
|
| 467 |
+
# $+$ = $
|
| 468 |
+
bothDollars = payload == PredictionContext.EMPTY_RETURN_STATE and \
|
| 469 |
+
a_parent is None and b_parent is None
|
| 470 |
+
ax_ax = (a_parent is not None and b_parent is not None) and a_parent==b_parent # ax+ax -> ax
|
| 471 |
+
if bothDollars or ax_ax:
|
| 472 |
+
mergedParents[k] = a_parent # choose left
|
| 473 |
+
mergedReturnStates[k] = payload
|
| 474 |
+
else: # ax+ay -> a'[x,y]
|
| 475 |
+
mergedParent = merge(a_parent, b_parent, rootIsWildcard, mergeCache)
|
| 476 |
+
mergedParents[k] = mergedParent
|
| 477 |
+
mergedReturnStates[k] = payload
|
| 478 |
+
i += 1 # hop over left one as usual
|
| 479 |
+
j += 1 # but also skip one in right side since we merge
|
| 480 |
+
elif a.returnStates[i]<b.returnStates[j]: # copy a[i] to M
|
| 481 |
+
mergedParents[k] = a_parent
|
| 482 |
+
mergedReturnStates[k] = a.returnStates[i]
|
| 483 |
+
i += 1
|
| 484 |
+
else: # b > a, copy b[j] to M
|
| 485 |
+
mergedParents[k] = b_parent
|
| 486 |
+
mergedReturnStates[k] = b.returnStates[j]
|
| 487 |
+
j += 1
|
| 488 |
+
k += 1
|
| 489 |
+
|
| 490 |
+
# copy over any payloads remaining in either array
|
| 491 |
+
if i < len(a.returnStates):
|
| 492 |
+
for p in range(i, len(a.returnStates)):
|
| 493 |
+
mergedParents[k] = a.parents[p]
|
| 494 |
+
mergedReturnStates[k] = a.returnStates[p]
|
| 495 |
+
k += 1
|
| 496 |
+
else:
|
| 497 |
+
for p in range(j, len(b.returnStates)):
|
| 498 |
+
mergedParents[k] = b.parents[p]
|
| 499 |
+
mergedReturnStates[k] = b.returnStates[p]
|
| 500 |
+
k += 1
|
| 501 |
+
|
| 502 |
+
# trim merged if we combined a few that had same stack tops
|
| 503 |
+
if k < len(mergedParents): # write index < last position; trim
|
| 504 |
+
if k == 1: # for just one merged element, return singleton top
|
| 505 |
+
merged = SingletonPredictionContext.create(mergedParents[0], mergedReturnStates[0])
|
| 506 |
+
if mergeCache is not None:
|
| 507 |
+
mergeCache[(a,b)] = merged
|
| 508 |
+
return merged
|
| 509 |
+
mergedParents = mergedParents[0:k]
|
| 510 |
+
mergedReturnStates = mergedReturnStates[0:k]
|
| 511 |
+
|
| 512 |
+
merged = ArrayPredictionContext(mergedParents, mergedReturnStates)
|
| 513 |
+
|
| 514 |
+
# if we created same array as a or b, return that instead
|
| 515 |
+
# TODO: track whether this is possible above during merge sort for speed
|
| 516 |
+
if merged==a:
|
| 517 |
+
if mergeCache is not None:
|
| 518 |
+
mergeCache[(a,b)] = a
|
| 519 |
+
return a
|
| 520 |
+
if merged==b:
|
| 521 |
+
if mergeCache is not None:
|
| 522 |
+
mergeCache[(a,b)] = b
|
| 523 |
+
return b
|
| 524 |
+
combineCommonParents(mergedParents)
|
| 525 |
+
|
| 526 |
+
if mergeCache is not None:
|
| 527 |
+
mergeCache[(a,b)] = merged
|
| 528 |
+
return merged
|
| 529 |
+
|
| 530 |
+
|
| 531 |
+
#
|
| 532 |
+
# Make pass over all <em>M</em> {@code parents}; merge any {@code equals()}
|
| 533 |
+
# ones.
|
| 534 |
+
#/
|
| 535 |
+
def combineCommonParents(parents:list):
|
| 536 |
+
uniqueParents = dict()
|
| 537 |
+
|
| 538 |
+
for p in range(0, len(parents)):
|
| 539 |
+
parent = parents[p]
|
| 540 |
+
if uniqueParents.get(parent, None) is None:
|
| 541 |
+
uniqueParents[parent] = parent
|
| 542 |
+
|
| 543 |
+
for p in range(0, len(parents)):
|
| 544 |
+
parents[p] = uniqueParents[parents[p]]
|
| 545 |
+
|
| 546 |
+
def getCachedPredictionContext(context:PredictionContext, contextCache:PredictionContextCache, visited:dict):
|
| 547 |
+
if context.isEmpty():
|
| 548 |
+
return context
|
| 549 |
+
existing = visited.get(context)
|
| 550 |
+
if existing is not None:
|
| 551 |
+
return existing
|
| 552 |
+
existing = contextCache.get(context)
|
| 553 |
+
if existing is not None:
|
| 554 |
+
visited[context] = existing
|
| 555 |
+
return existing
|
| 556 |
+
changed = False
|
| 557 |
+
parents = [None] * len(context)
|
| 558 |
+
for i in range(0, len(parents)):
|
| 559 |
+
parent = getCachedPredictionContext(context.getParent(i), contextCache, visited)
|
| 560 |
+
if changed or parent is not context.getParent(i):
|
| 561 |
+
if not changed:
|
| 562 |
+
parents = [context.getParent(j) for j in range(len(context))]
|
| 563 |
+
changed = True
|
| 564 |
+
parents[i] = parent
|
| 565 |
+
if not changed:
|
| 566 |
+
contextCache.add(context)
|
| 567 |
+
visited[context] = context
|
| 568 |
+
return context
|
| 569 |
+
|
| 570 |
+
updated = None
|
| 571 |
+
if len(parents) == 0:
|
| 572 |
+
updated = PredictionContext.EMPTY
|
| 573 |
+
elif len(parents) == 1:
|
| 574 |
+
updated = SingletonPredictionContext.create(parents[0], context.getReturnState(0))
|
| 575 |
+
else:
|
| 576 |
+
updated = ArrayPredictionContext(parents, context.returnStates)
|
| 577 |
+
|
| 578 |
+
contextCache.add(updated)
|
| 579 |
+
visited[updated] = updated
|
| 580 |
+
visited[context] = updated
|
| 581 |
+
|
| 582 |
+
return updated
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
# # extra structures, but cut/paste/morphed works, so leave it.
|
| 586 |
+
# # seems to do a breadth-first walk
|
| 587 |
+
# public static List<PredictionContext> getAllNodes(PredictionContext context) {
|
| 588 |
+
# Map<PredictionContext, PredictionContext> visited =
|
| 589 |
+
# new IdentityHashMap<PredictionContext, PredictionContext>();
|
| 590 |
+
# Deque<PredictionContext> workList = new ArrayDeque<PredictionContext>();
|
| 591 |
+
# workList.add(context);
|
| 592 |
+
# visited.put(context, context);
|
| 593 |
+
# List<PredictionContext> nodes = new ArrayList<PredictionContext>();
|
| 594 |
+
# while (!workList.isEmpty()) {
|
| 595 |
+
# PredictionContext current = workList.pop();
|
| 596 |
+
# nodes.add(current);
|
| 597 |
+
# for (int i = 0; i < current.size(); i++) {
|
| 598 |
+
# PredictionContext parent = current.getParent(i);
|
| 599 |
+
# if ( parent!=null && visited.put(parent, parent) == null) {
|
| 600 |
+
# workList.push(parent);
|
| 601 |
+
# }
|
| 602 |
+
# }
|
| 603 |
+
# }
|
| 604 |
+
# return nodes;
|
| 605 |
+
# }
|
| 606 |
+
|
| 607 |
+
# ter's recursive version of Sam's getAllNodes()
|
| 608 |
+
def getAllContextNodes(context:PredictionContext, nodes:list=None, visited:dict=None):
|
| 609 |
+
if nodes is None:
|
| 610 |
+
nodes = list()
|
| 611 |
+
return getAllContextNodes(context, nodes, visited)
|
| 612 |
+
elif visited is None:
|
| 613 |
+
visited = dict()
|
| 614 |
+
return getAllContextNodes(context, nodes, visited)
|
| 615 |
+
else:
|
| 616 |
+
if context is None or visited.get(context, None) is not None:
|
| 617 |
+
return nodes
|
| 618 |
+
visited.put(context, context)
|
| 619 |
+
nodes.add(context)
|
| 620 |
+
for i in range(0, len(context)):
|
| 621 |
+
getAllContextNodes(context.getParent(i), nodes, visited)
|
| 622 |
+
return nodes
|
| 623 |
+
|
cameras/deps/antlr4/Recognizer.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
from antlr4.RuleContext import RuleContext
|
| 7 |
+
from antlr4.Token import Token
|
| 8 |
+
from antlr4.error.ErrorListener import ProxyErrorListener, ConsoleErrorListener
|
| 9 |
+
|
| 10 |
+
# need forward delcaration
|
| 11 |
+
RecognitionException = None
|
| 12 |
+
|
| 13 |
+
class Recognizer(object):
|
| 14 |
+
__slots__ = ('_listeners', '_interp', '_stateNumber')
|
| 15 |
+
|
| 16 |
+
tokenTypeMapCache = dict()
|
| 17 |
+
ruleIndexMapCache = dict()
|
| 18 |
+
|
| 19 |
+
def __init__(self):
|
| 20 |
+
self._listeners = [ ConsoleErrorListener.INSTANCE ]
|
| 21 |
+
self._interp = None
|
| 22 |
+
self._stateNumber = -1
|
| 23 |
+
|
| 24 |
+
def extractVersion(self, version):
|
| 25 |
+
pos = version.find(".")
|
| 26 |
+
major = version[0:pos]
|
| 27 |
+
version = version[pos+1:]
|
| 28 |
+
pos = version.find(".")
|
| 29 |
+
if pos==-1:
|
| 30 |
+
pos = version.find("-")
|
| 31 |
+
if pos==-1:
|
| 32 |
+
pos = len(version)
|
| 33 |
+
minor = version[0:pos]
|
| 34 |
+
return major, minor
|
| 35 |
+
|
| 36 |
+
def checkVersion(self, toolVersion):
|
| 37 |
+
runtimeVersion = "4.9.3"
|
| 38 |
+
rvmajor, rvminor = self.extractVersion(runtimeVersion)
|
| 39 |
+
tvmajor, tvminor = self.extractVersion(toolVersion)
|
| 40 |
+
if rvmajor!=tvmajor or rvminor!=tvminor:
|
| 41 |
+
print("ANTLR runtime and generated code versions disagree: "+runtimeVersion+"!="+toolVersion)
|
| 42 |
+
|
| 43 |
+
def addErrorListener(self, listener):
|
| 44 |
+
self._listeners.append(listener)
|
| 45 |
+
|
| 46 |
+
def removeErrorListener(self, listener):
|
| 47 |
+
self._listeners.remove(listener)
|
| 48 |
+
|
| 49 |
+
def removeErrorListeners(self):
|
| 50 |
+
self._listeners = []
|
| 51 |
+
|
| 52 |
+
def getTokenTypeMap(self):
|
| 53 |
+
tokenNames = self.getTokenNames()
|
| 54 |
+
if tokenNames is None:
|
| 55 |
+
from antlr4.error.Errors import UnsupportedOperationException
|
| 56 |
+
raise UnsupportedOperationException("The current recognizer does not provide a list of token names.")
|
| 57 |
+
result = self.tokenTypeMapCache.get(tokenNames, None)
|
| 58 |
+
if result is None:
|
| 59 |
+
result = zip( tokenNames, range(0, len(tokenNames)))
|
| 60 |
+
result["EOF"] = Token.EOF
|
| 61 |
+
self.tokenTypeMapCache[tokenNames] = result
|
| 62 |
+
return result
|
| 63 |
+
|
| 64 |
+
# Get a map from rule names to rule indexes.
|
| 65 |
+
#
|
| 66 |
+
# <p>Used for XPath and tree pattern compilation.</p>
|
| 67 |
+
#
|
| 68 |
+
def getRuleIndexMap(self):
|
| 69 |
+
ruleNames = self.getRuleNames()
|
| 70 |
+
if ruleNames is None:
|
| 71 |
+
from antlr4.error.Errors import UnsupportedOperationException
|
| 72 |
+
raise UnsupportedOperationException("The current recognizer does not provide a list of rule names.")
|
| 73 |
+
result = self.ruleIndexMapCache.get(ruleNames, None)
|
| 74 |
+
if result is None:
|
| 75 |
+
result = zip( ruleNames, range(0, len(ruleNames)))
|
| 76 |
+
self.ruleIndexMapCache[ruleNames] = result
|
| 77 |
+
return result
|
| 78 |
+
|
| 79 |
+
def getTokenType(self, tokenName:str):
|
| 80 |
+
ttype = self.getTokenTypeMap().get(tokenName, None)
|
| 81 |
+
if ttype is not None:
|
| 82 |
+
return ttype
|
| 83 |
+
else:
|
| 84 |
+
return Token.INVALID_TYPE
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
# What is the error header, normally line/character position information?#
|
| 88 |
+
def getErrorHeader(self, e:RecognitionException):
|
| 89 |
+
line = e.getOffendingToken().line
|
| 90 |
+
column = e.getOffendingToken().column
|
| 91 |
+
return "line "+line+":"+column
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# How should a token be displayed in an error message? The default
|
| 95 |
+
# is to display just the text, but during development you might
|
| 96 |
+
# want to have a lot of information spit out. Override in that case
|
| 97 |
+
# to use t.toString() (which, for CommonToken, dumps everything about
|
| 98 |
+
# the token). This is better than forcing you to override a method in
|
| 99 |
+
# your token objects because you don't have to go modify your lexer
|
| 100 |
+
# so that it creates a new Java type.
|
| 101 |
+
#
|
| 102 |
+
# @deprecated This method is not called by the ANTLR 4 Runtime. Specific
|
| 103 |
+
# implementations of {@link ANTLRErrorStrategy} may provide a similar
|
| 104 |
+
# feature when necessary. For example, see
|
| 105 |
+
# {@link DefaultErrorStrategy#getTokenErrorDisplay}.
|
| 106 |
+
#
|
| 107 |
+
def getTokenErrorDisplay(self, t:Token):
|
| 108 |
+
if t is None:
|
| 109 |
+
return "<no token>"
|
| 110 |
+
s = t.text
|
| 111 |
+
if s is None:
|
| 112 |
+
if t.type==Token.EOF:
|
| 113 |
+
s = "<EOF>"
|
| 114 |
+
else:
|
| 115 |
+
s = "<" + str(t.type) + ">"
|
| 116 |
+
s = s.replace("\n","\\n")
|
| 117 |
+
s = s.replace("\r","\\r")
|
| 118 |
+
s = s.replace("\t","\\t")
|
| 119 |
+
return "'" + s + "'"
|
| 120 |
+
|
| 121 |
+
def getErrorListenerDispatch(self):
|
| 122 |
+
return ProxyErrorListener(self._listeners)
|
| 123 |
+
|
| 124 |
+
# subclass needs to override these if there are sempreds or actions
|
| 125 |
+
# that the ATN interp needs to execute
|
| 126 |
+
def sempred(self, localctx:RuleContext, ruleIndex:int, actionIndex:int):
|
| 127 |
+
return True
|
| 128 |
+
|
| 129 |
+
def precpred(self, localctx:RuleContext , precedence:int):
|
| 130 |
+
return True
|
| 131 |
+
|
| 132 |
+
@property
|
| 133 |
+
def state(self):
|
| 134 |
+
return self._stateNumber
|
| 135 |
+
|
| 136 |
+
# Indicate that the recognizer has changed internal state that is
|
| 137 |
+
# consistent with the ATN state passed in. This way we always know
|
| 138 |
+
# where we are in the ATN as the parser goes along. The rule
|
| 139 |
+
# context objects form a stack that lets us see the stack of
|
| 140 |
+
# invoking rules. Combine this and we have complete ATN
|
| 141 |
+
# configuration information.
|
| 142 |
+
|
| 143 |
+
@state.setter
|
| 144 |
+
def state(self, atnState:int):
|
| 145 |
+
self._stateNumber = atnState
|
| 146 |
+
|
| 147 |
+
del RecognitionException
|
cameras/deps/antlr4/RuleContext.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#/
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
# A rule context is a record of a single rule invocation. It knows
|
| 8 |
+
# which context invoked it, if any. If there is no parent context, then
|
| 9 |
+
# naturally the invoking state is not valid. The parent link
|
| 10 |
+
# provides a chain upwards from the current rule invocation to the root
|
| 11 |
+
# of the invocation tree, forming a stack. We actually carry no
|
| 12 |
+
# information about the rule associated with this context (except
|
| 13 |
+
# when parsing). We keep only the state number of the invoking state from
|
| 14 |
+
# the ATN submachine that invoked this. Contrast this with the s
|
| 15 |
+
# pointer inside ParserRuleContext that tracks the current state
|
| 16 |
+
# being "executed" for the current rule.
|
| 17 |
+
#
|
| 18 |
+
# The parent contexts are useful for computing lookahead sets and
|
| 19 |
+
# getting error information.
|
| 20 |
+
#
|
| 21 |
+
# These objects are used during parsing and prediction.
|
| 22 |
+
# For the special case of parsers, we use the subclass
|
| 23 |
+
# ParserRuleContext.
|
| 24 |
+
#
|
| 25 |
+
# @see ParserRuleContext
|
| 26 |
+
#/
|
| 27 |
+
from io import StringIO
|
| 28 |
+
from antlr4.tree.Tree import RuleNode, INVALID_INTERVAL, ParseTreeVisitor
|
| 29 |
+
from antlr4.tree.Trees import Trees
|
| 30 |
+
|
| 31 |
+
# need forward declarations
|
| 32 |
+
RuleContext = None
|
| 33 |
+
Parser = None
|
| 34 |
+
|
| 35 |
+
class RuleContext(RuleNode):
|
| 36 |
+
__slots__ = ('parentCtx', 'invokingState')
|
| 37 |
+
EMPTY = None
|
| 38 |
+
|
| 39 |
+
def __init__(self, parent:RuleContext=None, invokingState:int=-1):
|
| 40 |
+
super().__init__()
|
| 41 |
+
# What context invoked this rule?
|
| 42 |
+
self.parentCtx = parent
|
| 43 |
+
# What state invoked the rule associated with this context?
|
| 44 |
+
# The "return address" is the followState of invokingState
|
| 45 |
+
# If parent is null, this should be -1.
|
| 46 |
+
self.invokingState = invokingState
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def depth(self):
|
| 50 |
+
n = 0
|
| 51 |
+
p = self
|
| 52 |
+
while p is not None:
|
| 53 |
+
p = p.parentCtx
|
| 54 |
+
n += 1
|
| 55 |
+
return n
|
| 56 |
+
|
| 57 |
+
# A context is empty if there is no invoking state; meaning nobody call
|
| 58 |
+
# current context.
|
| 59 |
+
def isEmpty(self):
|
| 60 |
+
return self.invokingState == -1
|
| 61 |
+
|
| 62 |
+
# satisfy the ParseTree / SyntaxTree interface
|
| 63 |
+
|
| 64 |
+
def getSourceInterval(self):
|
| 65 |
+
return INVALID_INTERVAL
|
| 66 |
+
|
| 67 |
+
def getRuleContext(self):
|
| 68 |
+
return self
|
| 69 |
+
|
| 70 |
+
def getPayload(self):
|
| 71 |
+
return self
|
| 72 |
+
|
| 73 |
+
# Return the combined text of all child nodes. This method only considers
|
| 74 |
+
# tokens which have been added to the parse tree.
|
| 75 |
+
# <p>
|
| 76 |
+
# Since tokens on hidden channels (e.g. whitespace or comments) are not
|
| 77 |
+
# added to the parse trees, they will not appear in the output of this
|
| 78 |
+
# method.
|
| 79 |
+
#/
|
| 80 |
+
def getText(self):
|
| 81 |
+
if self.getChildCount() == 0:
|
| 82 |
+
return ""
|
| 83 |
+
with StringIO() as builder:
|
| 84 |
+
for child in self.getChildren():
|
| 85 |
+
builder.write(child.getText())
|
| 86 |
+
return builder.getvalue()
|
| 87 |
+
|
| 88 |
+
def getRuleIndex(self):
|
| 89 |
+
return -1
|
| 90 |
+
|
| 91 |
+
# For rule associated with this parse tree internal node, return
|
| 92 |
+
# the outer alternative number used to match the input. Default
|
| 93 |
+
# implementation does not compute nor store this alt num. Create
|
| 94 |
+
# a subclass of ParserRuleContext with backing field and set
|
| 95 |
+
# option contextSuperClass.
|
| 96 |
+
# to set it.
|
| 97 |
+
def getAltNumber(self):
|
| 98 |
+
return 0 # should use ATN.INVALID_ALT_NUMBER but won't compile
|
| 99 |
+
|
| 100 |
+
# Set the outer alternative number for this context node. Default
|
| 101 |
+
# implementation does nothing to avoid backing field overhead for
|
| 102 |
+
# trees that don't need it. Create
|
| 103 |
+
# a subclass of ParserRuleContext with backing field and set
|
| 104 |
+
# option contextSuperClass.
|
| 105 |
+
def setAltNumber(self, altNumber:int):
|
| 106 |
+
pass
|
| 107 |
+
|
| 108 |
+
def getChild(self, i:int):
|
| 109 |
+
return None
|
| 110 |
+
|
| 111 |
+
def getChildCount(self):
|
| 112 |
+
return 0
|
| 113 |
+
|
| 114 |
+
def getChildren(self):
|
| 115 |
+
for c in []:
|
| 116 |
+
yield c
|
| 117 |
+
|
| 118 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 119 |
+
return visitor.visitChildren(self)
|
| 120 |
+
|
| 121 |
+
# # Call this method to view a parse tree in a dialog box visually.#/
|
| 122 |
+
# public Future<JDialog> inspect(@Nullable Parser parser) {
|
| 123 |
+
# List<String> ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null;
|
| 124 |
+
# return inspect(ruleNames);
|
| 125 |
+
# }
|
| 126 |
+
#
|
| 127 |
+
# public Future<JDialog> inspect(@Nullable List<String> ruleNames) {
|
| 128 |
+
# TreeViewer viewer = new TreeViewer(ruleNames, this);
|
| 129 |
+
# return viewer.open();
|
| 130 |
+
# }
|
| 131 |
+
#
|
| 132 |
+
# # Save this tree in a postscript file#/
|
| 133 |
+
# public void save(@Nullable Parser parser, String fileName)
|
| 134 |
+
# throws IOException, PrintException
|
| 135 |
+
# {
|
| 136 |
+
# List<String> ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null;
|
| 137 |
+
# save(ruleNames, fileName);
|
| 138 |
+
# }
|
| 139 |
+
#
|
| 140 |
+
# # Save this tree in a postscript file using a particular font name and size#/
|
| 141 |
+
# public void save(@Nullable Parser parser, String fileName,
|
| 142 |
+
# String fontName, int fontSize)
|
| 143 |
+
# throws IOException
|
| 144 |
+
# {
|
| 145 |
+
# List<String> ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null;
|
| 146 |
+
# save(ruleNames, fileName, fontName, fontSize);
|
| 147 |
+
# }
|
| 148 |
+
#
|
| 149 |
+
# # Save this tree in a postscript file#/
|
| 150 |
+
# public void save(@Nullable List<String> ruleNames, String fileName)
|
| 151 |
+
# throws IOException, PrintException
|
| 152 |
+
# {
|
| 153 |
+
# Trees.writePS(this, ruleNames, fileName);
|
| 154 |
+
# }
|
| 155 |
+
#
|
| 156 |
+
# # Save this tree in a postscript file using a particular font name and size#/
|
| 157 |
+
# public void save(@Nullable List<String> ruleNames, String fileName,
|
| 158 |
+
# String fontName, int fontSize)
|
| 159 |
+
# throws IOException
|
| 160 |
+
# {
|
| 161 |
+
# Trees.writePS(this, ruleNames, fileName, fontName, fontSize);
|
| 162 |
+
# }
|
| 163 |
+
#
|
| 164 |
+
# # Print out a whole tree, not just a node, in LISP format
|
| 165 |
+
# # (root child1 .. childN). Print just a node if this is a leaf.
|
| 166 |
+
# # We have to know the recognizer so we can get rule names.
|
| 167 |
+
# #/
|
| 168 |
+
# @Override
|
| 169 |
+
# public String toStringTree(@Nullable Parser recog) {
|
| 170 |
+
# return Trees.toStringTree(this, recog);
|
| 171 |
+
# }
|
| 172 |
+
#
|
| 173 |
+
# Print out a whole tree, not just a node, in LISP format
|
| 174 |
+
# (root child1 .. childN). Print just a node if this is a leaf.
|
| 175 |
+
#
|
| 176 |
+
def toStringTree(self, ruleNames:list=None, recog:Parser=None):
|
| 177 |
+
return Trees.toStringTree(self, ruleNames=ruleNames, recog=recog)
|
| 178 |
+
# }
|
| 179 |
+
#
|
| 180 |
+
# @Override
|
| 181 |
+
# public String toStringTree() {
|
| 182 |
+
# return toStringTree((List<String>)null);
|
| 183 |
+
# }
|
| 184 |
+
#
|
| 185 |
+
def __str__(self):
|
| 186 |
+
return self.toString(None, None)
|
| 187 |
+
|
| 188 |
+
# @Override
|
| 189 |
+
# public String toString() {
|
| 190 |
+
# return toString((List<String>)null, (RuleContext)null);
|
| 191 |
+
# }
|
| 192 |
+
#
|
| 193 |
+
# public final String toString(@Nullable Recognizer<?,?> recog) {
|
| 194 |
+
# return toString(recog, ParserRuleContext.EMPTY);
|
| 195 |
+
# }
|
| 196 |
+
#
|
| 197 |
+
# public final String toString(@Nullable List<String> ruleNames) {
|
| 198 |
+
# return toString(ruleNames, null);
|
| 199 |
+
# }
|
| 200 |
+
#
|
| 201 |
+
# // recog null unless ParserRuleContext, in which case we use subclass toString(...)
|
| 202 |
+
# public String toString(@Nullable Recognizer<?,?> recog, @Nullable RuleContext stop) {
|
| 203 |
+
# String[] ruleNames = recog != null ? recog.getRuleNames() : null;
|
| 204 |
+
# List<String> ruleNamesList = ruleNames != null ? Arrays.asList(ruleNames) : null;
|
| 205 |
+
# return toString(ruleNamesList, stop);
|
| 206 |
+
# }
|
| 207 |
+
|
| 208 |
+
def toString(self, ruleNames:list, stop:RuleContext)->str:
|
| 209 |
+
with StringIO() as buf:
|
| 210 |
+
p = self
|
| 211 |
+
buf.write("[")
|
| 212 |
+
while p is not None and p is not stop:
|
| 213 |
+
if ruleNames is None:
|
| 214 |
+
if not p.isEmpty():
|
| 215 |
+
buf.write(str(p.invokingState))
|
| 216 |
+
else:
|
| 217 |
+
ri = p.getRuleIndex()
|
| 218 |
+
ruleName = ruleNames[ri] if ri >= 0 and ri < len(ruleNames) else str(ri)
|
| 219 |
+
buf.write(ruleName)
|
| 220 |
+
|
| 221 |
+
if p.parentCtx is not None and (ruleNames is not None or not p.parentCtx.isEmpty()):
|
| 222 |
+
buf.write(" ")
|
| 223 |
+
|
| 224 |
+
p = p.parentCtx
|
| 225 |
+
|
| 226 |
+
buf.write("]")
|
| 227 |
+
return buf.getvalue()
|
cameras/deps/antlr4/StdinStream.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import codecs
|
| 2 |
+
import sys
|
| 3 |
+
|
| 4 |
+
from antlr4.InputStream import InputStream
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class StdinStream(InputStream):
|
| 8 |
+
def __init__(self, encoding:str='ascii', errors:str='strict') -> None:
|
| 9 |
+
bytes = sys.stdin.buffer.read()
|
| 10 |
+
data = codecs.decode(bytes, encoding, errors)
|
| 11 |
+
super().__init__(data)
|
cameras/deps/antlr4/Token.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#
|
| 5 |
+
|
| 6 |
+
# A token has properties: text, type, line, character position in the line
|
| 7 |
+
# (so we can ignore tabs), token channel, index, and source from which
|
| 8 |
+
# we obtained this token.
|
| 9 |
+
from io import StringIO
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class Token (object):
|
| 13 |
+
__slots__ = ('source', 'type', 'channel', 'start', 'stop', 'tokenIndex', 'line', 'column', '_text')
|
| 14 |
+
|
| 15 |
+
INVALID_TYPE = 0
|
| 16 |
+
|
| 17 |
+
# During lookahead operations, this "token" signifies we hit rule end ATN state
|
| 18 |
+
# and did not follow it despite needing to.
|
| 19 |
+
EPSILON = -2
|
| 20 |
+
|
| 21 |
+
MIN_USER_TOKEN_TYPE = 1
|
| 22 |
+
|
| 23 |
+
EOF = -1
|
| 24 |
+
|
| 25 |
+
# All tokens go to the parser (unless skip() is called in that rule)
|
| 26 |
+
# on a particular "channel". The parser tunes to a particular channel
|
| 27 |
+
# so that whitespace etc... can go to the parser on a "hidden" channel.
|
| 28 |
+
|
| 29 |
+
DEFAULT_CHANNEL = 0
|
| 30 |
+
|
| 31 |
+
# Anything on different channel than DEFAULT_CHANNEL is not parsed
|
| 32 |
+
# by parser.
|
| 33 |
+
|
| 34 |
+
HIDDEN_CHANNEL = 1
|
| 35 |
+
|
| 36 |
+
def __init__(self):
|
| 37 |
+
self.source = None
|
| 38 |
+
self.type = None # token type of the token
|
| 39 |
+
self.channel = None # The parser ignores everything not on DEFAULT_CHANNEL
|
| 40 |
+
self.start = None # optional; return -1 if not implemented.
|
| 41 |
+
self.stop = None # optional; return -1 if not implemented.
|
| 42 |
+
self.tokenIndex = None # from 0..n-1 of the token object in the input stream
|
| 43 |
+
self.line = None # line=1..n of the 1st character
|
| 44 |
+
self.column = None # beginning of the line at which it occurs, 0..n-1
|
| 45 |
+
self._text = None # text of the token.
|
| 46 |
+
|
| 47 |
+
@property
|
| 48 |
+
def text(self):
|
| 49 |
+
return self._text
|
| 50 |
+
|
| 51 |
+
# Explicitly set the text for this token. If {code text} is not
|
| 52 |
+
# {@code null}, then {@link #getText} will return this value rather than
|
| 53 |
+
# extracting the text from the input.
|
| 54 |
+
#
|
| 55 |
+
# @param text The explicit text of the token, or {@code null} if the text
|
| 56 |
+
# should be obtained from the input along with the start and stop indexes
|
| 57 |
+
# of the token.
|
| 58 |
+
|
| 59 |
+
@text.setter
|
| 60 |
+
def text(self, text:str):
|
| 61 |
+
self._text = text
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def getTokenSource(self):
|
| 65 |
+
return self.source[0]
|
| 66 |
+
|
| 67 |
+
def getInputStream(self):
|
| 68 |
+
return self.source[1]
|
| 69 |
+
|
| 70 |
+
class CommonToken(Token):
|
| 71 |
+
|
| 72 |
+
# An empty {@link Pair} which is used as the default value of
|
| 73 |
+
# {@link #source} for tokens that do not have a source.
|
| 74 |
+
EMPTY_SOURCE = (None, None)
|
| 75 |
+
|
| 76 |
+
def __init__(self, source:tuple = EMPTY_SOURCE, type:int = None, channel:int=Token.DEFAULT_CHANNEL, start:int=-1, stop:int=-1):
|
| 77 |
+
super().__init__()
|
| 78 |
+
self.source = source
|
| 79 |
+
self.type = type
|
| 80 |
+
self.channel = channel
|
| 81 |
+
self.start = start
|
| 82 |
+
self.stop = stop
|
| 83 |
+
self.tokenIndex = -1
|
| 84 |
+
if source[0] is not None:
|
| 85 |
+
self.line = source[0].line
|
| 86 |
+
self.column = source[0].column
|
| 87 |
+
else:
|
| 88 |
+
self.column = -1
|
| 89 |
+
|
| 90 |
+
# Constructs a new {@link CommonToken} as a copy of another {@link Token}.
|
| 91 |
+
#
|
| 92 |
+
# <p>
|
| 93 |
+
# If {@code oldToken} is also a {@link CommonToken} instance, the newly
|
| 94 |
+
# constructed token will share a reference to the {@link #text} field and
|
| 95 |
+
# the {@link Pair} stored in {@link #source}. Otherwise, {@link #text} will
|
| 96 |
+
# be assigned the result of calling {@link #getText}, and {@link #source}
|
| 97 |
+
# will be constructed from the result of {@link Token#getTokenSource} and
|
| 98 |
+
# {@link Token#getInputStream}.</p>
|
| 99 |
+
#
|
| 100 |
+
# @param oldToken The token to copy.
|
| 101 |
+
#
|
| 102 |
+
def clone(self):
|
| 103 |
+
t = CommonToken(self.source, self.type, self.channel, self.start, self.stop)
|
| 104 |
+
t.tokenIndex = self.tokenIndex
|
| 105 |
+
t.line = self.line
|
| 106 |
+
t.column = self.column
|
| 107 |
+
t.text = self.text
|
| 108 |
+
return t
|
| 109 |
+
|
| 110 |
+
@property
|
| 111 |
+
def text(self):
|
| 112 |
+
if self._text is not None:
|
| 113 |
+
return self._text
|
| 114 |
+
input = self.getInputStream()
|
| 115 |
+
if input is None:
|
| 116 |
+
return None
|
| 117 |
+
n = input.size
|
| 118 |
+
if self.start < n and self.stop < n:
|
| 119 |
+
return input.getText(self.start, self.stop)
|
| 120 |
+
else:
|
| 121 |
+
return "<EOF>"
|
| 122 |
+
|
| 123 |
+
@text.setter
|
| 124 |
+
def text(self, text:str):
|
| 125 |
+
self._text = text
|
| 126 |
+
|
| 127 |
+
def __str__(self):
|
| 128 |
+
with StringIO() as buf:
|
| 129 |
+
buf.write("[@")
|
| 130 |
+
buf.write(str(self.tokenIndex))
|
| 131 |
+
buf.write(",")
|
| 132 |
+
buf.write(str(self.start))
|
| 133 |
+
buf.write(":")
|
| 134 |
+
buf.write(str(self.stop))
|
| 135 |
+
buf.write("='")
|
| 136 |
+
txt = self.text
|
| 137 |
+
if txt is not None:
|
| 138 |
+
txt = txt.replace("\n","\\n")
|
| 139 |
+
txt = txt.replace("\r","\\r")
|
| 140 |
+
txt = txt.replace("\t","\\t")
|
| 141 |
+
else:
|
| 142 |
+
txt = "<no text>"
|
| 143 |
+
buf.write(txt)
|
| 144 |
+
buf.write("',<")
|
| 145 |
+
buf.write(str(self.type))
|
| 146 |
+
buf.write(">")
|
| 147 |
+
if self.channel > 0:
|
| 148 |
+
buf.write(",channel=")
|
| 149 |
+
buf.write(str(self.channel))
|
| 150 |
+
buf.write(",")
|
| 151 |
+
buf.write(str(self.line))
|
| 152 |
+
buf.write(":")
|
| 153 |
+
buf.write(str(self.column))
|
| 154 |
+
buf.write("]")
|
| 155 |
+
return buf.getvalue()
|
cameras/deps/antlr4/TokenStreamRewriter.py
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
from io import StringIO
|
| 8 |
+
from antlr4.Token import Token
|
| 9 |
+
|
| 10 |
+
from antlr4.CommonTokenStream import CommonTokenStream
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class TokenStreamRewriter(object):
|
| 14 |
+
__slots__ = ('tokens', 'programs', 'lastRewriteTokenIndexes')
|
| 15 |
+
|
| 16 |
+
DEFAULT_PROGRAM_NAME = "default"
|
| 17 |
+
PROGRAM_INIT_SIZE = 100
|
| 18 |
+
MIN_TOKEN_INDEX = 0
|
| 19 |
+
|
| 20 |
+
def __init__(self, tokens):
|
| 21 |
+
"""
|
| 22 |
+
:type tokens: antlr4.BufferedTokenStream.BufferedTokenStream
|
| 23 |
+
:param tokens:
|
| 24 |
+
:return:
|
| 25 |
+
"""
|
| 26 |
+
super(TokenStreamRewriter, self).__init__()
|
| 27 |
+
self.tokens = tokens
|
| 28 |
+
self.programs = {self.DEFAULT_PROGRAM_NAME: []}
|
| 29 |
+
self.lastRewriteTokenIndexes = {}
|
| 30 |
+
|
| 31 |
+
def getTokenStream(self):
|
| 32 |
+
return self.tokens
|
| 33 |
+
|
| 34 |
+
def rollback(self, instruction_index, program_name):
|
| 35 |
+
ins = self.programs.get(program_name, None)
|
| 36 |
+
if ins:
|
| 37 |
+
self.programs[program_name] = ins[self.MIN_TOKEN_INDEX: instruction_index]
|
| 38 |
+
|
| 39 |
+
def deleteProgram(self, program_name=DEFAULT_PROGRAM_NAME):
|
| 40 |
+
self.rollback(self.MIN_TOKEN_INDEX, program_name)
|
| 41 |
+
|
| 42 |
+
def insertAfterToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
|
| 43 |
+
self.insertAfter(token.tokenIndex, text, program_name)
|
| 44 |
+
|
| 45 |
+
def insertAfter(self, index, text, program_name=DEFAULT_PROGRAM_NAME):
|
| 46 |
+
op = self.InsertAfterOp(self.tokens, index + 1, text)
|
| 47 |
+
rewrites = self.getProgram(program_name)
|
| 48 |
+
op.instructionIndex = len(rewrites)
|
| 49 |
+
rewrites.append(op)
|
| 50 |
+
|
| 51 |
+
def insertBeforeIndex(self, index, text):
|
| 52 |
+
self.insertBefore(self.DEFAULT_PROGRAM_NAME, index, text)
|
| 53 |
+
|
| 54 |
+
def insertBeforeToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
|
| 55 |
+
self.insertBefore(program_name, token.tokenIndex, text)
|
| 56 |
+
|
| 57 |
+
def insertBefore(self, program_name, index, text):
|
| 58 |
+
op = self.InsertBeforeOp(self.tokens, index, text)
|
| 59 |
+
rewrites = self.getProgram(program_name)
|
| 60 |
+
op.instructionIndex = len(rewrites)
|
| 61 |
+
rewrites.append(op)
|
| 62 |
+
|
| 63 |
+
def replaceIndex(self, index, text):
|
| 64 |
+
self.replace(self.DEFAULT_PROGRAM_NAME, index, index, text)
|
| 65 |
+
|
| 66 |
+
def replaceRange(self, from_idx, to_idx, text):
|
| 67 |
+
self.replace(self.DEFAULT_PROGRAM_NAME, from_idx, to_idx, text)
|
| 68 |
+
|
| 69 |
+
def replaceSingleToken(self, token, text):
|
| 70 |
+
self.replace(self.DEFAULT_PROGRAM_NAME, token.tokenIndex, token.tokenIndex, text)
|
| 71 |
+
|
| 72 |
+
def replaceRangeTokens(self, from_token, to_token, text, program_name=DEFAULT_PROGRAM_NAME):
|
| 73 |
+
self.replace(program_name, from_token.tokenIndex, to_token.tokenIndex, text)
|
| 74 |
+
|
| 75 |
+
def replace(self, program_name, from_idx, to_idx, text):
|
| 76 |
+
if any((from_idx > to_idx, from_idx < 0, to_idx < 0, to_idx >= len(self.tokens.tokens))):
|
| 77 |
+
raise ValueError(
|
| 78 |
+
'replace: range invalid: {}..{}(size={})'.format(from_idx, to_idx, len(self.tokens.tokens)))
|
| 79 |
+
op = self.ReplaceOp(from_idx, to_idx, self.tokens, text)
|
| 80 |
+
rewrites = self.getProgram(program_name)
|
| 81 |
+
op.instructionIndex = len(rewrites)
|
| 82 |
+
rewrites.append(op)
|
| 83 |
+
|
| 84 |
+
def deleteToken(self, token):
|
| 85 |
+
self.delete(self.DEFAULT_PROGRAM_NAME, token, token)
|
| 86 |
+
|
| 87 |
+
def deleteIndex(self, index):
|
| 88 |
+
self.delete(self.DEFAULT_PROGRAM_NAME, index, index)
|
| 89 |
+
|
| 90 |
+
def delete(self, program_name, from_idx, to_idx):
|
| 91 |
+
if isinstance(from_idx, Token):
|
| 92 |
+
self.replace(program_name, from_idx.tokenIndex, to_idx.tokenIndex, "")
|
| 93 |
+
else:
|
| 94 |
+
self.replace(program_name, from_idx, to_idx, "")
|
| 95 |
+
|
| 96 |
+
def lastRewriteTokenIndex(self, program_name=DEFAULT_PROGRAM_NAME):
|
| 97 |
+
return self.lastRewriteTokenIndexes.get(program_name, -1)
|
| 98 |
+
|
| 99 |
+
def setLastRewriteTokenIndex(self, program_name, i):
|
| 100 |
+
self.lastRewriteTokenIndexes[program_name] = i
|
| 101 |
+
|
| 102 |
+
def getProgram(self, program_name):
|
| 103 |
+
return self.programs.setdefault(program_name, [])
|
| 104 |
+
|
| 105 |
+
def getDefaultText(self):
|
| 106 |
+
return self.getText(self.DEFAULT_PROGRAM_NAME, 0, len(self.tokens.tokens) - 1)
|
| 107 |
+
|
| 108 |
+
def getText(self, program_name, start:int, stop:int):
|
| 109 |
+
"""
|
| 110 |
+
:return: the text in tokens[start, stop](closed interval)
|
| 111 |
+
"""
|
| 112 |
+
rewrites = self.programs.get(program_name)
|
| 113 |
+
|
| 114 |
+
# ensure start/end are in range
|
| 115 |
+
if stop > len(self.tokens.tokens) - 1:
|
| 116 |
+
stop = len(self.tokens.tokens) - 1
|
| 117 |
+
if start < 0:
|
| 118 |
+
start = 0
|
| 119 |
+
|
| 120 |
+
# if no instructions to execute
|
| 121 |
+
if not rewrites: return self.tokens.getText(start, stop)
|
| 122 |
+
buf = StringIO()
|
| 123 |
+
indexToOp = self._reduceToSingleOperationPerIndex(rewrites)
|
| 124 |
+
i = start
|
| 125 |
+
while all((i <= stop, i < len(self.tokens.tokens))):
|
| 126 |
+
op = indexToOp.pop(i, None)
|
| 127 |
+
token = self.tokens.get(i)
|
| 128 |
+
if op is None:
|
| 129 |
+
if token.type != Token.EOF: buf.write(token.text)
|
| 130 |
+
i += 1
|
| 131 |
+
else:
|
| 132 |
+
i = op.execute(buf)
|
| 133 |
+
|
| 134 |
+
if stop == len(self.tokens.tokens)-1:
|
| 135 |
+
for op in indexToOp.values():
|
| 136 |
+
if op.index >= len(self.tokens.tokens)-1: buf.write(op.text)
|
| 137 |
+
|
| 138 |
+
return buf.getvalue()
|
| 139 |
+
|
| 140 |
+
def _reduceToSingleOperationPerIndex(self, rewrites):
|
| 141 |
+
# Walk replaces
|
| 142 |
+
for i, rop in enumerate(rewrites):
|
| 143 |
+
if any((rop is None, not isinstance(rop, TokenStreamRewriter.ReplaceOp))):
|
| 144 |
+
continue
|
| 145 |
+
# Wipe prior inserts within range
|
| 146 |
+
inserts = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.InsertBeforeOp)]
|
| 147 |
+
for iop in inserts:
|
| 148 |
+
if iop.index == rop.index:
|
| 149 |
+
rewrites[iop.instructionIndex] = None
|
| 150 |
+
rop.text = '{}{}'.format(iop.text, rop.text)
|
| 151 |
+
elif all((iop.index > rop.index, iop.index <= rop.last_index)):
|
| 152 |
+
rewrites[iop.instructionIndex] = None
|
| 153 |
+
|
| 154 |
+
# Drop any prior replaces contained within
|
| 155 |
+
prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]
|
| 156 |
+
for prevRop in prevReplaces:
|
| 157 |
+
if all((prevRop.index >= rop.index, prevRop.last_index <= rop.last_index)):
|
| 158 |
+
rewrites[prevRop.instructionIndex] = None
|
| 159 |
+
continue
|
| 160 |
+
isDisjoint = any((prevRop.last_index<rop.index, prevRop.index>rop.last_index))
|
| 161 |
+
if all((prevRop.text is None, rop.text is None, not isDisjoint)):
|
| 162 |
+
rewrites[prevRop.instructionIndex] = None
|
| 163 |
+
rop.index = min(prevRop.index, rop.index)
|
| 164 |
+
rop.last_index = min(prevRop.last_index, rop.last_index)
|
| 165 |
+
print('New rop {}'.format(rop))
|
| 166 |
+
elif (not(isDisjoint)):
|
| 167 |
+
raise ValueError("replace op boundaries of {} overlap with previous {}".format(rop, prevRop))
|
| 168 |
+
|
| 169 |
+
# Walk inserts
|
| 170 |
+
for i, iop in enumerate(rewrites):
|
| 171 |
+
if any((iop is None, not isinstance(iop, TokenStreamRewriter.InsertBeforeOp))):
|
| 172 |
+
continue
|
| 173 |
+
prevInserts = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.InsertBeforeOp)]
|
| 174 |
+
for prev_index, prevIop in enumerate(prevInserts):
|
| 175 |
+
if prevIop.index == iop.index and type(prevIop) is TokenStreamRewriter.InsertBeforeOp:
|
| 176 |
+
iop.text += prevIop.text
|
| 177 |
+
rewrites[prev_index] = None
|
| 178 |
+
elif prevIop.index == iop.index and type(prevIop) is TokenStreamRewriter.InsertAfterOp:
|
| 179 |
+
iop.text = prevIop.text + iop.text
|
| 180 |
+
rewrites[prev_index] = None
|
| 181 |
+
# look for replaces where iop.index is in range; error
|
| 182 |
+
prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]
|
| 183 |
+
for rop in prevReplaces:
|
| 184 |
+
if iop.index == rop.index:
|
| 185 |
+
rop.text = iop.text + rop.text
|
| 186 |
+
rewrites[i] = None
|
| 187 |
+
continue
|
| 188 |
+
if all((iop.index >= rop.index, iop.index <= rop.last_index)):
|
| 189 |
+
raise ValueError("insert op {} within boundaries of previous {}".format(iop, rop))
|
| 190 |
+
|
| 191 |
+
reduced = {}
|
| 192 |
+
for i, op in enumerate(rewrites):
|
| 193 |
+
if op is None: continue
|
| 194 |
+
if reduced.get(op.index): raise ValueError('should be only one op per index')
|
| 195 |
+
reduced[op.index] = op
|
| 196 |
+
|
| 197 |
+
return reduced
|
| 198 |
+
|
| 199 |
+
class RewriteOperation(object):
|
| 200 |
+
__slots__ = ('tokens', 'index', 'text', 'instructionIndex')
|
| 201 |
+
|
| 202 |
+
def __init__(self, tokens, index, text=""):
|
| 203 |
+
"""
|
| 204 |
+
:type tokens: CommonTokenStream
|
| 205 |
+
:param tokens:
|
| 206 |
+
:param index:
|
| 207 |
+
:param text:
|
| 208 |
+
:return:
|
| 209 |
+
"""
|
| 210 |
+
self.tokens = tokens
|
| 211 |
+
self.index = index
|
| 212 |
+
self.text = text
|
| 213 |
+
self.instructionIndex = 0
|
| 214 |
+
|
| 215 |
+
def execute(self, buf):
|
| 216 |
+
"""
|
| 217 |
+
:type buf: StringIO.StringIO
|
| 218 |
+
:param buf:
|
| 219 |
+
:return:
|
| 220 |
+
"""
|
| 221 |
+
return self.index
|
| 222 |
+
|
| 223 |
+
def __str__(self):
|
| 224 |
+
return '<{}@{}:"{}">'.format(self.__class__.__name__, self.tokens.get(self.index), self.text)
|
| 225 |
+
|
| 226 |
+
class InsertBeforeOp(RewriteOperation):
|
| 227 |
+
|
| 228 |
+
def __init__(self, tokens, index, text=""):
|
| 229 |
+
super(TokenStreamRewriter.InsertBeforeOp, self).__init__(tokens, index, text)
|
| 230 |
+
|
| 231 |
+
def execute(self, buf):
|
| 232 |
+
buf.write(self.text)
|
| 233 |
+
if self.tokens.get(self.index).type != Token.EOF:
|
| 234 |
+
buf.write(self.tokens.get(self.index).text)
|
| 235 |
+
return self.index + 1
|
| 236 |
+
|
| 237 |
+
class InsertAfterOp(InsertBeforeOp):
|
| 238 |
+
pass
|
| 239 |
+
|
| 240 |
+
class ReplaceOp(RewriteOperation):
|
| 241 |
+
__slots__ = 'last_index'
|
| 242 |
+
|
| 243 |
+
def __init__(self, from_idx, to_idx, tokens, text):
|
| 244 |
+
super(TokenStreamRewriter.ReplaceOp, self).__init__(tokens, from_idx, text)
|
| 245 |
+
self.last_index = to_idx
|
| 246 |
+
|
| 247 |
+
def execute(self, buf):
|
| 248 |
+
if self.text:
|
| 249 |
+
buf.write(self.text)
|
| 250 |
+
return self.last_index + 1
|
| 251 |
+
|
| 252 |
+
def __str__(self):
|
| 253 |
+
if self.text:
|
| 254 |
+
return '<ReplaceOp@{}..{}:"{}">'.format(self.tokens.get(self.index), self.tokens.get(self.last_index),
|
| 255 |
+
self.text)
|
cameras/deps/antlr4/Utils.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#
|
| 5 |
+
|
| 6 |
+
from io import StringIO
|
| 7 |
+
|
| 8 |
+
def str_list(val):
|
| 9 |
+
with StringIO() as buf:
|
| 10 |
+
buf.write('[')
|
| 11 |
+
first = True
|
| 12 |
+
for item in val:
|
| 13 |
+
if not first:
|
| 14 |
+
buf.write(', ')
|
| 15 |
+
buf.write(str(item))
|
| 16 |
+
first = False
|
| 17 |
+
buf.write(']')
|
| 18 |
+
return buf.getvalue()
|
| 19 |
+
|
| 20 |
+
def escapeWhitespace(s:str, escapeSpaces:bool):
|
| 21 |
+
with StringIO() as buf:
|
| 22 |
+
for c in s:
|
| 23 |
+
if c==' ' and escapeSpaces:
|
| 24 |
+
buf.write('\u00B7')
|
| 25 |
+
elif c=='\t':
|
| 26 |
+
buf.write("\\t")
|
| 27 |
+
elif c=='\n':
|
| 28 |
+
buf.write("\\n")
|
| 29 |
+
elif c=='\r':
|
| 30 |
+
buf.write("\\r")
|
| 31 |
+
else:
|
| 32 |
+
buf.write(c)
|
| 33 |
+
return buf.getvalue()
|
cameras/deps/antlr4/__init__.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from antlr4.Token import Token
|
| 2 |
+
from antlr4.InputStream import InputStream
|
| 3 |
+
from antlr4.FileStream import FileStream
|
| 4 |
+
from antlr4.StdinStream import StdinStream
|
| 5 |
+
from antlr4.BufferedTokenStream import TokenStream
|
| 6 |
+
from antlr4.CommonTokenStream import CommonTokenStream
|
| 7 |
+
from antlr4.Lexer import Lexer
|
| 8 |
+
from antlr4.Parser import Parser
|
| 9 |
+
from antlr4.dfa.DFA import DFA
|
| 10 |
+
from antlr4.atn.ATN import ATN
|
| 11 |
+
from antlr4.atn.ATNDeserializer import ATNDeserializer
|
| 12 |
+
from antlr4.atn.LexerATNSimulator import LexerATNSimulator
|
| 13 |
+
from antlr4.atn.ParserATNSimulator import ParserATNSimulator
|
| 14 |
+
from antlr4.atn.PredictionMode import PredictionMode
|
| 15 |
+
from antlr4.PredictionContext import PredictionContextCache
|
| 16 |
+
from antlr4.ParserRuleContext import RuleContext, ParserRuleContext
|
| 17 |
+
from antlr4.tree.Tree import ParseTreeListener, ParseTreeVisitor, ParseTreeWalker, TerminalNode, ErrorNode, RuleNode
|
| 18 |
+
from antlr4.error.Errors import RecognitionException, IllegalStateException, NoViableAltException
|
| 19 |
+
from antlr4.error.ErrorStrategy import BailErrorStrategy
|
| 20 |
+
from antlr4.error.DiagnosticErrorListener import DiagnosticErrorListener
|
| 21 |
+
from antlr4.Utils import str_list
|
cameras/deps/antlr4/atn/ATN.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#/
|
| 5 |
+
from antlr4.IntervalSet import IntervalSet
|
| 6 |
+
|
| 7 |
+
from antlr4.RuleContext import RuleContext
|
| 8 |
+
|
| 9 |
+
from antlr4.Token import Token
|
| 10 |
+
from antlr4.atn.ATNType import ATNType
|
| 11 |
+
from antlr4.atn.ATNState import ATNState, DecisionState
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class ATN(object):
|
| 15 |
+
__slots__ = (
|
| 16 |
+
'grammarType', 'maxTokenType', 'states', 'decisionToState',
|
| 17 |
+
'ruleToStartState', 'ruleToStopState', 'modeNameToStartState',
|
| 18 |
+
'ruleToTokenType', 'lexerActions', 'modeToStartState'
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
INVALID_ALT_NUMBER = 0
|
| 22 |
+
|
| 23 |
+
# Used for runtime deserialization of ATNs from strings#/
|
| 24 |
+
def __init__(self, grammarType:ATNType , maxTokenType:int ):
|
| 25 |
+
# The type of the ATN.
|
| 26 |
+
self.grammarType = grammarType
|
| 27 |
+
# The maximum value for any symbol recognized by a transition in the ATN.
|
| 28 |
+
self.maxTokenType = maxTokenType
|
| 29 |
+
self.states = []
|
| 30 |
+
# Each subrule/rule is a decision point and we must track them so we
|
| 31 |
+
# can go back later and build DFA predictors for them. This includes
|
| 32 |
+
# all the rules, subrules, optional blocks, ()+, ()* etc...
|
| 33 |
+
self.decisionToState = []
|
| 34 |
+
# Maps from rule index to starting state number.
|
| 35 |
+
self.ruleToStartState = []
|
| 36 |
+
# Maps from rule index to stop state number.
|
| 37 |
+
self.ruleToStopState = None
|
| 38 |
+
self.modeNameToStartState = dict()
|
| 39 |
+
# For lexer ATNs, this maps the rule index to the resulting token type.
|
| 40 |
+
# For parser ATNs, this maps the rule index to the generated bypass token
|
| 41 |
+
# type if the
|
| 42 |
+
# {@link ATNDeserializationOptions#isGenerateRuleBypassTransitions}
|
| 43 |
+
# deserialization option was specified; otherwise, this is {@code null}.
|
| 44 |
+
self.ruleToTokenType = None
|
| 45 |
+
# For lexer ATNs, this is an array of {@link LexerAction} objects which may
|
| 46 |
+
# be referenced by action transitions in the ATN.
|
| 47 |
+
self.lexerActions = None
|
| 48 |
+
self.modeToStartState = []
|
| 49 |
+
|
| 50 |
+
# Compute the set of valid tokens that can occur starting in state {@code s}.
|
| 51 |
+
# If {@code ctx} is null, the set of tokens will not include what can follow
|
| 52 |
+
# the rule surrounding {@code s}. In other words, the set will be
|
| 53 |
+
# restricted to tokens reachable staying within {@code s}'s rule.
|
| 54 |
+
def nextTokensInContext(self, s:ATNState, ctx:RuleContext):
|
| 55 |
+
from antlr4.LL1Analyzer import LL1Analyzer
|
| 56 |
+
anal = LL1Analyzer(self)
|
| 57 |
+
return anal.LOOK(s, ctx=ctx)
|
| 58 |
+
|
| 59 |
+
# Compute the set of valid tokens that can occur starting in {@code s} and
|
| 60 |
+
# staying in same rule. {@link Token#EPSILON} is in set if we reach end of
|
| 61 |
+
# rule.
|
| 62 |
+
def nextTokensNoContext(self, s:ATNState):
|
| 63 |
+
if s.nextTokenWithinRule is not None:
|
| 64 |
+
return s.nextTokenWithinRule
|
| 65 |
+
s.nextTokenWithinRule = self.nextTokensInContext(s, None)
|
| 66 |
+
s.nextTokenWithinRule.readonly = True
|
| 67 |
+
return s.nextTokenWithinRule
|
| 68 |
+
|
| 69 |
+
def nextTokens(self, s:ATNState, ctx:RuleContext = None):
|
| 70 |
+
if ctx==None:
|
| 71 |
+
return self.nextTokensNoContext(s)
|
| 72 |
+
else:
|
| 73 |
+
return self.nextTokensInContext(s, ctx)
|
| 74 |
+
|
| 75 |
+
def addState(self, state:ATNState):
|
| 76 |
+
if state is not None:
|
| 77 |
+
state.atn = self
|
| 78 |
+
state.stateNumber = len(self.states)
|
| 79 |
+
self.states.append(state)
|
| 80 |
+
|
| 81 |
+
def removeState(self, state:ATNState):
|
| 82 |
+
self.states[state.stateNumber] = None # just free mem, don't shift states in list
|
| 83 |
+
|
| 84 |
+
def defineDecisionState(self, s:DecisionState):
|
| 85 |
+
self.decisionToState.append(s)
|
| 86 |
+
s.decision = len(self.decisionToState)-1
|
| 87 |
+
return s.decision
|
| 88 |
+
|
| 89 |
+
def getDecisionState(self, decision:int):
|
| 90 |
+
if len(self.decisionToState)==0:
|
| 91 |
+
return None
|
| 92 |
+
else:
|
| 93 |
+
return self.decisionToState[decision]
|
| 94 |
+
|
| 95 |
+
# Computes the set of input symbols which could follow ATN state number
|
| 96 |
+
# {@code stateNumber} in the specified full {@code context}. This method
|
| 97 |
+
# considers the complete parser context, but does not evaluate semantic
|
| 98 |
+
# predicates (i.e. all predicates encountered during the calculation are
|
| 99 |
+
# assumed true). If a path in the ATN exists from the starting state to the
|
| 100 |
+
# {@link RuleStopState} of the outermost context without matching any
|
| 101 |
+
# symbols, {@link Token#EOF} is added to the returned set.
|
| 102 |
+
#
|
| 103 |
+
# <p>If {@code context} is {@code null}, it is treated as
|
| 104 |
+
# {@link ParserRuleContext#EMPTY}.</p>
|
| 105 |
+
#
|
| 106 |
+
# @param stateNumber the ATN state number
|
| 107 |
+
# @param context the full parse context
|
| 108 |
+
# @return The set of potentially valid input symbols which could follow the
|
| 109 |
+
# specified state in the specified context.
|
| 110 |
+
# @throws IllegalArgumentException if the ATN does not contain a state with
|
| 111 |
+
# number {@code stateNumber}
|
| 112 |
+
#/
|
| 113 |
+
def getExpectedTokens(self, stateNumber:int, ctx:RuleContext ):
|
| 114 |
+
if stateNumber < 0 or stateNumber >= len(self.states):
|
| 115 |
+
raise Exception("Invalid state number.")
|
| 116 |
+
s = self.states[stateNumber]
|
| 117 |
+
following = self.nextTokens(s)
|
| 118 |
+
if Token.EPSILON not in following:
|
| 119 |
+
return following
|
| 120 |
+
expected = IntervalSet()
|
| 121 |
+
expected.addSet(following)
|
| 122 |
+
expected.removeOne(Token.EPSILON)
|
| 123 |
+
while (ctx != None and ctx.invokingState >= 0 and Token.EPSILON in following):
|
| 124 |
+
invokingState = self.states[ctx.invokingState]
|
| 125 |
+
rt = invokingState.transitions[0]
|
| 126 |
+
following = self.nextTokens(rt.followState)
|
| 127 |
+
expected.addSet(following)
|
| 128 |
+
expected.removeOne(Token.EPSILON)
|
| 129 |
+
ctx = ctx.parentCtx
|
| 130 |
+
if Token.EPSILON in following:
|
| 131 |
+
expected.addOne(Token.EOF)
|
| 132 |
+
return expected
|
cameras/deps/antlr4/atn/ATNConfig.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
# A tuple: (ATN state, predicted alt, syntactic, semantic context).
|
| 8 |
+
# The syntactic context is a graph-structured stack node whose
|
| 9 |
+
# path(s) to the root is the rule invocation(s)
|
| 10 |
+
# chain used to arrive at the state. The semantic context is
|
| 11 |
+
# the tree of semantic predicates encountered before reaching
|
| 12 |
+
# an ATN state.
|
| 13 |
+
#/
|
| 14 |
+
from io import StringIO
|
| 15 |
+
from antlr4.PredictionContext import PredictionContext
|
| 16 |
+
from antlr4.atn.ATNState import ATNState, DecisionState
|
| 17 |
+
from antlr4.atn.LexerActionExecutor import LexerActionExecutor
|
| 18 |
+
from antlr4.atn.SemanticContext import SemanticContext
|
| 19 |
+
|
| 20 |
+
# need a forward declaration
|
| 21 |
+
ATNConfig = None
|
| 22 |
+
|
| 23 |
+
class ATNConfig(object):
|
| 24 |
+
__slots__ = (
|
| 25 |
+
'state', 'alt', 'context', 'semanticContext', 'reachesIntoOuterContext',
|
| 26 |
+
'precedenceFilterSuppressed'
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
def __init__(self, state:ATNState=None, alt:int=None, context:PredictionContext=None, semantic:SemanticContext=None, config:ATNConfig=None):
|
| 30 |
+
if config is not None:
|
| 31 |
+
if state is None:
|
| 32 |
+
state = config.state
|
| 33 |
+
if alt is None:
|
| 34 |
+
alt = config.alt
|
| 35 |
+
if context is None:
|
| 36 |
+
context = config.context
|
| 37 |
+
if semantic is None:
|
| 38 |
+
semantic = config.semanticContext
|
| 39 |
+
if semantic is None:
|
| 40 |
+
semantic = SemanticContext.NONE
|
| 41 |
+
# The ATN state associated with this configuration#/
|
| 42 |
+
self.state = state
|
| 43 |
+
# What alt (or lexer rule) is predicted by this configuration#/
|
| 44 |
+
self.alt = alt
|
| 45 |
+
# The stack of invoking states leading to the rule/states associated
|
| 46 |
+
# with this config. We track only those contexts pushed during
|
| 47 |
+
# execution of the ATN simulator.
|
| 48 |
+
self.context = context
|
| 49 |
+
self.semanticContext = semantic
|
| 50 |
+
# We cannot execute predicates dependent upon local context unless
|
| 51 |
+
# we know for sure we are in the correct context. Because there is
|
| 52 |
+
# no way to do this efficiently, we simply cannot evaluate
|
| 53 |
+
# dependent predicates unless we are in the rule that initially
|
| 54 |
+
# invokes the ATN simulator.
|
| 55 |
+
#
|
| 56 |
+
# closure() tracks the depth of how far we dip into the
|
| 57 |
+
# outer context: depth > 0. Note that it may not be totally
|
| 58 |
+
# accurate depth since I don't ever decrement. TODO: make it a boolean then
|
| 59 |
+
self.reachesIntoOuterContext = 0 if config is None else config.reachesIntoOuterContext
|
| 60 |
+
self.precedenceFilterSuppressed = False if config is None else config.precedenceFilterSuppressed
|
| 61 |
+
|
| 62 |
+
# An ATN configuration is equal to another if both have
|
| 63 |
+
# the same state, they predict the same alternative, and
|
| 64 |
+
# syntactic/semantic contexts are the same.
|
| 65 |
+
#/
|
| 66 |
+
def __eq__(self, other):
|
| 67 |
+
if self is other:
|
| 68 |
+
return True
|
| 69 |
+
elif not isinstance(other, ATNConfig):
|
| 70 |
+
return False
|
| 71 |
+
else:
|
| 72 |
+
return self.state.stateNumber==other.state.stateNumber \
|
| 73 |
+
and self.alt==other.alt \
|
| 74 |
+
and ((self.context is other.context) or (self.context==other.context)) \
|
| 75 |
+
and self.semanticContext==other.semanticContext \
|
| 76 |
+
and self.precedenceFilterSuppressed==other.precedenceFilterSuppressed
|
| 77 |
+
|
| 78 |
+
def __hash__(self):
|
| 79 |
+
return hash((self.state.stateNumber, self.alt, self.context, self.semanticContext))
|
| 80 |
+
|
| 81 |
+
def hashCodeForConfigSet(self):
|
| 82 |
+
return hash((self.state.stateNumber, self.alt, hash(self.semanticContext)))
|
| 83 |
+
|
| 84 |
+
def equalsForConfigSet(self, other):
|
| 85 |
+
if self is other:
|
| 86 |
+
return True
|
| 87 |
+
elif not isinstance(other, ATNConfig):
|
| 88 |
+
return False
|
| 89 |
+
else:
|
| 90 |
+
return self.state.stateNumber==other.state.stateNumber \
|
| 91 |
+
and self.alt==other.alt \
|
| 92 |
+
and self.semanticContext==other.semanticContext
|
| 93 |
+
|
| 94 |
+
def __str__(self):
|
| 95 |
+
with StringIO() as buf:
|
| 96 |
+
buf.write('(')
|
| 97 |
+
buf.write(str(self.state))
|
| 98 |
+
buf.write(",")
|
| 99 |
+
buf.write(str(self.alt))
|
| 100 |
+
if self.context is not None:
|
| 101 |
+
buf.write(",[")
|
| 102 |
+
buf.write(str(self.context))
|
| 103 |
+
buf.write("]")
|
| 104 |
+
if self.semanticContext is not None and self.semanticContext is not SemanticContext.NONE:
|
| 105 |
+
buf.write(",")
|
| 106 |
+
buf.write(str(self.semanticContext))
|
| 107 |
+
if self.reachesIntoOuterContext>0:
|
| 108 |
+
buf.write(",up=")
|
| 109 |
+
buf.write(str(self.reachesIntoOuterContext))
|
| 110 |
+
buf.write(')')
|
| 111 |
+
return buf.getvalue()
|
| 112 |
+
|
| 113 |
+
# need a forward declaration
|
| 114 |
+
LexerATNConfig = None
|
| 115 |
+
|
| 116 |
+
class LexerATNConfig(ATNConfig):
|
| 117 |
+
__slots__ = ('lexerActionExecutor', 'passedThroughNonGreedyDecision')
|
| 118 |
+
|
| 119 |
+
def __init__(self, state:ATNState, alt:int=None, context:PredictionContext=None, semantic:SemanticContext=SemanticContext.NONE,
|
| 120 |
+
lexerActionExecutor:LexerActionExecutor=None, config:LexerATNConfig=None):
|
| 121 |
+
super().__init__(state=state, alt=alt, context=context, semantic=semantic, config=config)
|
| 122 |
+
if config is not None:
|
| 123 |
+
if lexerActionExecutor is None:
|
| 124 |
+
lexerActionExecutor = config.lexerActionExecutor
|
| 125 |
+
# This is the backing field for {@link #getLexerActionExecutor}.
|
| 126 |
+
self.lexerActionExecutor = lexerActionExecutor
|
| 127 |
+
self.passedThroughNonGreedyDecision = False if config is None else self.checkNonGreedyDecision(config, state)
|
| 128 |
+
|
| 129 |
+
def __hash__(self):
|
| 130 |
+
return hash((self.state.stateNumber, self.alt, self.context,
|
| 131 |
+
self.semanticContext, self.passedThroughNonGreedyDecision,
|
| 132 |
+
self.lexerActionExecutor))
|
| 133 |
+
|
| 134 |
+
def __eq__(self, other):
|
| 135 |
+
if self is other:
|
| 136 |
+
return True
|
| 137 |
+
elif not isinstance(other, LexerATNConfig):
|
| 138 |
+
return False
|
| 139 |
+
if self.passedThroughNonGreedyDecision != other.passedThroughNonGreedyDecision:
|
| 140 |
+
return False
|
| 141 |
+
if not(self.lexerActionExecutor == other.lexerActionExecutor):
|
| 142 |
+
return False
|
| 143 |
+
return super().__eq__(other)
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def hashCodeForConfigSet(self):
|
| 148 |
+
return hash(self)
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def equalsForConfigSet(self, other):
|
| 153 |
+
return self==other
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def checkNonGreedyDecision(self, source:LexerATNConfig, target:ATNState):
|
| 158 |
+
return source.passedThroughNonGreedyDecision \
|
| 159 |
+
or isinstance(target, DecisionState) and target.nonGreedy
|
cameras/deps/antlr4/atn/ATNConfigSet.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
|
| 6 |
+
#
|
| 7 |
+
# Specialized {@link Set}{@code <}{@link ATNConfig}{@code >} that can track
|
| 8 |
+
# info about the set, with support for combining similar configurations using a
|
| 9 |
+
# graph-structured stack.
|
| 10 |
+
#/
|
| 11 |
+
from io import StringIO
|
| 12 |
+
from functools import reduce
|
| 13 |
+
from antlr4.PredictionContext import PredictionContext, merge
|
| 14 |
+
from antlr4.Utils import str_list
|
| 15 |
+
from antlr4.atn.ATN import ATN
|
| 16 |
+
from antlr4.atn.ATNConfig import ATNConfig
|
| 17 |
+
from antlr4.atn.SemanticContext import SemanticContext
|
| 18 |
+
from antlr4.error.Errors import UnsupportedOperationException, IllegalStateException
|
| 19 |
+
|
| 20 |
+
ATNSimulator = None
|
| 21 |
+
|
| 22 |
+
class ATNConfigSet(object):
|
| 23 |
+
__slots__ = (
|
| 24 |
+
'configLookup', 'fullCtx', 'readonly', 'configs', 'uniqueAlt',
|
| 25 |
+
'conflictingAlts', 'hasSemanticContext', 'dipsIntoOuterContext',
|
| 26 |
+
'cachedHashCode'
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
#
|
| 30 |
+
# The reason that we need this is because we don't want the hash map to use
|
| 31 |
+
# the standard hash code and equals. We need all configurations with the same
|
| 32 |
+
# {@code (s,i,_,semctx)} to be equal. Unfortunately, this key effectively doubles
|
| 33 |
+
# the number of objects associated with ATNConfigs. The other solution is to
|
| 34 |
+
# use a hash table that lets us specify the equals/hashcode operation.
|
| 35 |
+
|
| 36 |
+
def __init__(self, fullCtx:bool=True):
|
| 37 |
+
# All configs but hashed by (s, i, _, pi) not including context. Wiped out
|
| 38 |
+
# when we go readonly as this set becomes a DFA state.
|
| 39 |
+
self.configLookup = dict()
|
| 40 |
+
# Indicates that this configuration set is part of a full context
|
| 41 |
+
# LL prediction. It will be used to determine how to merge $. With SLL
|
| 42 |
+
# it's a wildcard whereas it is not for LL context merge.
|
| 43 |
+
self.fullCtx = fullCtx
|
| 44 |
+
# Indicates that the set of configurations is read-only. Do not
|
| 45 |
+
# allow any code to manipulate the set; DFA states will point at
|
| 46 |
+
# the sets and they must not change. This does not protect the other
|
| 47 |
+
# fields; in particular, conflictingAlts is set after
|
| 48 |
+
# we've made this readonly.
|
| 49 |
+
self.readonly = False
|
| 50 |
+
# Track the elements as they are added to the set; supports get(i)#/
|
| 51 |
+
self.configs = []
|
| 52 |
+
|
| 53 |
+
# TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
|
| 54 |
+
# TODO: can we track conflicts as they are added to save scanning configs later?
|
| 55 |
+
self.uniqueAlt = 0
|
| 56 |
+
self.conflictingAlts = None
|
| 57 |
+
|
| 58 |
+
# Used in parser and lexer. In lexer, it indicates we hit a pred
|
| 59 |
+
# while computing a closure operation. Don't make a DFA state from this.
|
| 60 |
+
self.hasSemanticContext = False
|
| 61 |
+
self.dipsIntoOuterContext = False
|
| 62 |
+
|
| 63 |
+
self.cachedHashCode = -1
|
| 64 |
+
|
| 65 |
+
def __iter__(self):
|
| 66 |
+
return self.configs.__iter__()
|
| 67 |
+
|
| 68 |
+
# Adding a new config means merging contexts with existing configs for
|
| 69 |
+
# {@code (s, i, pi, _)}, where {@code s} is the
|
| 70 |
+
# {@link ATNConfig#state}, {@code i} is the {@link ATNConfig#alt}, and
|
| 71 |
+
# {@code pi} is the {@link ATNConfig#semanticContext}. We use
|
| 72 |
+
# {@code (s,i,pi)} as key.
|
| 73 |
+
#
|
| 74 |
+
# <p>This method updates {@link #dipsIntoOuterContext} and
|
| 75 |
+
# {@link #hasSemanticContext} when necessary.</p>
|
| 76 |
+
#/
|
| 77 |
+
def add(self, config:ATNConfig, mergeCache=None):
|
| 78 |
+
if self.readonly:
|
| 79 |
+
raise Exception("This set is readonly")
|
| 80 |
+
if config.semanticContext is not SemanticContext.NONE:
|
| 81 |
+
self.hasSemanticContext = True
|
| 82 |
+
if config.reachesIntoOuterContext > 0:
|
| 83 |
+
self.dipsIntoOuterContext = True
|
| 84 |
+
existing = self.getOrAdd(config)
|
| 85 |
+
if existing is config:
|
| 86 |
+
self.cachedHashCode = -1
|
| 87 |
+
self.configs.append(config) # track order here
|
| 88 |
+
return True
|
| 89 |
+
# a previous (s,i,pi,_), merge with it and save result
|
| 90 |
+
rootIsWildcard = not self.fullCtx
|
| 91 |
+
merged = merge(existing.context, config.context, rootIsWildcard, mergeCache)
|
| 92 |
+
# no need to check for existing.context, config.context in cache
|
| 93 |
+
# since only way to create new graphs is "call rule" and here.
|
| 94 |
+
# We cache at both places.
|
| 95 |
+
existing.reachesIntoOuterContext = max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext)
|
| 96 |
+
# make sure to preserve the precedence filter suppression during the merge
|
| 97 |
+
if config.precedenceFilterSuppressed:
|
| 98 |
+
existing.precedenceFilterSuppressed = True
|
| 99 |
+
existing.context = merged # replace context; no need to alt mapping
|
| 100 |
+
return True
|
| 101 |
+
|
| 102 |
+
def getOrAdd(self, config:ATNConfig):
|
| 103 |
+
h = config.hashCodeForConfigSet()
|
| 104 |
+
l = self.configLookup.get(h, None)
|
| 105 |
+
if l is not None:
|
| 106 |
+
r = next((cfg for cfg in l if config.equalsForConfigSet(cfg)), None)
|
| 107 |
+
if r is not None:
|
| 108 |
+
return r
|
| 109 |
+
if l is None:
|
| 110 |
+
l = [config]
|
| 111 |
+
self.configLookup[h] = l
|
| 112 |
+
else:
|
| 113 |
+
l.append(config)
|
| 114 |
+
return config
|
| 115 |
+
|
| 116 |
+
def getStates(self):
|
| 117 |
+
return set(c.state for c in self.configs)
|
| 118 |
+
|
| 119 |
+
def getPredicates(self):
|
| 120 |
+
return list(cfg.semanticContext for cfg in self.configs if cfg.semanticContext!=SemanticContext.NONE)
|
| 121 |
+
|
| 122 |
+
def get(self, i:int):
|
| 123 |
+
return self.configs[i]
|
| 124 |
+
|
| 125 |
+
def optimizeConfigs(self, interpreter:ATNSimulator):
|
| 126 |
+
if self.readonly:
|
| 127 |
+
raise IllegalStateException("This set is readonly")
|
| 128 |
+
if len(self.configs)==0:
|
| 129 |
+
return
|
| 130 |
+
for config in self.configs:
|
| 131 |
+
config.context = interpreter.getCachedContext(config.context)
|
| 132 |
+
|
| 133 |
+
def addAll(self, coll:list):
|
| 134 |
+
for c in coll:
|
| 135 |
+
self.add(c)
|
| 136 |
+
return False
|
| 137 |
+
|
| 138 |
+
def __eq__(self, other):
|
| 139 |
+
if self is other:
|
| 140 |
+
return True
|
| 141 |
+
elif not isinstance(other, ATNConfigSet):
|
| 142 |
+
return False
|
| 143 |
+
|
| 144 |
+
same = self.configs is not None and \
|
| 145 |
+
self.configs==other.configs and \
|
| 146 |
+
self.fullCtx == other.fullCtx and \
|
| 147 |
+
self.uniqueAlt == other.uniqueAlt and \
|
| 148 |
+
self.conflictingAlts == other.conflictingAlts and \
|
| 149 |
+
self.hasSemanticContext == other.hasSemanticContext and \
|
| 150 |
+
self.dipsIntoOuterContext == other.dipsIntoOuterContext
|
| 151 |
+
|
| 152 |
+
return same
|
| 153 |
+
|
| 154 |
+
def __hash__(self):
|
| 155 |
+
if self.readonly:
|
| 156 |
+
if self.cachedHashCode == -1:
|
| 157 |
+
self.cachedHashCode = self.hashConfigs()
|
| 158 |
+
return self.cachedHashCode
|
| 159 |
+
return self.hashConfigs()
|
| 160 |
+
|
| 161 |
+
def hashConfigs(self):
|
| 162 |
+
return reduce(lambda h, cfg: hash((h, cfg)), self.configs, 0)
|
| 163 |
+
|
| 164 |
+
def __len__(self):
|
| 165 |
+
return len(self.configs)
|
| 166 |
+
|
| 167 |
+
def isEmpty(self):
|
| 168 |
+
return len(self.configs)==0
|
| 169 |
+
|
| 170 |
+
def __contains__(self, config):
|
| 171 |
+
if self.configLookup is None:
|
| 172 |
+
raise UnsupportedOperationException("This method is not implemented for readonly sets.")
|
| 173 |
+
h = config.hashCodeForConfigSet()
|
| 174 |
+
l = self.configLookup.get(h, None)
|
| 175 |
+
if l is not None:
|
| 176 |
+
for c in l:
|
| 177 |
+
if config.equalsForConfigSet(c):
|
| 178 |
+
return True
|
| 179 |
+
return False
|
| 180 |
+
|
| 181 |
+
def clear(self):
|
| 182 |
+
if self.readonly:
|
| 183 |
+
raise IllegalStateException("This set is readonly")
|
| 184 |
+
self.configs.clear()
|
| 185 |
+
self.cachedHashCode = -1
|
| 186 |
+
self.configLookup.clear()
|
| 187 |
+
|
| 188 |
+
def setReadonly(self, readonly:bool):
|
| 189 |
+
self.readonly = readonly
|
| 190 |
+
self.configLookup = None # can't mod, no need for lookup cache
|
| 191 |
+
|
| 192 |
+
def __str__(self):
|
| 193 |
+
with StringIO() as buf:
|
| 194 |
+
buf.write(str_list(self.configs))
|
| 195 |
+
if self.hasSemanticContext:
|
| 196 |
+
buf.write(",hasSemanticContext=")
|
| 197 |
+
buf.write(str(self.hasSemanticContext))
|
| 198 |
+
if self.uniqueAlt!=ATN.INVALID_ALT_NUMBER:
|
| 199 |
+
buf.write(",uniqueAlt=")
|
| 200 |
+
buf.write(str(self.uniqueAlt))
|
| 201 |
+
if self.conflictingAlts is not None:
|
| 202 |
+
buf.write(",conflictingAlts=")
|
| 203 |
+
buf.write(str(self.conflictingAlts))
|
| 204 |
+
if self.dipsIntoOuterContext:
|
| 205 |
+
buf.write(",dipsIntoOuterContext")
|
| 206 |
+
return buf.getvalue()
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
class OrderedATNConfigSet(ATNConfigSet):
|
| 210 |
+
|
| 211 |
+
def __init__(self):
|
| 212 |
+
super().__init__()
|
cameras/deps/antlr4/atn/ATNDeserializationOptions.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
|
| 5 |
+
# need a forward declaration
|
| 6 |
+
ATNDeserializationOptions = None
|
| 7 |
+
|
| 8 |
+
class ATNDeserializationOptions(object):
|
| 9 |
+
__slots__ = ('readonly', 'verifyATN', 'generateRuleBypassTransitions')
|
| 10 |
+
|
| 11 |
+
defaultOptions = None
|
| 12 |
+
|
| 13 |
+
def __init__(self, copyFrom:ATNDeserializationOptions = None):
|
| 14 |
+
self.readonly = False
|
| 15 |
+
self.verifyATN = True if copyFrom is None else copyFrom.verifyATN
|
| 16 |
+
self.generateRuleBypassTransitions = False if copyFrom is None else copyFrom.generateRuleBypassTransitions
|
| 17 |
+
|
| 18 |
+
def __setattr__(self, key, value):
|
| 19 |
+
if key!="readonly" and self.readonly:
|
| 20 |
+
raise Exception("The object is read only.")
|
| 21 |
+
super(type(self), self).__setattr__(key,value)
|
| 22 |
+
|
| 23 |
+
ATNDeserializationOptions.defaultOptions = ATNDeserializationOptions()
|
| 24 |
+
ATNDeserializationOptions.defaultOptions.readonly = True
|
cameras/deps/antlr4/atn/ATNDeserializer.py
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#/
|
| 5 |
+
from uuid import UUID
|
| 6 |
+
from io import StringIO
|
| 7 |
+
from typing import Callable
|
| 8 |
+
from antlr4.Token import Token
|
| 9 |
+
from antlr4.atn.ATN import ATN
|
| 10 |
+
from antlr4.atn.ATNType import ATNType
|
| 11 |
+
from antlr4.atn.ATNState import *
|
| 12 |
+
from antlr4.atn.Transition import *
|
| 13 |
+
from antlr4.atn.LexerAction import *
|
| 14 |
+
from antlr4.atn.ATNDeserializationOptions import ATNDeserializationOptions
|
| 15 |
+
|
| 16 |
+
# This is the earliest supported serialized UUID.
|
| 17 |
+
BASE_SERIALIZED_UUID = UUID("AADB8D7E-AEEF-4415-AD2B-8204D6CF042E")
|
| 18 |
+
|
| 19 |
+
# This UUID indicates the serialized ATN contains two sets of
|
| 20 |
+
# IntervalSets, where the second set's values are encoded as
|
| 21 |
+
# 32-bit integers to support the full Unicode SMP range up to U+10FFFF.
|
| 22 |
+
ADDED_UNICODE_SMP = UUID("59627784-3BE5-417A-B9EB-8131A7286089")
|
| 23 |
+
|
| 24 |
+
# This list contains all of the currently supported UUIDs, ordered by when
|
| 25 |
+
# the feature first appeared in this branch.
|
| 26 |
+
SUPPORTED_UUIDS = [ BASE_SERIALIZED_UUID, ADDED_UNICODE_SMP ]
|
| 27 |
+
|
| 28 |
+
SERIALIZED_VERSION = 3
|
| 29 |
+
|
| 30 |
+
# This is the current serialized UUID.
|
| 31 |
+
SERIALIZED_UUID = ADDED_UNICODE_SMP
|
| 32 |
+
|
| 33 |
+
class ATNDeserializer (object):
|
| 34 |
+
__slots__ = ('deserializationOptions', 'data', 'pos', 'uuid')
|
| 35 |
+
|
| 36 |
+
def __init__(self, options : ATNDeserializationOptions = None):
|
| 37 |
+
if options is None:
|
| 38 |
+
options = ATNDeserializationOptions.defaultOptions
|
| 39 |
+
self.deserializationOptions = options
|
| 40 |
+
|
| 41 |
+
# Determines if a particular serialized representation of an ATN supports
|
| 42 |
+
# a particular feature, identified by the {@link UUID} used for serializing
|
| 43 |
+
# the ATN at the time the feature was first introduced.
|
| 44 |
+
#
|
| 45 |
+
# @param feature The {@link UUID} marking the first time the feature was
|
| 46 |
+
# supported in the serialized ATN.
|
| 47 |
+
# @param actualUuid The {@link UUID} of the actual serialized ATN which is
|
| 48 |
+
# currently being deserialized.
|
| 49 |
+
# @return {@code true} if the {@code actualUuid} value represents a
|
| 50 |
+
# serialized ATN at or after the feature identified by {@code feature} was
|
| 51 |
+
# introduced; otherwise, {@code false}.
|
| 52 |
+
|
| 53 |
+
def isFeatureSupported(self, feature : UUID , actualUuid : UUID ):
|
| 54 |
+
idx1 = SUPPORTED_UUIDS.index(feature)
|
| 55 |
+
if idx1<0:
|
| 56 |
+
return False
|
| 57 |
+
idx2 = SUPPORTED_UUIDS.index(actualUuid)
|
| 58 |
+
return idx2 >= idx1
|
| 59 |
+
|
| 60 |
+
def deserialize(self, data : str):
|
| 61 |
+
self.reset(data)
|
| 62 |
+
self.checkVersion()
|
| 63 |
+
self.checkUUID()
|
| 64 |
+
atn = self.readATN()
|
| 65 |
+
self.readStates(atn)
|
| 66 |
+
self.readRules(atn)
|
| 67 |
+
self.readModes(atn)
|
| 68 |
+
sets = []
|
| 69 |
+
# First, read all sets with 16-bit Unicode code points <= U+FFFF.
|
| 70 |
+
self.readSets(atn, sets, self.readInt)
|
| 71 |
+
# Next, if the ATN was serialized with the Unicode SMP feature,
|
| 72 |
+
# deserialize sets with 32-bit arguments <= U+10FFFF.
|
| 73 |
+
if self.isFeatureSupported(ADDED_UNICODE_SMP, self.uuid):
|
| 74 |
+
self.readSets(atn, sets, self.readInt32)
|
| 75 |
+
self.readEdges(atn, sets)
|
| 76 |
+
self.readDecisions(atn)
|
| 77 |
+
self.readLexerActions(atn)
|
| 78 |
+
self.markPrecedenceDecisions(atn)
|
| 79 |
+
self.verifyATN(atn)
|
| 80 |
+
if self.deserializationOptions.generateRuleBypassTransitions \
|
| 81 |
+
and atn.grammarType == ATNType.PARSER:
|
| 82 |
+
self.generateRuleBypassTransitions(atn)
|
| 83 |
+
# re-verify after modification
|
| 84 |
+
self.verifyATN(atn)
|
| 85 |
+
return atn
|
| 86 |
+
|
| 87 |
+
def reset(self, data:str):
|
| 88 |
+
def adjust(c):
|
| 89 |
+
v = ord(c)
|
| 90 |
+
return v-2 if v>1 else v + 65533
|
| 91 |
+
temp = [ adjust(c) for c in data ]
|
| 92 |
+
# don't adjust the first value since that's the version number
|
| 93 |
+
temp[0] = ord(data[0])
|
| 94 |
+
self.data = temp
|
| 95 |
+
self.pos = 0
|
| 96 |
+
|
| 97 |
+
def checkVersion(self):
|
| 98 |
+
version = self.readInt()
|
| 99 |
+
if version != SERIALIZED_VERSION:
|
| 100 |
+
raise Exception("Could not deserialize ATN with version " + str(version) + " (expected " + str(SERIALIZED_VERSION) + ").")
|
| 101 |
+
|
| 102 |
+
def checkUUID(self):
|
| 103 |
+
uuid = self.readUUID()
|
| 104 |
+
if not uuid in SUPPORTED_UUIDS:
|
| 105 |
+
raise Exception("Could not deserialize ATN with UUID: " + str(uuid) + \
|
| 106 |
+
" (expected " + str(SERIALIZED_UUID) + " or a legacy UUID).", uuid, SERIALIZED_UUID)
|
| 107 |
+
self.uuid = uuid
|
| 108 |
+
|
| 109 |
+
def readATN(self):
|
| 110 |
+
idx = self.readInt()
|
| 111 |
+
grammarType = ATNType.fromOrdinal(idx)
|
| 112 |
+
maxTokenType = self.readInt()
|
| 113 |
+
return ATN(grammarType, maxTokenType)
|
| 114 |
+
|
| 115 |
+
def readStates(self, atn:ATN):
|
| 116 |
+
loopBackStateNumbers = []
|
| 117 |
+
endStateNumbers = []
|
| 118 |
+
nstates = self.readInt()
|
| 119 |
+
for i in range(0, nstates):
|
| 120 |
+
stype = self.readInt()
|
| 121 |
+
# ignore bad type of states
|
| 122 |
+
if stype==ATNState.INVALID_TYPE:
|
| 123 |
+
atn.addState(None)
|
| 124 |
+
continue
|
| 125 |
+
ruleIndex = self.readInt()
|
| 126 |
+
if ruleIndex == 0xFFFF:
|
| 127 |
+
ruleIndex = -1
|
| 128 |
+
|
| 129 |
+
s = self.stateFactory(stype, ruleIndex)
|
| 130 |
+
if stype == ATNState.LOOP_END: # special case
|
| 131 |
+
loopBackStateNumber = self.readInt()
|
| 132 |
+
loopBackStateNumbers.append((s, loopBackStateNumber))
|
| 133 |
+
elif isinstance(s, BlockStartState):
|
| 134 |
+
endStateNumber = self.readInt()
|
| 135 |
+
endStateNumbers.append((s, endStateNumber))
|
| 136 |
+
|
| 137 |
+
atn.addState(s)
|
| 138 |
+
|
| 139 |
+
# delay the assignment of loop back and end states until we know all the state instances have been initialized
|
| 140 |
+
for pair in loopBackStateNumbers:
|
| 141 |
+
pair[0].loopBackState = atn.states[pair[1]]
|
| 142 |
+
|
| 143 |
+
for pair in endStateNumbers:
|
| 144 |
+
pair[0].endState = atn.states[pair[1]]
|
| 145 |
+
|
| 146 |
+
numNonGreedyStates = self.readInt()
|
| 147 |
+
for i in range(0, numNonGreedyStates):
|
| 148 |
+
stateNumber = self.readInt()
|
| 149 |
+
atn.states[stateNumber].nonGreedy = True
|
| 150 |
+
|
| 151 |
+
numPrecedenceStates = self.readInt()
|
| 152 |
+
for i in range(0, numPrecedenceStates):
|
| 153 |
+
stateNumber = self.readInt()
|
| 154 |
+
atn.states[stateNumber].isPrecedenceRule = True
|
| 155 |
+
|
| 156 |
+
def readRules(self, atn:ATN):
|
| 157 |
+
nrules = self.readInt()
|
| 158 |
+
if atn.grammarType == ATNType.LEXER:
|
| 159 |
+
atn.ruleToTokenType = [0] * nrules
|
| 160 |
+
|
| 161 |
+
atn.ruleToStartState = [0] * nrules
|
| 162 |
+
for i in range(0, nrules):
|
| 163 |
+
s = self.readInt()
|
| 164 |
+
startState = atn.states[s]
|
| 165 |
+
atn.ruleToStartState[i] = startState
|
| 166 |
+
if atn.grammarType == ATNType.LEXER:
|
| 167 |
+
tokenType = self.readInt()
|
| 168 |
+
if tokenType == 0xFFFF:
|
| 169 |
+
tokenType = Token.EOF
|
| 170 |
+
|
| 171 |
+
atn.ruleToTokenType[i] = tokenType
|
| 172 |
+
|
| 173 |
+
atn.ruleToStopState = [0] * nrules
|
| 174 |
+
for state in atn.states:
|
| 175 |
+
if not isinstance(state, RuleStopState):
|
| 176 |
+
continue
|
| 177 |
+
atn.ruleToStopState[state.ruleIndex] = state
|
| 178 |
+
atn.ruleToStartState[state.ruleIndex].stopState = state
|
| 179 |
+
|
| 180 |
+
def readModes(self, atn:ATN):
|
| 181 |
+
nmodes = self.readInt()
|
| 182 |
+
for i in range(0, nmodes):
|
| 183 |
+
s = self.readInt()
|
| 184 |
+
atn.modeToStartState.append(atn.states[s])
|
| 185 |
+
|
| 186 |
+
def readSets(self, atn:ATN, sets:list, readUnicode:Callable[[], int]):
|
| 187 |
+
m = self.readInt()
|
| 188 |
+
for i in range(0, m):
|
| 189 |
+
iset = IntervalSet()
|
| 190 |
+
sets.append(iset)
|
| 191 |
+
n = self.readInt()
|
| 192 |
+
containsEof = self.readInt()
|
| 193 |
+
if containsEof!=0:
|
| 194 |
+
iset.addOne(-1)
|
| 195 |
+
for j in range(0, n):
|
| 196 |
+
i1 = readUnicode()
|
| 197 |
+
i2 = readUnicode()
|
| 198 |
+
iset.addRange(range(i1, i2 + 1)) # range upper limit is exclusive
|
| 199 |
+
|
| 200 |
+
def readEdges(self, atn:ATN, sets:list):
|
| 201 |
+
nedges = self.readInt()
|
| 202 |
+
for i in range(0, nedges):
|
| 203 |
+
src = self.readInt()
|
| 204 |
+
trg = self.readInt()
|
| 205 |
+
ttype = self.readInt()
|
| 206 |
+
arg1 = self.readInt()
|
| 207 |
+
arg2 = self.readInt()
|
| 208 |
+
arg3 = self.readInt()
|
| 209 |
+
trans = self.edgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets)
|
| 210 |
+
srcState = atn.states[src]
|
| 211 |
+
srcState.addTransition(trans)
|
| 212 |
+
|
| 213 |
+
# edges for rule stop states can be derived, so they aren't serialized
|
| 214 |
+
for state in atn.states:
|
| 215 |
+
for i in range(0, len(state.transitions)):
|
| 216 |
+
t = state.transitions[i]
|
| 217 |
+
if not isinstance(t, RuleTransition):
|
| 218 |
+
continue
|
| 219 |
+
outermostPrecedenceReturn = -1
|
| 220 |
+
if atn.ruleToStartState[t.target.ruleIndex].isPrecedenceRule:
|
| 221 |
+
if t.precedence == 0:
|
| 222 |
+
outermostPrecedenceReturn = t.target.ruleIndex
|
| 223 |
+
trans = EpsilonTransition(t.followState, outermostPrecedenceReturn)
|
| 224 |
+
atn.ruleToStopState[t.target.ruleIndex].addTransition(trans)
|
| 225 |
+
|
| 226 |
+
for state in atn.states:
|
| 227 |
+
if isinstance(state, BlockStartState):
|
| 228 |
+
# we need to know the end state to set its start state
|
| 229 |
+
if state.endState is None:
|
| 230 |
+
raise Exception("IllegalState")
|
| 231 |
+
# block end states can only be associated to a single block start state
|
| 232 |
+
if state.endState.startState is not None:
|
| 233 |
+
raise Exception("IllegalState")
|
| 234 |
+
state.endState.startState = state
|
| 235 |
+
|
| 236 |
+
if isinstance(state, PlusLoopbackState):
|
| 237 |
+
for i in range(0, len(state.transitions)):
|
| 238 |
+
target = state.transitions[i].target
|
| 239 |
+
if isinstance(target, PlusBlockStartState):
|
| 240 |
+
target.loopBackState = state
|
| 241 |
+
elif isinstance(state, StarLoopbackState):
|
| 242 |
+
for i in range(0, len(state.transitions)):
|
| 243 |
+
target = state.transitions[i].target
|
| 244 |
+
if isinstance(target, StarLoopEntryState):
|
| 245 |
+
target.loopBackState = state
|
| 246 |
+
|
| 247 |
+
def readDecisions(self, atn:ATN):
|
| 248 |
+
ndecisions = self.readInt()
|
| 249 |
+
for i in range(0, ndecisions):
|
| 250 |
+
s = self.readInt()
|
| 251 |
+
decState = atn.states[s]
|
| 252 |
+
atn.decisionToState.append(decState)
|
| 253 |
+
decState.decision = i
|
| 254 |
+
|
| 255 |
+
def readLexerActions(self, atn:ATN):
|
| 256 |
+
if atn.grammarType == ATNType.LEXER:
|
| 257 |
+
count = self.readInt()
|
| 258 |
+
atn.lexerActions = [ None ] * count
|
| 259 |
+
for i in range(0, count):
|
| 260 |
+
actionType = self.readInt()
|
| 261 |
+
data1 = self.readInt()
|
| 262 |
+
if data1 == 0xFFFF:
|
| 263 |
+
data1 = -1
|
| 264 |
+
data2 = self.readInt()
|
| 265 |
+
if data2 == 0xFFFF:
|
| 266 |
+
data2 = -1
|
| 267 |
+
lexerAction = self.lexerActionFactory(actionType, data1, data2)
|
| 268 |
+
atn.lexerActions[i] = lexerAction
|
| 269 |
+
|
| 270 |
+
def generateRuleBypassTransitions(self, atn:ATN):
|
| 271 |
+
|
| 272 |
+
count = len(atn.ruleToStartState)
|
| 273 |
+
atn.ruleToTokenType = [ 0 ] * count
|
| 274 |
+
for i in range(0, count):
|
| 275 |
+
atn.ruleToTokenType[i] = atn.maxTokenType + i + 1
|
| 276 |
+
|
| 277 |
+
for i in range(0, count):
|
| 278 |
+
self.generateRuleBypassTransition(atn, i)
|
| 279 |
+
|
| 280 |
+
def generateRuleBypassTransition(self, atn:ATN, idx:int):
|
| 281 |
+
|
| 282 |
+
bypassStart = BasicBlockStartState()
|
| 283 |
+
bypassStart.ruleIndex = idx
|
| 284 |
+
atn.addState(bypassStart)
|
| 285 |
+
|
| 286 |
+
bypassStop = BlockEndState()
|
| 287 |
+
bypassStop.ruleIndex = idx
|
| 288 |
+
atn.addState(bypassStop)
|
| 289 |
+
|
| 290 |
+
bypassStart.endState = bypassStop
|
| 291 |
+
atn.defineDecisionState(bypassStart)
|
| 292 |
+
|
| 293 |
+
bypassStop.startState = bypassStart
|
| 294 |
+
|
| 295 |
+
excludeTransition = None
|
| 296 |
+
|
| 297 |
+
if atn.ruleToStartState[idx].isPrecedenceRule:
|
| 298 |
+
# wrap from the beginning of the rule to the StarLoopEntryState
|
| 299 |
+
endState = None
|
| 300 |
+
for state in atn.states:
|
| 301 |
+
if self.stateIsEndStateFor(state, idx):
|
| 302 |
+
endState = state
|
| 303 |
+
excludeTransition = state.loopBackState.transitions[0]
|
| 304 |
+
break
|
| 305 |
+
|
| 306 |
+
if excludeTransition is None:
|
| 307 |
+
raise Exception("Couldn't identify final state of the precedence rule prefix section.")
|
| 308 |
+
|
| 309 |
+
else:
|
| 310 |
+
|
| 311 |
+
endState = atn.ruleToStopState[idx]
|
| 312 |
+
|
| 313 |
+
# all non-excluded transitions that currently target end state need to target blockEnd instead
|
| 314 |
+
for state in atn.states:
|
| 315 |
+
for transition in state.transitions:
|
| 316 |
+
if transition == excludeTransition:
|
| 317 |
+
continue
|
| 318 |
+
if transition.target == endState:
|
| 319 |
+
transition.target = bypassStop
|
| 320 |
+
|
| 321 |
+
# all transitions leaving the rule start state need to leave blockStart instead
|
| 322 |
+
ruleToStartState = atn.ruleToStartState[idx]
|
| 323 |
+
count = len(ruleToStartState.transitions)
|
| 324 |
+
while count > 0:
|
| 325 |
+
bypassStart.addTransition(ruleToStartState.transitions[count-1])
|
| 326 |
+
del ruleToStartState.transitions[-1]
|
| 327 |
+
|
| 328 |
+
# link the new states
|
| 329 |
+
atn.ruleToStartState[idx].addTransition(EpsilonTransition(bypassStart))
|
| 330 |
+
bypassStop.addTransition(EpsilonTransition(endState))
|
| 331 |
+
|
| 332 |
+
matchState = BasicState()
|
| 333 |
+
atn.addState(matchState)
|
| 334 |
+
matchState.addTransition(AtomTransition(bypassStop, atn.ruleToTokenType[idx]))
|
| 335 |
+
bypassStart.addTransition(EpsilonTransition(matchState))
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
def stateIsEndStateFor(self, state:ATNState, idx:int):
|
| 339 |
+
if state.ruleIndex != idx:
|
| 340 |
+
return None
|
| 341 |
+
if not isinstance(state, StarLoopEntryState):
|
| 342 |
+
return None
|
| 343 |
+
|
| 344 |
+
maybeLoopEndState = state.transitions[len(state.transitions) - 1].target
|
| 345 |
+
if not isinstance(maybeLoopEndState, LoopEndState):
|
| 346 |
+
return None
|
| 347 |
+
|
| 348 |
+
if maybeLoopEndState.epsilonOnlyTransitions and \
|
| 349 |
+
isinstance(maybeLoopEndState.transitions[0].target, RuleStopState):
|
| 350 |
+
return state
|
| 351 |
+
else:
|
| 352 |
+
return None
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
#
|
| 356 |
+
# Analyze the {@link StarLoopEntryState} states in the specified ATN to set
|
| 357 |
+
# the {@link StarLoopEntryState#isPrecedenceDecision} field to the
|
| 358 |
+
# correct value.
|
| 359 |
+
#
|
| 360 |
+
# @param atn The ATN.
|
| 361 |
+
#
|
| 362 |
+
def markPrecedenceDecisions(self, atn:ATN):
|
| 363 |
+
for state in atn.states:
|
| 364 |
+
if not isinstance(state, StarLoopEntryState):
|
| 365 |
+
continue
|
| 366 |
+
|
| 367 |
+
# We analyze the ATN to determine if this ATN decision state is the
|
| 368 |
+
# decision for the closure block that determines whether a
|
| 369 |
+
# precedence rule should continue or complete.
|
| 370 |
+
#
|
| 371 |
+
if atn.ruleToStartState[state.ruleIndex].isPrecedenceRule:
|
| 372 |
+
maybeLoopEndState = state.transitions[len(state.transitions) - 1].target
|
| 373 |
+
if isinstance(maybeLoopEndState, LoopEndState):
|
| 374 |
+
if maybeLoopEndState.epsilonOnlyTransitions and \
|
| 375 |
+
isinstance(maybeLoopEndState.transitions[0].target, RuleStopState):
|
| 376 |
+
state.isPrecedenceDecision = True
|
| 377 |
+
|
| 378 |
+
def verifyATN(self, atn:ATN):
|
| 379 |
+
if not self.deserializationOptions.verifyATN:
|
| 380 |
+
return
|
| 381 |
+
# verify assumptions
|
| 382 |
+
for state in atn.states:
|
| 383 |
+
if state is None:
|
| 384 |
+
continue
|
| 385 |
+
|
| 386 |
+
self.checkCondition(state.epsilonOnlyTransitions or len(state.transitions) <= 1)
|
| 387 |
+
|
| 388 |
+
if isinstance(state, PlusBlockStartState):
|
| 389 |
+
self.checkCondition(state.loopBackState is not None)
|
| 390 |
+
|
| 391 |
+
if isinstance(state, StarLoopEntryState):
|
| 392 |
+
self.checkCondition(state.loopBackState is not None)
|
| 393 |
+
self.checkCondition(len(state.transitions) == 2)
|
| 394 |
+
|
| 395 |
+
if isinstance(state.transitions[0].target, StarBlockStartState):
|
| 396 |
+
self.checkCondition(isinstance(state.transitions[1].target, LoopEndState))
|
| 397 |
+
self.checkCondition(not state.nonGreedy)
|
| 398 |
+
elif isinstance(state.transitions[0].target, LoopEndState):
|
| 399 |
+
self.checkCondition(isinstance(state.transitions[1].target, StarBlockStartState))
|
| 400 |
+
self.checkCondition(state.nonGreedy)
|
| 401 |
+
else:
|
| 402 |
+
raise Exception("IllegalState")
|
| 403 |
+
|
| 404 |
+
if isinstance(state, StarLoopbackState):
|
| 405 |
+
self.checkCondition(len(state.transitions) == 1)
|
| 406 |
+
self.checkCondition(isinstance(state.transitions[0].target, StarLoopEntryState))
|
| 407 |
+
|
| 408 |
+
if isinstance(state, LoopEndState):
|
| 409 |
+
self.checkCondition(state.loopBackState is not None)
|
| 410 |
+
|
| 411 |
+
if isinstance(state, RuleStartState):
|
| 412 |
+
self.checkCondition(state.stopState is not None)
|
| 413 |
+
|
| 414 |
+
if isinstance(state, BlockStartState):
|
| 415 |
+
self.checkCondition(state.endState is not None)
|
| 416 |
+
|
| 417 |
+
if isinstance(state, BlockEndState):
|
| 418 |
+
self.checkCondition(state.startState is not None)
|
| 419 |
+
|
| 420 |
+
if isinstance(state, DecisionState):
|
| 421 |
+
self.checkCondition(len(state.transitions) <= 1 or state.decision >= 0)
|
| 422 |
+
else:
|
| 423 |
+
self.checkCondition(len(state.transitions) <= 1 or isinstance(state, RuleStopState))
|
| 424 |
+
|
| 425 |
+
def checkCondition(self, condition:bool, message=None):
|
| 426 |
+
if not condition:
|
| 427 |
+
if message is None:
|
| 428 |
+
message = "IllegalState"
|
| 429 |
+
raise Exception(message)
|
| 430 |
+
|
| 431 |
+
def readInt(self):
|
| 432 |
+
i = self.data[self.pos]
|
| 433 |
+
self.pos += 1
|
| 434 |
+
return i
|
| 435 |
+
|
| 436 |
+
def readInt32(self):
|
| 437 |
+
low = self.readInt()
|
| 438 |
+
high = self.readInt()
|
| 439 |
+
return low | (high << 16)
|
| 440 |
+
|
| 441 |
+
def readLong(self):
|
| 442 |
+
low = self.readInt32()
|
| 443 |
+
high = self.readInt32()
|
| 444 |
+
return (low & 0x00000000FFFFFFFF) | (high << 32)
|
| 445 |
+
|
| 446 |
+
def readUUID(self):
|
| 447 |
+
low = self.readLong()
|
| 448 |
+
high = self.readLong()
|
| 449 |
+
allBits = (low & 0xFFFFFFFFFFFFFFFF) | (high << 64)
|
| 450 |
+
return UUID(int=allBits)
|
| 451 |
+
|
| 452 |
+
edgeFactories = [ lambda args : None,
|
| 453 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : EpsilonTransition(target),
|
| 454 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 455 |
+
RangeTransition(target, Token.EOF, arg2) if arg3 != 0 else RangeTransition(target, arg1, arg2),
|
| 456 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 457 |
+
RuleTransition(atn.states[arg1], arg2, arg3, target),
|
| 458 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 459 |
+
PredicateTransition(target, arg1, arg2, arg3 != 0),
|
| 460 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 461 |
+
AtomTransition(target, Token.EOF) if arg3 != 0 else AtomTransition(target, arg1),
|
| 462 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 463 |
+
ActionTransition(target, arg1, arg2, arg3 != 0),
|
| 464 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 465 |
+
SetTransition(target, sets[arg1]),
|
| 466 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 467 |
+
NotSetTransition(target, sets[arg1]),
|
| 468 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 469 |
+
WildcardTransition(target),
|
| 470 |
+
lambda atn, src, trg, arg1, arg2, arg3, sets, target : \
|
| 471 |
+
PrecedencePredicateTransition(target, arg1)
|
| 472 |
+
]
|
| 473 |
+
|
| 474 |
+
def edgeFactory(self, atn:ATN, type:int, src:int, trg:int, arg1:int, arg2:int, arg3:int, sets:list):
|
| 475 |
+
target = atn.states[trg]
|
| 476 |
+
if type > len(self.edgeFactories) or self.edgeFactories[type] is None:
|
| 477 |
+
raise Exception("The specified transition type: " + str(type) + " is not valid.")
|
| 478 |
+
else:
|
| 479 |
+
return self.edgeFactories[type](atn, src, trg, arg1, arg2, arg3, sets, target)
|
| 480 |
+
|
| 481 |
+
stateFactories = [ lambda : None,
|
| 482 |
+
lambda : BasicState(),
|
| 483 |
+
lambda : RuleStartState(),
|
| 484 |
+
lambda : BasicBlockStartState(),
|
| 485 |
+
lambda : PlusBlockStartState(),
|
| 486 |
+
lambda : StarBlockStartState(),
|
| 487 |
+
lambda : TokensStartState(),
|
| 488 |
+
lambda : RuleStopState(),
|
| 489 |
+
lambda : BlockEndState(),
|
| 490 |
+
lambda : StarLoopbackState(),
|
| 491 |
+
lambda : StarLoopEntryState(),
|
| 492 |
+
lambda : PlusLoopbackState(),
|
| 493 |
+
lambda : LoopEndState()
|
| 494 |
+
]
|
| 495 |
+
|
| 496 |
+
def stateFactory(self, type:int, ruleIndex:int):
|
| 497 |
+
if type> len(self.stateFactories) or self.stateFactories[type] is None:
|
| 498 |
+
raise Exception("The specified state type " + str(type) + " is not valid.")
|
| 499 |
+
else:
|
| 500 |
+
s = self.stateFactories[type]()
|
| 501 |
+
if s is not None:
|
| 502 |
+
s.ruleIndex = ruleIndex
|
| 503 |
+
return s
|
| 504 |
+
|
| 505 |
+
CHANNEL = 0 #The type of a {@link LexerChannelAction} action.
|
| 506 |
+
CUSTOM = 1 #The type of a {@link LexerCustomAction} action.
|
| 507 |
+
MODE = 2 #The type of a {@link LexerModeAction} action.
|
| 508 |
+
MORE = 3 #The type of a {@link LexerMoreAction} action.
|
| 509 |
+
POP_MODE = 4 #The type of a {@link LexerPopModeAction} action.
|
| 510 |
+
PUSH_MODE = 5 #The type of a {@link LexerPushModeAction} action.
|
| 511 |
+
SKIP = 6 #The type of a {@link LexerSkipAction} action.
|
| 512 |
+
TYPE = 7 #The type of a {@link LexerTypeAction} action.
|
| 513 |
+
|
| 514 |
+
actionFactories = [ lambda data1, data2: LexerChannelAction(data1),
|
| 515 |
+
lambda data1, data2: LexerCustomAction(data1, data2),
|
| 516 |
+
lambda data1, data2: LexerModeAction(data1),
|
| 517 |
+
lambda data1, data2: LexerMoreAction.INSTANCE,
|
| 518 |
+
lambda data1, data2: LexerPopModeAction.INSTANCE,
|
| 519 |
+
lambda data1, data2: LexerPushModeAction(data1),
|
| 520 |
+
lambda data1, data2: LexerSkipAction.INSTANCE,
|
| 521 |
+
lambda data1, data2: LexerTypeAction(data1)
|
| 522 |
+
]
|
| 523 |
+
|
| 524 |
+
def lexerActionFactory(self, type:int, data1:int, data2:int):
|
| 525 |
+
|
| 526 |
+
if type > len(self.actionFactories) or self.actionFactories[type] is None:
|
| 527 |
+
raise Exception("The specified lexer action type " + str(type) + " is not valid.")
|
| 528 |
+
else:
|
| 529 |
+
return self.actionFactories[type](data1, data2)
|
cameras/deps/antlr4/atn/ATNSimulator.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
from antlr4.PredictionContext import PredictionContextCache, PredictionContext, getCachedPredictionContext
|
| 7 |
+
from antlr4.atn.ATN import ATN
|
| 8 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet
|
| 9 |
+
from antlr4.dfa.DFAState import DFAState
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class ATNSimulator(object):
|
| 13 |
+
__slots__ = ('atn', 'sharedContextCache', '__dict__')
|
| 14 |
+
|
| 15 |
+
# Must distinguish between missing edge and edge we know leads nowhere#/
|
| 16 |
+
ERROR = DFAState(configs=ATNConfigSet())
|
| 17 |
+
ERROR.stateNumber = 0x7FFFFFFF
|
| 18 |
+
|
| 19 |
+
# The context cache maps all PredictionContext objects that are ==
|
| 20 |
+
# to a single cached copy. This cache is shared across all contexts
|
| 21 |
+
# in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet
|
| 22 |
+
# to use only cached nodes/graphs in addDFAState(). We don't want to
|
| 23 |
+
# fill this during closure() since there are lots of contexts that
|
| 24 |
+
# pop up but are not used ever again. It also greatly slows down closure().
|
| 25 |
+
#
|
| 26 |
+
# <p>This cache makes a huge difference in memory and a little bit in speed.
|
| 27 |
+
# For the Java grammar on java.*, it dropped the memory requirements
|
| 28 |
+
# at the end from 25M to 16M. We don't store any of the full context
|
| 29 |
+
# graphs in the DFA because they are limited to local context only,
|
| 30 |
+
# but apparently there's a lot of repetition there as well. We optimize
|
| 31 |
+
# the config contexts before storing the config set in the DFA states
|
| 32 |
+
# by literally rebuilding them with cached subgraphs only.</p>
|
| 33 |
+
#
|
| 34 |
+
# <p>I tried a cache for use during closure operations, that was
|
| 35 |
+
# whacked after each adaptivePredict(). It cost a little bit
|
| 36 |
+
# more time I think and doesn't save on the overall footprint
|
| 37 |
+
# so it's not worth the complexity.</p>
|
| 38 |
+
#/
|
| 39 |
+
def __init__(self, atn:ATN, sharedContextCache:PredictionContextCache):
|
| 40 |
+
self.atn = atn
|
| 41 |
+
self.sharedContextCache = sharedContextCache
|
| 42 |
+
|
| 43 |
+
def getCachedContext(self, context:PredictionContext):
|
| 44 |
+
if self.sharedContextCache is None:
|
| 45 |
+
return context
|
| 46 |
+
visited = dict()
|
| 47 |
+
return getCachedPredictionContext(context, self.sharedContextCache, visited)
|
cameras/deps/antlr4/atn/ATNState.py
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
# The following images show the relation of states and
|
| 8 |
+
# {@link ATNState#transitions} for various grammar constructs.
|
| 9 |
+
#
|
| 10 |
+
# <ul>
|
| 11 |
+
#
|
| 12 |
+
# <li>Solid edges marked with an ε indicate a required
|
| 13 |
+
# {@link EpsilonTransition}.</li>
|
| 14 |
+
#
|
| 15 |
+
# <li>Dashed edges indicate locations where any transition derived from
|
| 16 |
+
# {@link Transition} might appear.</li>
|
| 17 |
+
#
|
| 18 |
+
# <li>Dashed nodes are place holders for either a sequence of linked
|
| 19 |
+
# {@link BasicState} states or the inclusion of a block representing a nested
|
| 20 |
+
# construct in one of the forms below.</li>
|
| 21 |
+
#
|
| 22 |
+
# <li>Nodes showing multiple outgoing alternatives with a {@code ...} support
|
| 23 |
+
# any number of alternatives (one or more). Nodes without the {@code ...} only
|
| 24 |
+
# support the exact number of alternatives shown in the diagram.</li>
|
| 25 |
+
#
|
| 26 |
+
# </ul>
|
| 27 |
+
#
|
| 28 |
+
# <h2>Basic Blocks</h2>
|
| 29 |
+
#
|
| 30 |
+
# <h3>Rule</h3>
|
| 31 |
+
#
|
| 32 |
+
# <embed src="images/Rule.svg" type="image/svg+xml"/>
|
| 33 |
+
#
|
| 34 |
+
# <h3>Block of 1 or more alternatives</h3>
|
| 35 |
+
#
|
| 36 |
+
# <embed src="images/Block.svg" type="image/svg+xml"/>
|
| 37 |
+
#
|
| 38 |
+
# <h2>Greedy Loops</h2>
|
| 39 |
+
#
|
| 40 |
+
# <h3>Greedy Closure: {@code (...)*}</h3>
|
| 41 |
+
#
|
| 42 |
+
# <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
|
| 43 |
+
#
|
| 44 |
+
# <h3>Greedy Positive Closure: {@code (...)+}</h3>
|
| 45 |
+
#
|
| 46 |
+
# <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
|
| 47 |
+
#
|
| 48 |
+
# <h3>Greedy Optional: {@code (...)?}</h3>
|
| 49 |
+
#
|
| 50 |
+
# <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
|
| 51 |
+
#
|
| 52 |
+
# <h2>Non-Greedy Loops</h2>
|
| 53 |
+
#
|
| 54 |
+
# <h3>Non-Greedy Closure: {@code (...)*?}</h3>
|
| 55 |
+
#
|
| 56 |
+
# <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
|
| 57 |
+
#
|
| 58 |
+
# <h3>Non-Greedy Positive Closure: {@code (...)+?}</h3>
|
| 59 |
+
#
|
| 60 |
+
# <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
|
| 61 |
+
#
|
| 62 |
+
# <h3>Non-Greedy Optional: {@code (...)??}</h3>
|
| 63 |
+
#
|
| 64 |
+
# <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
|
| 65 |
+
#
|
| 66 |
+
|
| 67 |
+
from antlr4.atn.Transition import Transition
|
| 68 |
+
|
| 69 |
+
INITIAL_NUM_TRANSITIONS = 4
|
| 70 |
+
|
| 71 |
+
class ATNState(object):
|
| 72 |
+
__slots__ = (
|
| 73 |
+
'atn', 'stateNumber', 'stateType', 'ruleIndex', 'epsilonOnlyTransitions',
|
| 74 |
+
'transitions', 'nextTokenWithinRule',
|
| 75 |
+
)
|
| 76 |
+
|
| 77 |
+
# constants for serialization
|
| 78 |
+
INVALID_TYPE = 0
|
| 79 |
+
BASIC = 1
|
| 80 |
+
RULE_START = 2
|
| 81 |
+
BLOCK_START = 3
|
| 82 |
+
PLUS_BLOCK_START = 4
|
| 83 |
+
STAR_BLOCK_START = 5
|
| 84 |
+
TOKEN_START = 6
|
| 85 |
+
RULE_STOP = 7
|
| 86 |
+
BLOCK_END = 8
|
| 87 |
+
STAR_LOOP_BACK = 9
|
| 88 |
+
STAR_LOOP_ENTRY = 10
|
| 89 |
+
PLUS_LOOP_BACK = 11
|
| 90 |
+
LOOP_END = 12
|
| 91 |
+
|
| 92 |
+
serializationNames = [
|
| 93 |
+
"INVALID",
|
| 94 |
+
"BASIC",
|
| 95 |
+
"RULE_START",
|
| 96 |
+
"BLOCK_START",
|
| 97 |
+
"PLUS_BLOCK_START",
|
| 98 |
+
"STAR_BLOCK_START",
|
| 99 |
+
"TOKEN_START",
|
| 100 |
+
"RULE_STOP",
|
| 101 |
+
"BLOCK_END",
|
| 102 |
+
"STAR_LOOP_BACK",
|
| 103 |
+
"STAR_LOOP_ENTRY",
|
| 104 |
+
"PLUS_LOOP_BACK",
|
| 105 |
+
"LOOP_END" ]
|
| 106 |
+
|
| 107 |
+
INVALID_STATE_NUMBER = -1
|
| 108 |
+
|
| 109 |
+
def __init__(self):
|
| 110 |
+
# Which ATN are we in?
|
| 111 |
+
self.atn = None
|
| 112 |
+
self.stateNumber = ATNState.INVALID_STATE_NUMBER
|
| 113 |
+
self.stateType = None
|
| 114 |
+
self.ruleIndex = 0 # at runtime, we don't have Rule objects
|
| 115 |
+
self.epsilonOnlyTransitions = False
|
| 116 |
+
# Track the transitions emanating from this ATN state.
|
| 117 |
+
self.transitions = []
|
| 118 |
+
# Used to cache lookahead during parsing, not used during construction
|
| 119 |
+
self.nextTokenWithinRule = None
|
| 120 |
+
|
| 121 |
+
def __hash__(self):
|
| 122 |
+
return self.stateNumber
|
| 123 |
+
|
| 124 |
+
def __eq__(self, other):
|
| 125 |
+
return isinstance(other, ATNState) and self.stateNumber==other.stateNumber
|
| 126 |
+
|
| 127 |
+
def onlyHasEpsilonTransitions(self):
|
| 128 |
+
return self.epsilonOnlyTransitions
|
| 129 |
+
|
| 130 |
+
def isNonGreedyExitState(self):
|
| 131 |
+
return False
|
| 132 |
+
|
| 133 |
+
def __str__(self):
|
| 134 |
+
return str(self.stateNumber)
|
| 135 |
+
|
| 136 |
+
def addTransition(self, trans:Transition, index:int=-1):
|
| 137 |
+
if len(self.transitions)==0:
|
| 138 |
+
self.epsilonOnlyTransitions = trans.isEpsilon
|
| 139 |
+
elif self.epsilonOnlyTransitions != trans.isEpsilon:
|
| 140 |
+
self.epsilonOnlyTransitions = False
|
| 141 |
+
# TODO System.err.format(Locale.getDefault(), "ATN state %d has both epsilon and non-epsilon transitions.\n", stateNumber);
|
| 142 |
+
if index==-1:
|
| 143 |
+
self.transitions.append(trans)
|
| 144 |
+
else:
|
| 145 |
+
self.transitions.insert(index, trans)
|
| 146 |
+
|
| 147 |
+
class BasicState(ATNState):
|
| 148 |
+
|
| 149 |
+
def __init__(self):
|
| 150 |
+
super().__init__()
|
| 151 |
+
self.stateType = self.BASIC
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
class DecisionState(ATNState):
|
| 155 |
+
__slots__ = ('decision', 'nonGreedy')
|
| 156 |
+
def __init__(self):
|
| 157 |
+
super().__init__()
|
| 158 |
+
self.decision = -1
|
| 159 |
+
self.nonGreedy = False
|
| 160 |
+
|
| 161 |
+
# The start of a regular {@code (...)} block.
|
| 162 |
+
class BlockStartState(DecisionState):
|
| 163 |
+
__slots__ = 'endState'
|
| 164 |
+
|
| 165 |
+
def __init__(self):
|
| 166 |
+
super().__init__()
|
| 167 |
+
self.endState = None
|
| 168 |
+
|
| 169 |
+
class BasicBlockStartState(BlockStartState):
|
| 170 |
+
|
| 171 |
+
def __init__(self):
|
| 172 |
+
super().__init__()
|
| 173 |
+
self.stateType = self.BLOCK_START
|
| 174 |
+
|
| 175 |
+
# Terminal node of a simple {@code (a|b|c)} block.
|
| 176 |
+
class BlockEndState(ATNState):
|
| 177 |
+
__slots__ = 'startState'
|
| 178 |
+
|
| 179 |
+
def __init__(self):
|
| 180 |
+
super().__init__()
|
| 181 |
+
self.stateType = self.BLOCK_END
|
| 182 |
+
self.startState = None
|
| 183 |
+
|
| 184 |
+
# The last node in the ATN for a rule, unless that rule is the start symbol.
|
| 185 |
+
# In that case, there is one transition to EOF. Later, we might encode
|
| 186 |
+
# references to all calls to this rule to compute FOLLOW sets for
|
| 187 |
+
# error handling.
|
| 188 |
+
#
|
| 189 |
+
class RuleStopState(ATNState):
|
| 190 |
+
|
| 191 |
+
def __init__(self):
|
| 192 |
+
super().__init__()
|
| 193 |
+
self.stateType = self.RULE_STOP
|
| 194 |
+
|
| 195 |
+
class RuleStartState(ATNState):
|
| 196 |
+
__slots__ = ('stopState', 'isPrecedenceRule')
|
| 197 |
+
|
| 198 |
+
def __init__(self):
|
| 199 |
+
super().__init__()
|
| 200 |
+
self.stateType = self.RULE_START
|
| 201 |
+
self.stopState = None
|
| 202 |
+
self.isPrecedenceRule = False
|
| 203 |
+
|
| 204 |
+
# Decision state for {@code A+} and {@code (A|B)+}. It has two transitions:
|
| 205 |
+
# one to the loop back to start of the block and one to exit.
|
| 206 |
+
#
|
| 207 |
+
class PlusLoopbackState(DecisionState):
|
| 208 |
+
|
| 209 |
+
def __init__(self):
|
| 210 |
+
super().__init__()
|
| 211 |
+
self.stateType = self.PLUS_LOOP_BACK
|
| 212 |
+
|
| 213 |
+
# Start of {@code (A|B|...)+} loop. Technically a decision state, but
|
| 214 |
+
# we don't use for code generation; somebody might need it, so I'm defining
|
| 215 |
+
# it for completeness. In reality, the {@link PlusLoopbackState} node is the
|
| 216 |
+
# real decision-making note for {@code A+}.
|
| 217 |
+
#
|
| 218 |
+
class PlusBlockStartState(BlockStartState):
|
| 219 |
+
__slots__ = 'loopBackState'
|
| 220 |
+
|
| 221 |
+
def __init__(self):
|
| 222 |
+
super().__init__()
|
| 223 |
+
self.stateType = self.PLUS_BLOCK_START
|
| 224 |
+
self.loopBackState = None
|
| 225 |
+
|
| 226 |
+
# The block that begins a closure loop.
|
| 227 |
+
class StarBlockStartState(BlockStartState):
|
| 228 |
+
|
| 229 |
+
def __init__(self):
|
| 230 |
+
super().__init__()
|
| 231 |
+
self.stateType = self.STAR_BLOCK_START
|
| 232 |
+
|
| 233 |
+
class StarLoopbackState(ATNState):
|
| 234 |
+
|
| 235 |
+
def __init__(self):
|
| 236 |
+
super().__init__()
|
| 237 |
+
self.stateType = self.STAR_LOOP_BACK
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
class StarLoopEntryState(DecisionState):
|
| 241 |
+
__slots__ = ('loopBackState', 'isPrecedenceDecision')
|
| 242 |
+
|
| 243 |
+
def __init__(self):
|
| 244 |
+
super().__init__()
|
| 245 |
+
self.stateType = self.STAR_LOOP_ENTRY
|
| 246 |
+
self.loopBackState = None
|
| 247 |
+
# Indicates whether this state can benefit from a precedence DFA during SLL decision making.
|
| 248 |
+
self.isPrecedenceDecision = None
|
| 249 |
+
|
| 250 |
+
# Mark the end of a * or + loop.
|
| 251 |
+
class LoopEndState(ATNState):
|
| 252 |
+
__slots__ = 'loopBackState'
|
| 253 |
+
|
| 254 |
+
def __init__(self):
|
| 255 |
+
super().__init__()
|
| 256 |
+
self.stateType = self.LOOP_END
|
| 257 |
+
self.loopBackState = None
|
| 258 |
+
|
| 259 |
+
# The Tokens rule start state linking to each lexer rule start state */
|
| 260 |
+
class TokensStartState(DecisionState):
|
| 261 |
+
|
| 262 |
+
def __init__(self):
|
| 263 |
+
super().__init__()
|
| 264 |
+
self.stateType = self.TOKEN_START
|
cameras/deps/antlr4/atn/ATNType.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 2 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 3 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 4 |
+
#/
|
| 5 |
+
|
| 6 |
+
from enum import IntEnum
|
| 7 |
+
|
| 8 |
+
# Represents the type of recognizer an ATN applies to.
|
| 9 |
+
|
| 10 |
+
class ATNType(IntEnum):
|
| 11 |
+
|
| 12 |
+
LEXER = 0
|
| 13 |
+
PARSER = 1
|
| 14 |
+
|
| 15 |
+
@classmethod
|
| 16 |
+
def fromOrdinal(cls, i:int):
|
| 17 |
+
return cls._value2member_map_[i]
|
cameras/deps/antlr4/atn/LexerATNSimulator.py
ADDED
|
@@ -0,0 +1,570 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
# When we hit an accept state in either the DFA or the ATN, we
|
| 8 |
+
# have to notify the character stream to start buffering characters
|
| 9 |
+
# via {@link IntStream#mark} and record the current state. The current sim state
|
| 10 |
+
# includes the current index into the input, the current line,
|
| 11 |
+
# and current character position in that line. Note that the Lexer is
|
| 12 |
+
# tracking the starting line and characterization of the token. These
|
| 13 |
+
# variables track the "state" of the simulator when it hits an accept state.
|
| 14 |
+
#
|
| 15 |
+
# <p>We track these variables separately for the DFA and ATN simulation
|
| 16 |
+
# because the DFA simulation often has to fail over to the ATN
|
| 17 |
+
# simulation. If the ATN simulation fails, we need the DFA to fall
|
| 18 |
+
# back to its previously accepted state, if any. If the ATN succeeds,
|
| 19 |
+
# then the ATN does the accept and the DFA simulator that invoked it
|
| 20 |
+
# can simply return the predicted token type.</p>
|
| 21 |
+
#/
|
| 22 |
+
|
| 23 |
+
from antlr4.PredictionContext import PredictionContextCache, SingletonPredictionContext, PredictionContext
|
| 24 |
+
from antlr4.InputStream import InputStream
|
| 25 |
+
from antlr4.Token import Token
|
| 26 |
+
from antlr4.atn.ATN import ATN
|
| 27 |
+
from antlr4.atn.ATNConfig import LexerATNConfig
|
| 28 |
+
from antlr4.atn.ATNSimulator import ATNSimulator
|
| 29 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet, OrderedATNConfigSet
|
| 30 |
+
from antlr4.atn.ATNState import RuleStopState, ATNState
|
| 31 |
+
from antlr4.atn.LexerActionExecutor import LexerActionExecutor
|
| 32 |
+
from antlr4.atn.Transition import Transition
|
| 33 |
+
from antlr4.dfa.DFAState import DFAState
|
| 34 |
+
from antlr4.error.Errors import LexerNoViableAltException, UnsupportedOperationException
|
| 35 |
+
|
| 36 |
+
class SimState(object):
|
| 37 |
+
__slots__ = ('index', 'line', 'column', 'dfaState')
|
| 38 |
+
|
| 39 |
+
def __init__(self):
|
| 40 |
+
self.reset()
|
| 41 |
+
|
| 42 |
+
def reset(self):
|
| 43 |
+
self.index = -1
|
| 44 |
+
self.line = 0
|
| 45 |
+
self.column = -1
|
| 46 |
+
self.dfaState = None
|
| 47 |
+
|
| 48 |
+
# need forward declaration
|
| 49 |
+
Lexer = None
|
| 50 |
+
LexerATNSimulator = None
|
| 51 |
+
|
| 52 |
+
class LexerATNSimulator(ATNSimulator):
|
| 53 |
+
__slots__ = (
|
| 54 |
+
'decisionToDFA', 'recog', 'startIndex', 'line', 'column', 'mode',
|
| 55 |
+
'DEFAULT_MODE', 'MAX_CHAR_VALUE', 'prevAccept'
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
debug = False
|
| 59 |
+
dfa_debug = False
|
| 60 |
+
|
| 61 |
+
MIN_DFA_EDGE = 0
|
| 62 |
+
MAX_DFA_EDGE = 127 # forces unicode to stay in ATN
|
| 63 |
+
|
| 64 |
+
ERROR = None
|
| 65 |
+
|
| 66 |
+
def __init__(self, recog:Lexer, atn:ATN, decisionToDFA:list, sharedContextCache:PredictionContextCache):
|
| 67 |
+
super().__init__(atn, sharedContextCache)
|
| 68 |
+
self.decisionToDFA = decisionToDFA
|
| 69 |
+
self.recog = recog
|
| 70 |
+
# The current token's starting index into the character stream.
|
| 71 |
+
# Shared across DFA to ATN simulation in case the ATN fails and the
|
| 72 |
+
# DFA did not have a previous accept state. In this case, we use the
|
| 73 |
+
# ATN-generated exception object.
|
| 74 |
+
self.startIndex = -1
|
| 75 |
+
# line number 1..n within the input#/
|
| 76 |
+
self.line = 1
|
| 77 |
+
# The index of the character relative to the beginning of the line 0..n-1#/
|
| 78 |
+
self.column = 0
|
| 79 |
+
from antlr4.Lexer import Lexer
|
| 80 |
+
self.mode = Lexer.DEFAULT_MODE
|
| 81 |
+
# Cache Lexer properties to avoid further imports
|
| 82 |
+
self.DEFAULT_MODE = Lexer.DEFAULT_MODE
|
| 83 |
+
self.MAX_CHAR_VALUE = Lexer.MAX_CHAR_VALUE
|
| 84 |
+
# Used during DFA/ATN exec to record the most recent accept configuration info
|
| 85 |
+
self.prevAccept = SimState()
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def copyState(self, simulator:LexerATNSimulator ):
|
| 89 |
+
self.column = simulator.column
|
| 90 |
+
self.line = simulator.line
|
| 91 |
+
self.mode = simulator.mode
|
| 92 |
+
self.startIndex = simulator.startIndex
|
| 93 |
+
|
| 94 |
+
def match(self, input:InputStream , mode:int):
|
| 95 |
+
self.mode = mode
|
| 96 |
+
mark = input.mark()
|
| 97 |
+
try:
|
| 98 |
+
self.startIndex = input.index
|
| 99 |
+
self.prevAccept.reset()
|
| 100 |
+
dfa = self.decisionToDFA[mode]
|
| 101 |
+
if dfa.s0 is None:
|
| 102 |
+
return self.matchATN(input)
|
| 103 |
+
else:
|
| 104 |
+
return self.execATN(input, dfa.s0)
|
| 105 |
+
finally:
|
| 106 |
+
input.release(mark)
|
| 107 |
+
|
| 108 |
+
def reset(self):
|
| 109 |
+
self.prevAccept.reset()
|
| 110 |
+
self.startIndex = -1
|
| 111 |
+
self.line = 1
|
| 112 |
+
self.column = 0
|
| 113 |
+
self.mode = self.DEFAULT_MODE
|
| 114 |
+
|
| 115 |
+
def matchATN(self, input:InputStream):
|
| 116 |
+
startState = self.atn.modeToStartState[self.mode]
|
| 117 |
+
|
| 118 |
+
if LexerATNSimulator.debug:
|
| 119 |
+
print("matchATN mode " + str(self.mode) + " start: " + str(startState))
|
| 120 |
+
|
| 121 |
+
old_mode = self.mode
|
| 122 |
+
s0_closure = self.computeStartState(input, startState)
|
| 123 |
+
suppressEdge = s0_closure.hasSemanticContext
|
| 124 |
+
s0_closure.hasSemanticContext = False
|
| 125 |
+
|
| 126 |
+
next = self.addDFAState(s0_closure)
|
| 127 |
+
if not suppressEdge:
|
| 128 |
+
self.decisionToDFA[self.mode].s0 = next
|
| 129 |
+
|
| 130 |
+
predict = self.execATN(input, next)
|
| 131 |
+
|
| 132 |
+
if LexerATNSimulator.debug:
|
| 133 |
+
print("DFA after matchATN: " + str(self.decisionToDFA[old_mode].toLexerString()))
|
| 134 |
+
|
| 135 |
+
return predict
|
| 136 |
+
|
| 137 |
+
def execATN(self, input:InputStream, ds0:DFAState):
|
| 138 |
+
if LexerATNSimulator.debug:
|
| 139 |
+
print("start state closure=" + str(ds0.configs))
|
| 140 |
+
|
| 141 |
+
if ds0.isAcceptState:
|
| 142 |
+
# allow zero-length tokens
|
| 143 |
+
self.captureSimState(self.prevAccept, input, ds0)
|
| 144 |
+
|
| 145 |
+
t = input.LA(1)
|
| 146 |
+
s = ds0 # s is current/from DFA state
|
| 147 |
+
|
| 148 |
+
while True: # while more work
|
| 149 |
+
if LexerATNSimulator.debug:
|
| 150 |
+
print("execATN loop starting closure:", str(s.configs))
|
| 151 |
+
|
| 152 |
+
# As we move src->trg, src->trg, we keep track of the previous trg to
|
| 153 |
+
# avoid looking up the DFA state again, which is expensive.
|
| 154 |
+
# If the previous target was already part of the DFA, we might
|
| 155 |
+
# be able to avoid doing a reach operation upon t. If s!=null,
|
| 156 |
+
# it means that semantic predicates didn't prevent us from
|
| 157 |
+
# creating a DFA state. Once we know s!=null, we check to see if
|
| 158 |
+
# the DFA state has an edge already for t. If so, we can just reuse
|
| 159 |
+
# it's configuration set; there's no point in re-computing it.
|
| 160 |
+
# This is kind of like doing DFA simulation within the ATN
|
| 161 |
+
# simulation because DFA simulation is really just a way to avoid
|
| 162 |
+
# computing reach/closure sets. Technically, once we know that
|
| 163 |
+
# we have a previously added DFA state, we could jump over to
|
| 164 |
+
# the DFA simulator. But, that would mean popping back and forth
|
| 165 |
+
# a lot and making things more complicated algorithmically.
|
| 166 |
+
# This optimization makes a lot of sense for loops within DFA.
|
| 167 |
+
# A character will take us back to an existing DFA state
|
| 168 |
+
# that already has lots of edges out of it. e.g., .* in comments.
|
| 169 |
+
# print("Target for:" + str(s) + " and:" + str(t))
|
| 170 |
+
target = self.getExistingTargetState(s, t)
|
| 171 |
+
# print("Existing:" + str(target))
|
| 172 |
+
if target is None:
|
| 173 |
+
target = self.computeTargetState(input, s, t)
|
| 174 |
+
# print("Computed:" + str(target))
|
| 175 |
+
|
| 176 |
+
if target == self.ERROR:
|
| 177 |
+
break
|
| 178 |
+
|
| 179 |
+
# If this is a consumable input element, make sure to consume before
|
| 180 |
+
# capturing the accept state so the input index, line, and char
|
| 181 |
+
# position accurately reflect the state of the interpreter at the
|
| 182 |
+
# end of the token.
|
| 183 |
+
if t != Token.EOF:
|
| 184 |
+
self.consume(input)
|
| 185 |
+
|
| 186 |
+
if target.isAcceptState:
|
| 187 |
+
self.captureSimState(self.prevAccept, input, target)
|
| 188 |
+
if t == Token.EOF:
|
| 189 |
+
break
|
| 190 |
+
|
| 191 |
+
t = input.LA(1)
|
| 192 |
+
|
| 193 |
+
s = target # flip; current DFA target becomes new src/from state
|
| 194 |
+
|
| 195 |
+
return self.failOrAccept(self.prevAccept, input, s.configs, t)
|
| 196 |
+
|
| 197 |
+
# Get an existing target state for an edge in the DFA. If the target state
|
| 198 |
+
# for the edge has not yet been computed or is otherwise not available,
|
| 199 |
+
# this method returns {@code null}.
|
| 200 |
+
#
|
| 201 |
+
# @param s The current DFA state
|
| 202 |
+
# @param t The next input symbol
|
| 203 |
+
# @return The existing target DFA state for the given input symbol
|
| 204 |
+
# {@code t}, or {@code null} if the target state for this edge is not
|
| 205 |
+
# already cached
|
| 206 |
+
def getExistingTargetState(self, s:DFAState, t:int):
|
| 207 |
+
if s.edges is None or t < self.MIN_DFA_EDGE or t > self.MAX_DFA_EDGE:
|
| 208 |
+
return None
|
| 209 |
+
|
| 210 |
+
target = s.edges[t - self.MIN_DFA_EDGE]
|
| 211 |
+
if LexerATNSimulator.debug and target is not None:
|
| 212 |
+
print("reuse state", str(s.stateNumber), "edge to", str(target.stateNumber))
|
| 213 |
+
|
| 214 |
+
return target
|
| 215 |
+
|
| 216 |
+
# Compute a target state for an edge in the DFA, and attempt to add the
|
| 217 |
+
# computed state and corresponding edge to the DFA.
|
| 218 |
+
#
|
| 219 |
+
# @param input The input stream
|
| 220 |
+
# @param s The current DFA state
|
| 221 |
+
# @param t The next input symbol
|
| 222 |
+
#
|
| 223 |
+
# @return The computed target DFA state for the given input symbol
|
| 224 |
+
# {@code t}. If {@code t} does not lead to a valid DFA state, this method
|
| 225 |
+
# returns {@link #ERROR}.
|
| 226 |
+
def computeTargetState(self, input:InputStream, s:DFAState, t:int):
|
| 227 |
+
reach = OrderedATNConfigSet()
|
| 228 |
+
|
| 229 |
+
# if we don't find an existing DFA state
|
| 230 |
+
# Fill reach starting from closure, following t transitions
|
| 231 |
+
self.getReachableConfigSet(input, s.configs, reach, t)
|
| 232 |
+
|
| 233 |
+
if len(reach)==0: # we got nowhere on t from s
|
| 234 |
+
if not reach.hasSemanticContext:
|
| 235 |
+
# we got nowhere on t, don't throw out this knowledge; it'd
|
| 236 |
+
# cause a failover from DFA later.
|
| 237 |
+
self. addDFAEdge(s, t, self.ERROR)
|
| 238 |
+
|
| 239 |
+
# stop when we can't match any more char
|
| 240 |
+
return self.ERROR
|
| 241 |
+
|
| 242 |
+
# Add an edge from s to target DFA found/created for reach
|
| 243 |
+
return self.addDFAEdge(s, t, cfgs=reach)
|
| 244 |
+
|
| 245 |
+
def failOrAccept(self, prevAccept:SimState , input:InputStream, reach:ATNConfigSet, t:int):
|
| 246 |
+
if self.prevAccept.dfaState is not None:
|
| 247 |
+
lexerActionExecutor = prevAccept.dfaState.lexerActionExecutor
|
| 248 |
+
self.accept(input, lexerActionExecutor, self.startIndex, prevAccept.index, prevAccept.line, prevAccept.column)
|
| 249 |
+
return prevAccept.dfaState.prediction
|
| 250 |
+
else:
|
| 251 |
+
# if no accept and EOF is first char, return EOF
|
| 252 |
+
if t==Token.EOF and input.index==self.startIndex:
|
| 253 |
+
return Token.EOF
|
| 254 |
+
raise LexerNoViableAltException(self.recog, input, self.startIndex, reach)
|
| 255 |
+
|
| 256 |
+
# Given a starting configuration set, figure out all ATN configurations
|
| 257 |
+
# we can reach upon input {@code t}. Parameter {@code reach} is a return
|
| 258 |
+
# parameter.
|
| 259 |
+
def getReachableConfigSet(self, input:InputStream, closure:ATNConfigSet, reach:ATNConfigSet, t:int):
|
| 260 |
+
# this is used to skip processing for configs which have a lower priority
|
| 261 |
+
# than a config that already reached an accept state for the same rule
|
| 262 |
+
skipAlt = ATN.INVALID_ALT_NUMBER
|
| 263 |
+
for cfg in closure:
|
| 264 |
+
currentAltReachedAcceptState = ( cfg.alt == skipAlt )
|
| 265 |
+
if currentAltReachedAcceptState and cfg.passedThroughNonGreedyDecision:
|
| 266 |
+
continue
|
| 267 |
+
|
| 268 |
+
if LexerATNSimulator.debug:
|
| 269 |
+
print("testing", self.getTokenName(t), "at", str(cfg))
|
| 270 |
+
|
| 271 |
+
for trans in cfg.state.transitions: # for each transition
|
| 272 |
+
target = self.getReachableTarget(trans, t)
|
| 273 |
+
if target is not None:
|
| 274 |
+
lexerActionExecutor = cfg.lexerActionExecutor
|
| 275 |
+
if lexerActionExecutor is not None:
|
| 276 |
+
lexerActionExecutor = lexerActionExecutor.fixOffsetBeforeMatch(input.index - self.startIndex)
|
| 277 |
+
|
| 278 |
+
treatEofAsEpsilon = (t == Token.EOF)
|
| 279 |
+
config = LexerATNConfig(state=target, lexerActionExecutor=lexerActionExecutor, config=cfg)
|
| 280 |
+
if self.closure(input, config, reach, currentAltReachedAcceptState, True, treatEofAsEpsilon):
|
| 281 |
+
# any remaining configs for this alt have a lower priority than
|
| 282 |
+
# the one that just reached an accept state.
|
| 283 |
+
skipAlt = cfg.alt
|
| 284 |
+
|
| 285 |
+
def accept(self, input:InputStream, lexerActionExecutor:LexerActionExecutor, startIndex:int, index:int, line:int, charPos:int):
|
| 286 |
+
if LexerATNSimulator.debug:
|
| 287 |
+
print("ACTION", lexerActionExecutor)
|
| 288 |
+
|
| 289 |
+
# seek to after last char in token
|
| 290 |
+
input.seek(index)
|
| 291 |
+
self.line = line
|
| 292 |
+
self.column = charPos
|
| 293 |
+
|
| 294 |
+
if lexerActionExecutor is not None and self.recog is not None:
|
| 295 |
+
lexerActionExecutor.execute(self.recog, input, startIndex)
|
| 296 |
+
|
| 297 |
+
def getReachableTarget(self, trans:Transition, t:int):
|
| 298 |
+
if trans.matches(t, 0, self.MAX_CHAR_VALUE):
|
| 299 |
+
return trans.target
|
| 300 |
+
else:
|
| 301 |
+
return None
|
| 302 |
+
|
| 303 |
+
def computeStartState(self, input:InputStream, p:ATNState):
|
| 304 |
+
initialContext = PredictionContext.EMPTY
|
| 305 |
+
configs = OrderedATNConfigSet()
|
| 306 |
+
for i in range(0,len(p.transitions)):
|
| 307 |
+
target = p.transitions[i].target
|
| 308 |
+
c = LexerATNConfig(state=target, alt=i+1, context=initialContext)
|
| 309 |
+
self.closure(input, c, configs, False, False, False)
|
| 310 |
+
return configs
|
| 311 |
+
|
| 312 |
+
# Since the alternatives within any lexer decision are ordered by
|
| 313 |
+
# preference, this method stops pursuing the closure as soon as an accept
|
| 314 |
+
# state is reached. After the first accept state is reached by depth-first
|
| 315 |
+
# search from {@code config}, all other (potentially reachable) states for
|
| 316 |
+
# this rule would have a lower priority.
|
| 317 |
+
#
|
| 318 |
+
# @return {@code true} if an accept state is reached, otherwise
|
| 319 |
+
# {@code false}.
|
| 320 |
+
def closure(self, input:InputStream, config:LexerATNConfig, configs:ATNConfigSet, currentAltReachedAcceptState:bool,
|
| 321 |
+
speculative:bool, treatEofAsEpsilon:bool):
|
| 322 |
+
if LexerATNSimulator.debug:
|
| 323 |
+
print("closure(" + str(config) + ")")
|
| 324 |
+
|
| 325 |
+
if isinstance( config.state, RuleStopState ):
|
| 326 |
+
if LexerATNSimulator.debug:
|
| 327 |
+
if self.recog is not None:
|
| 328 |
+
print("closure at", self.recog.symbolicNames[config.state.ruleIndex], "rule stop", str(config))
|
| 329 |
+
else:
|
| 330 |
+
print("closure at rule stop", str(config))
|
| 331 |
+
|
| 332 |
+
if config.context is None or config.context.hasEmptyPath():
|
| 333 |
+
if config.context is None or config.context.isEmpty():
|
| 334 |
+
configs.add(config)
|
| 335 |
+
return True
|
| 336 |
+
else:
|
| 337 |
+
configs.add(LexerATNConfig(state=config.state, config=config, context=PredictionContext.EMPTY))
|
| 338 |
+
currentAltReachedAcceptState = True
|
| 339 |
+
|
| 340 |
+
if config.context is not None and not config.context.isEmpty():
|
| 341 |
+
for i in range(0,len(config.context)):
|
| 342 |
+
if config.context.getReturnState(i) != PredictionContext.EMPTY_RETURN_STATE:
|
| 343 |
+
newContext = config.context.getParent(i) # "pop" return state
|
| 344 |
+
returnState = self.atn.states[config.context.getReturnState(i)]
|
| 345 |
+
c = LexerATNConfig(state=returnState, config=config, context=newContext)
|
| 346 |
+
currentAltReachedAcceptState = self.closure(input, c, configs,
|
| 347 |
+
currentAltReachedAcceptState, speculative, treatEofAsEpsilon)
|
| 348 |
+
|
| 349 |
+
return currentAltReachedAcceptState
|
| 350 |
+
|
| 351 |
+
# optimization
|
| 352 |
+
if not config.state.epsilonOnlyTransitions:
|
| 353 |
+
if not currentAltReachedAcceptState or not config.passedThroughNonGreedyDecision:
|
| 354 |
+
configs.add(config)
|
| 355 |
+
|
| 356 |
+
for t in config.state.transitions:
|
| 357 |
+
c = self.getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon)
|
| 358 |
+
if c is not None:
|
| 359 |
+
currentAltReachedAcceptState = self.closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon)
|
| 360 |
+
|
| 361 |
+
return currentAltReachedAcceptState
|
| 362 |
+
|
| 363 |
+
# side-effect: can alter configs.hasSemanticContext
|
| 364 |
+
def getEpsilonTarget(self, input:InputStream, config:LexerATNConfig, t:Transition, configs:ATNConfigSet,
|
| 365 |
+
speculative:bool, treatEofAsEpsilon:bool):
|
| 366 |
+
c = None
|
| 367 |
+
if t.serializationType==Transition.RULE:
|
| 368 |
+
newContext = SingletonPredictionContext.create(config.context, t.followState.stateNumber)
|
| 369 |
+
c = LexerATNConfig(state=t.target, config=config, context=newContext)
|
| 370 |
+
|
| 371 |
+
elif t.serializationType==Transition.PRECEDENCE:
|
| 372 |
+
raise UnsupportedOperationException("Precedence predicates are not supported in lexers.")
|
| 373 |
+
|
| 374 |
+
elif t.serializationType==Transition.PREDICATE:
|
| 375 |
+
# Track traversing semantic predicates. If we traverse,
|
| 376 |
+
# we cannot add a DFA state for this "reach" computation
|
| 377 |
+
# because the DFA would not test the predicate again in the
|
| 378 |
+
# future. Rather than creating collections of semantic predicates
|
| 379 |
+
# like v3 and testing them on prediction, v4 will test them on the
|
| 380 |
+
# fly all the time using the ATN not the DFA. This is slower but
|
| 381 |
+
# semantically it's not used that often. One of the key elements to
|
| 382 |
+
# this predicate mechanism is not adding DFA states that see
|
| 383 |
+
# predicates immediately afterwards in the ATN. For example,
|
| 384 |
+
|
| 385 |
+
# a : ID {p1}? | ID {p2}? ;
|
| 386 |
+
|
| 387 |
+
# should create the start state for rule 'a' (to save start state
|
| 388 |
+
# competition), but should not create target of ID state. The
|
| 389 |
+
# collection of ATN states the following ID references includes
|
| 390 |
+
# states reached by traversing predicates. Since this is when we
|
| 391 |
+
# test them, we cannot cash the DFA state target of ID.
|
| 392 |
+
|
| 393 |
+
if LexerATNSimulator.debug:
|
| 394 |
+
print("EVAL rule "+ str(t.ruleIndex) + ":" + str(t.predIndex))
|
| 395 |
+
configs.hasSemanticContext = True
|
| 396 |
+
if self.evaluatePredicate(input, t.ruleIndex, t.predIndex, speculative):
|
| 397 |
+
c = LexerATNConfig(state=t.target, config=config)
|
| 398 |
+
|
| 399 |
+
elif t.serializationType==Transition.ACTION:
|
| 400 |
+
if config.context is None or config.context.hasEmptyPath():
|
| 401 |
+
# execute actions anywhere in the start rule for a token.
|
| 402 |
+
#
|
| 403 |
+
# TODO: if the entry rule is invoked recursively, some
|
| 404 |
+
# actions may be executed during the recursive call. The
|
| 405 |
+
# problem can appear when hasEmptyPath() is true but
|
| 406 |
+
# isEmpty() is false. In this case, the config needs to be
|
| 407 |
+
# split into two contexts - one with just the empty path
|
| 408 |
+
# and another with everything but the empty path.
|
| 409 |
+
# Unfortunately, the current algorithm does not allow
|
| 410 |
+
# getEpsilonTarget to return two configurations, so
|
| 411 |
+
# additional modifications are needed before we can support
|
| 412 |
+
# the split operation.
|
| 413 |
+
lexerActionExecutor = LexerActionExecutor.append(config.lexerActionExecutor,
|
| 414 |
+
self.atn.lexerActions[t.actionIndex])
|
| 415 |
+
c = LexerATNConfig(state=t.target, config=config, lexerActionExecutor=lexerActionExecutor)
|
| 416 |
+
|
| 417 |
+
else:
|
| 418 |
+
# ignore actions in referenced rules
|
| 419 |
+
c = LexerATNConfig(state=t.target, config=config)
|
| 420 |
+
|
| 421 |
+
elif t.serializationType==Transition.EPSILON:
|
| 422 |
+
c = LexerATNConfig(state=t.target, config=config)
|
| 423 |
+
|
| 424 |
+
elif t.serializationType in [ Transition.ATOM, Transition.RANGE, Transition.SET ]:
|
| 425 |
+
if treatEofAsEpsilon:
|
| 426 |
+
if t.matches(Token.EOF, 0, self.MAX_CHAR_VALUE):
|
| 427 |
+
c = LexerATNConfig(state=t.target, config=config)
|
| 428 |
+
|
| 429 |
+
return c
|
| 430 |
+
|
| 431 |
+
# Evaluate a predicate specified in the lexer.
|
| 432 |
+
#
|
| 433 |
+
# <p>If {@code speculative} is {@code true}, this method was called before
|
| 434 |
+
# {@link #consume} for the matched character. This method should call
|
| 435 |
+
# {@link #consume} before evaluating the predicate to ensure position
|
| 436 |
+
# sensitive values, including {@link Lexer#getText}, {@link Lexer#getLine},
|
| 437 |
+
# and {@link Lexer#getcolumn}, properly reflect the current
|
| 438 |
+
# lexer state. This method should restore {@code input} and the simulator
|
| 439 |
+
# to the original state before returning (i.e. undo the actions made by the
|
| 440 |
+
# call to {@link #consume}.</p>
|
| 441 |
+
#
|
| 442 |
+
# @param input The input stream.
|
| 443 |
+
# @param ruleIndex The rule containing the predicate.
|
| 444 |
+
# @param predIndex The index of the predicate within the rule.
|
| 445 |
+
# @param speculative {@code true} if the current index in {@code input} is
|
| 446 |
+
# one character before the predicate's location.
|
| 447 |
+
#
|
| 448 |
+
# @return {@code true} if the specified predicate evaluates to
|
| 449 |
+
# {@code true}.
|
| 450 |
+
#/
|
| 451 |
+
def evaluatePredicate(self, input:InputStream, ruleIndex:int, predIndex:int, speculative:bool):
|
| 452 |
+
# assume true if no recognizer was provided
|
| 453 |
+
if self.recog is None:
|
| 454 |
+
return True
|
| 455 |
+
|
| 456 |
+
if not speculative:
|
| 457 |
+
return self.recog.sempred(None, ruleIndex, predIndex)
|
| 458 |
+
|
| 459 |
+
savedcolumn = self.column
|
| 460 |
+
savedLine = self.line
|
| 461 |
+
index = input.index
|
| 462 |
+
marker = input.mark()
|
| 463 |
+
try:
|
| 464 |
+
self.consume(input)
|
| 465 |
+
return self.recog.sempred(None, ruleIndex, predIndex)
|
| 466 |
+
finally:
|
| 467 |
+
self.column = savedcolumn
|
| 468 |
+
self.line = savedLine
|
| 469 |
+
input.seek(index)
|
| 470 |
+
input.release(marker)
|
| 471 |
+
|
| 472 |
+
def captureSimState(self, settings:SimState, input:InputStream, dfaState:DFAState):
|
| 473 |
+
settings.index = input.index
|
| 474 |
+
settings.line = self.line
|
| 475 |
+
settings.column = self.column
|
| 476 |
+
settings.dfaState = dfaState
|
| 477 |
+
|
| 478 |
+
def addDFAEdge(self, from_:DFAState, tk:int, to:DFAState=None, cfgs:ATNConfigSet=None) -> DFAState:
|
| 479 |
+
|
| 480 |
+
if to is None and cfgs is not None:
|
| 481 |
+
# leading to this call, ATNConfigSet.hasSemanticContext is used as a
|
| 482 |
+
# marker indicating dynamic predicate evaluation makes this edge
|
| 483 |
+
# dependent on the specific input sequence, so the static edge in the
|
| 484 |
+
# DFA should be omitted. The target DFAState is still created since
|
| 485 |
+
# execATN has the ability to resynchronize with the DFA state cache
|
| 486 |
+
# following the predicate evaluation step.
|
| 487 |
+
#
|
| 488 |
+
# TJP notes: next time through the DFA, we see a pred again and eval.
|
| 489 |
+
# If that gets us to a previously created (but dangling) DFA
|
| 490 |
+
# state, we can continue in pure DFA mode from there.
|
| 491 |
+
#/
|
| 492 |
+
suppressEdge = cfgs.hasSemanticContext
|
| 493 |
+
cfgs.hasSemanticContext = False
|
| 494 |
+
|
| 495 |
+
to = self.addDFAState(cfgs)
|
| 496 |
+
|
| 497 |
+
if suppressEdge:
|
| 498 |
+
return to
|
| 499 |
+
|
| 500 |
+
# add the edge
|
| 501 |
+
if tk < self.MIN_DFA_EDGE or tk > self.MAX_DFA_EDGE:
|
| 502 |
+
# Only track edges within the DFA bounds
|
| 503 |
+
return to
|
| 504 |
+
|
| 505 |
+
if LexerATNSimulator.debug:
|
| 506 |
+
print("EDGE " + str(from_) + " -> " + str(to) + " upon "+ chr(tk))
|
| 507 |
+
|
| 508 |
+
if from_.edges is None:
|
| 509 |
+
# make room for tokens 1..n and -1 masquerading as index 0
|
| 510 |
+
from_.edges = [ None ] * (self.MAX_DFA_EDGE - self.MIN_DFA_EDGE + 1)
|
| 511 |
+
|
| 512 |
+
from_.edges[tk - self.MIN_DFA_EDGE] = to # connect
|
| 513 |
+
|
| 514 |
+
return to
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
# Add a new DFA state if there isn't one with this set of
|
| 518 |
+
# configurations already. This method also detects the first
|
| 519 |
+
# configuration containing an ATN rule stop state. Later, when
|
| 520 |
+
# traversing the DFA, we will know which rule to accept.
|
| 521 |
+
def addDFAState(self, configs:ATNConfigSet) -> DFAState:
|
| 522 |
+
|
| 523 |
+
proposed = DFAState(configs=configs)
|
| 524 |
+
firstConfigWithRuleStopState = next((cfg for cfg in configs if isinstance(cfg.state, RuleStopState)), None)
|
| 525 |
+
|
| 526 |
+
if firstConfigWithRuleStopState is not None:
|
| 527 |
+
proposed.isAcceptState = True
|
| 528 |
+
proposed.lexerActionExecutor = firstConfigWithRuleStopState.lexerActionExecutor
|
| 529 |
+
proposed.prediction = self.atn.ruleToTokenType[firstConfigWithRuleStopState.state.ruleIndex]
|
| 530 |
+
|
| 531 |
+
dfa = self.decisionToDFA[self.mode]
|
| 532 |
+
existing = dfa.states.get(proposed, None)
|
| 533 |
+
if existing is not None:
|
| 534 |
+
return existing
|
| 535 |
+
|
| 536 |
+
newState = proposed
|
| 537 |
+
|
| 538 |
+
newState.stateNumber = len(dfa.states)
|
| 539 |
+
configs.setReadonly(True)
|
| 540 |
+
newState.configs = configs
|
| 541 |
+
dfa.states[newState] = newState
|
| 542 |
+
return newState
|
| 543 |
+
|
| 544 |
+
def getDFA(self, mode:int):
|
| 545 |
+
return self.decisionToDFA[mode]
|
| 546 |
+
|
| 547 |
+
# Get the text matched so far for the current token.
|
| 548 |
+
def getText(self, input:InputStream):
|
| 549 |
+
# index is first lookahead char, don't include.
|
| 550 |
+
return input.getText(self.startIndex, input.index-1)
|
| 551 |
+
|
| 552 |
+
def consume(self, input:InputStream):
|
| 553 |
+
curChar = input.LA(1)
|
| 554 |
+
if curChar==ord('\n'):
|
| 555 |
+
self.line += 1
|
| 556 |
+
self.column = 0
|
| 557 |
+
else:
|
| 558 |
+
self.column += 1
|
| 559 |
+
input.consume()
|
| 560 |
+
|
| 561 |
+
def getTokenName(self, t:int):
|
| 562 |
+
if t==-1:
|
| 563 |
+
return "EOF"
|
| 564 |
+
else:
|
| 565 |
+
return "'" + chr(t) + "'"
|
| 566 |
+
|
| 567 |
+
|
| 568 |
+
LexerATNSimulator.ERROR = DFAState(0x7FFFFFFF, ATNConfigSet())
|
| 569 |
+
|
| 570 |
+
del Lexer
|
cameras/deps/antlr4/atn/LexerAction.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
from enum import IntEnum
|
| 8 |
+
|
| 9 |
+
# need forward declaration
|
| 10 |
+
Lexer = None
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class LexerActionType(IntEnum):
|
| 14 |
+
|
| 15 |
+
CHANNEL = 0 #The type of a {@link LexerChannelAction} action.
|
| 16 |
+
CUSTOM = 1 #The type of a {@link LexerCustomAction} action.
|
| 17 |
+
MODE = 2 #The type of a {@link LexerModeAction} action.
|
| 18 |
+
MORE = 3 #The type of a {@link LexerMoreAction} action.
|
| 19 |
+
POP_MODE = 4 #The type of a {@link LexerPopModeAction} action.
|
| 20 |
+
PUSH_MODE = 5 #The type of a {@link LexerPushModeAction} action.
|
| 21 |
+
SKIP = 6 #The type of a {@link LexerSkipAction} action.
|
| 22 |
+
TYPE = 7 #The type of a {@link LexerTypeAction} action.
|
| 23 |
+
|
| 24 |
+
class LexerAction(object):
|
| 25 |
+
__slots__ = ('actionType', 'isPositionDependent')
|
| 26 |
+
|
| 27 |
+
def __init__(self, action:LexerActionType):
|
| 28 |
+
self.actionType = action
|
| 29 |
+
self.isPositionDependent = False
|
| 30 |
+
|
| 31 |
+
def __hash__(self):
|
| 32 |
+
return hash(self.actionType)
|
| 33 |
+
|
| 34 |
+
def __eq__(self, other):
|
| 35 |
+
return self is other
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
#
|
| 39 |
+
# Implements the {@code skip} lexer action by calling {@link Lexer#skip}.
|
| 40 |
+
#
|
| 41 |
+
# <p>The {@code skip} command does not have any parameters, so this action is
|
| 42 |
+
# implemented as a singleton instance exposed by {@link #INSTANCE}.</p>
|
| 43 |
+
class LexerSkipAction(LexerAction):
|
| 44 |
+
|
| 45 |
+
# Provides a singleton instance of this parameterless lexer action.
|
| 46 |
+
INSTANCE = None
|
| 47 |
+
|
| 48 |
+
def __init__(self):
|
| 49 |
+
super().__init__(LexerActionType.SKIP)
|
| 50 |
+
|
| 51 |
+
def execute(self, lexer:Lexer):
|
| 52 |
+
lexer.skip()
|
| 53 |
+
|
| 54 |
+
def __str__(self):
|
| 55 |
+
return "skip"
|
| 56 |
+
|
| 57 |
+
LexerSkipAction.INSTANCE = LexerSkipAction()
|
| 58 |
+
|
| 59 |
+
# Implements the {@code type} lexer action by calling {@link Lexer#setType}
|
| 60 |
+
# with the assigned type.
|
| 61 |
+
class LexerTypeAction(LexerAction):
|
| 62 |
+
__slots__ = 'type'
|
| 63 |
+
|
| 64 |
+
def __init__(self, type:int):
|
| 65 |
+
super().__init__(LexerActionType.TYPE)
|
| 66 |
+
self.type = type
|
| 67 |
+
|
| 68 |
+
def execute(self, lexer:Lexer):
|
| 69 |
+
lexer.type = self.type
|
| 70 |
+
|
| 71 |
+
def __hash__(self):
|
| 72 |
+
return hash((self.actionType, self.type))
|
| 73 |
+
|
| 74 |
+
def __eq__(self, other):
|
| 75 |
+
if self is other:
|
| 76 |
+
return True
|
| 77 |
+
elif not isinstance(other, LexerTypeAction):
|
| 78 |
+
return False
|
| 79 |
+
else:
|
| 80 |
+
return self.type == other.type
|
| 81 |
+
|
| 82 |
+
def __str__(self):
|
| 83 |
+
return "type(" + str(self.type) + ")"
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
# Implements the {@code pushMode} lexer action by calling
|
| 87 |
+
# {@link Lexer#pushMode} with the assigned mode.
|
| 88 |
+
class LexerPushModeAction(LexerAction):
|
| 89 |
+
__slots__ = 'mode'
|
| 90 |
+
|
| 91 |
+
def __init__(self, mode:int):
|
| 92 |
+
super().__init__(LexerActionType.PUSH_MODE)
|
| 93 |
+
self.mode = mode
|
| 94 |
+
|
| 95 |
+
# <p>This action is implemented by calling {@link Lexer#pushMode} with the
|
| 96 |
+
# value provided by {@link #getMode}.</p>
|
| 97 |
+
def execute(self, lexer:Lexer):
|
| 98 |
+
lexer.pushMode(self.mode)
|
| 99 |
+
|
| 100 |
+
def __hash__(self):
|
| 101 |
+
return hash((self.actionType, self.mode))
|
| 102 |
+
|
| 103 |
+
def __eq__(self, other):
|
| 104 |
+
if self is other:
|
| 105 |
+
return True
|
| 106 |
+
elif not isinstance(other, LexerPushModeAction):
|
| 107 |
+
return False
|
| 108 |
+
else:
|
| 109 |
+
return self.mode == other.mode
|
| 110 |
+
|
| 111 |
+
def __str__(self):
|
| 112 |
+
return "pushMode(" + str(self.mode) + ")"
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
# Implements the {@code popMode} lexer action by calling {@link Lexer#popMode}.
|
| 116 |
+
#
|
| 117 |
+
# <p>The {@code popMode} command does not have any parameters, so this action is
|
| 118 |
+
# implemented as a singleton instance exposed by {@link #INSTANCE}.</p>
|
| 119 |
+
class LexerPopModeAction(LexerAction):
|
| 120 |
+
|
| 121 |
+
INSTANCE = None
|
| 122 |
+
|
| 123 |
+
def __init__(self):
|
| 124 |
+
super().__init__(LexerActionType.POP_MODE)
|
| 125 |
+
|
| 126 |
+
# <p>This action is implemented by calling {@link Lexer#popMode}.</p>
|
| 127 |
+
def execute(self, lexer:Lexer):
|
| 128 |
+
lexer.popMode()
|
| 129 |
+
|
| 130 |
+
def __str__(self):
|
| 131 |
+
return "popMode"
|
| 132 |
+
|
| 133 |
+
LexerPopModeAction.INSTANCE = LexerPopModeAction()
|
| 134 |
+
|
| 135 |
+
# Implements the {@code more} lexer action by calling {@link Lexer#more}.
|
| 136 |
+
#
|
| 137 |
+
# <p>The {@code more} command does not have any parameters, so this action is
|
| 138 |
+
# implemented as a singleton instance exposed by {@link #INSTANCE}.</p>
|
| 139 |
+
class LexerMoreAction(LexerAction):
|
| 140 |
+
|
| 141 |
+
INSTANCE = None
|
| 142 |
+
|
| 143 |
+
def __init__(self):
|
| 144 |
+
super().__init__(LexerActionType.MORE)
|
| 145 |
+
|
| 146 |
+
# <p>This action is implemented by calling {@link Lexer#popMode}.</p>
|
| 147 |
+
def execute(self, lexer:Lexer):
|
| 148 |
+
lexer.more()
|
| 149 |
+
|
| 150 |
+
def __str__(self):
|
| 151 |
+
return "more"
|
| 152 |
+
|
| 153 |
+
LexerMoreAction.INSTANCE = LexerMoreAction()
|
| 154 |
+
|
| 155 |
+
# Implements the {@code mode} lexer action by calling {@link Lexer#mode} with
|
| 156 |
+
# the assigned mode.
|
| 157 |
+
class LexerModeAction(LexerAction):
|
| 158 |
+
__slots__ = 'mode'
|
| 159 |
+
|
| 160 |
+
def __init__(self, mode:int):
|
| 161 |
+
super().__init__(LexerActionType.MODE)
|
| 162 |
+
self.mode = mode
|
| 163 |
+
|
| 164 |
+
# <p>This action is implemented by calling {@link Lexer#mode} with the
|
| 165 |
+
# value provided by {@link #getMode}.</p>
|
| 166 |
+
def execute(self, lexer:Lexer):
|
| 167 |
+
lexer.mode(self.mode)
|
| 168 |
+
|
| 169 |
+
def __hash__(self):
|
| 170 |
+
return hash((self.actionType, self.mode))
|
| 171 |
+
|
| 172 |
+
def __eq__(self, other):
|
| 173 |
+
if self is other:
|
| 174 |
+
return True
|
| 175 |
+
elif not isinstance(other, LexerModeAction):
|
| 176 |
+
return False
|
| 177 |
+
else:
|
| 178 |
+
return self.mode == other.mode
|
| 179 |
+
|
| 180 |
+
def __str__(self):
|
| 181 |
+
return "mode(" + str(self.mode) + ")"
|
| 182 |
+
|
| 183 |
+
# Executes a custom lexer action by calling {@link Recognizer#action} with the
|
| 184 |
+
# rule and action indexes assigned to the custom action. The implementation of
|
| 185 |
+
# a custom action is added to the generated code for the lexer in an override
|
| 186 |
+
# of {@link Recognizer#action} when the grammar is compiled.
|
| 187 |
+
#
|
| 188 |
+
# <p>This class may represent embedded actions created with the <code>{...}</code>
|
| 189 |
+
# syntax in ANTLR 4, as well as actions created for lexer commands where the
|
| 190 |
+
# command argument could not be evaluated when the grammar was compiled.</p>
|
| 191 |
+
|
| 192 |
+
class LexerCustomAction(LexerAction):
|
| 193 |
+
__slots__ = ('ruleIndex', 'actionIndex')
|
| 194 |
+
|
| 195 |
+
# Constructs a custom lexer action with the specified rule and action
|
| 196 |
+
# indexes.
|
| 197 |
+
#
|
| 198 |
+
# @param ruleIndex The rule index to use for calls to
|
| 199 |
+
# {@link Recognizer#action}.
|
| 200 |
+
# @param actionIndex The action index to use for calls to
|
| 201 |
+
# {@link Recognizer#action}.
|
| 202 |
+
#/
|
| 203 |
+
def __init__(self, ruleIndex:int, actionIndex:int):
|
| 204 |
+
super().__init__(LexerActionType.CUSTOM)
|
| 205 |
+
self.ruleIndex = ruleIndex
|
| 206 |
+
self.actionIndex = actionIndex
|
| 207 |
+
self.isPositionDependent = True
|
| 208 |
+
|
| 209 |
+
# <p>Custom actions are implemented by calling {@link Lexer#action} with the
|
| 210 |
+
# appropriate rule and action indexes.</p>
|
| 211 |
+
def execute(self, lexer:Lexer):
|
| 212 |
+
lexer.action(None, self.ruleIndex, self.actionIndex)
|
| 213 |
+
|
| 214 |
+
def __hash__(self):
|
| 215 |
+
return hash((self.actionType, self.ruleIndex, self.actionIndex))
|
| 216 |
+
|
| 217 |
+
def __eq__(self, other):
|
| 218 |
+
if self is other:
|
| 219 |
+
return True
|
| 220 |
+
elif not isinstance(other, LexerCustomAction):
|
| 221 |
+
return False
|
| 222 |
+
else:
|
| 223 |
+
return self.ruleIndex == other.ruleIndex and self.actionIndex == other.actionIndex
|
| 224 |
+
|
| 225 |
+
# Implements the {@code channel} lexer action by calling
|
| 226 |
+
# {@link Lexer#setChannel} with the assigned channel.
|
| 227 |
+
class LexerChannelAction(LexerAction):
|
| 228 |
+
__slots__ = 'channel'
|
| 229 |
+
|
| 230 |
+
# Constructs a new {@code channel} action with the specified channel value.
|
| 231 |
+
# @param channel The channel value to pass to {@link Lexer#setChannel}.
|
| 232 |
+
def __init__(self, channel:int):
|
| 233 |
+
super().__init__(LexerActionType.CHANNEL)
|
| 234 |
+
self.channel = channel
|
| 235 |
+
|
| 236 |
+
# <p>This action is implemented by calling {@link Lexer#setChannel} with the
|
| 237 |
+
# value provided by {@link #getChannel}.</p>
|
| 238 |
+
def execute(self, lexer:Lexer):
|
| 239 |
+
lexer._channel = self.channel
|
| 240 |
+
|
| 241 |
+
def __hash__(self):
|
| 242 |
+
return hash((self.actionType, self.channel))
|
| 243 |
+
|
| 244 |
+
def __eq__(self, other):
|
| 245 |
+
if self is other:
|
| 246 |
+
return True
|
| 247 |
+
elif not isinstance(other, LexerChannelAction):
|
| 248 |
+
return False
|
| 249 |
+
else:
|
| 250 |
+
return self.channel == other.channel
|
| 251 |
+
|
| 252 |
+
def __str__(self):
|
| 253 |
+
return "channel(" + str(self.channel) + ")"
|
| 254 |
+
|
| 255 |
+
# This implementation of {@link LexerAction} is used for tracking input offsets
|
| 256 |
+
# for position-dependent actions within a {@link LexerActionExecutor}.
|
| 257 |
+
#
|
| 258 |
+
# <p>This action is not serialized as part of the ATN, and is only required for
|
| 259 |
+
# position-dependent lexer actions which appear at a location other than the
|
| 260 |
+
# end of a rule. For more information about DFA optimizations employed for
|
| 261 |
+
# lexer actions, see {@link LexerActionExecutor#append} and
|
| 262 |
+
# {@link LexerActionExecutor#fixOffsetBeforeMatch}.</p>
|
| 263 |
+
class LexerIndexedCustomAction(LexerAction):
|
| 264 |
+
__slots__ = ('offset', 'action')
|
| 265 |
+
|
| 266 |
+
# Constructs a new indexed custom action by associating a character offset
|
| 267 |
+
# with a {@link LexerAction}.
|
| 268 |
+
#
|
| 269 |
+
# <p>Note: This class is only required for lexer actions for which
|
| 270 |
+
# {@link LexerAction#isPositionDependent} returns {@code true}.</p>
|
| 271 |
+
#
|
| 272 |
+
# @param offset The offset into the input {@link CharStream}, relative to
|
| 273 |
+
# the token start index, at which the specified lexer action should be
|
| 274 |
+
# executed.
|
| 275 |
+
# @param action The lexer action to execute at a particular offset in the
|
| 276 |
+
# input {@link CharStream}.
|
| 277 |
+
def __init__(self, offset:int, action:LexerAction):
|
| 278 |
+
super().__init__(action.actionType)
|
| 279 |
+
self.offset = offset
|
| 280 |
+
self.action = action
|
| 281 |
+
self.isPositionDependent = True
|
| 282 |
+
|
| 283 |
+
# <p>This method calls {@link #execute} on the result of {@link #getAction}
|
| 284 |
+
# using the provided {@code lexer}.</p>
|
| 285 |
+
def execute(self, lexer:Lexer):
|
| 286 |
+
# assume the input stream position was properly set by the calling code
|
| 287 |
+
self.action.execute(lexer)
|
| 288 |
+
|
| 289 |
+
def __hash__(self):
|
| 290 |
+
return hash((self.actionType, self.offset, self.action))
|
| 291 |
+
|
| 292 |
+
def __eq__(self, other):
|
| 293 |
+
if self is other:
|
| 294 |
+
return True
|
| 295 |
+
elif not isinstance(other, LexerIndexedCustomAction):
|
| 296 |
+
return False
|
| 297 |
+
else:
|
| 298 |
+
return self.offset == other.offset and self.action == other.action
|
cameras/deps/antlr4/atn/LexerActionExecutor.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
# Represents an executor for a sequence of lexer actions which traversed during
|
| 8 |
+
# the matching operation of a lexer rule (token).
|
| 9 |
+
#
|
| 10 |
+
# <p>The executor tracks position information for position-dependent lexer actions
|
| 11 |
+
# efficiently, ensuring that actions appearing only at the end of the rule do
|
| 12 |
+
# not cause bloating of the {@link DFA} created for the lexer.</p>
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
from antlr4.InputStream import InputStream
|
| 16 |
+
from antlr4.atn.LexerAction import LexerAction, LexerIndexedCustomAction
|
| 17 |
+
|
| 18 |
+
# need a forward declaration
|
| 19 |
+
Lexer = None
|
| 20 |
+
LexerActionExecutor = None
|
| 21 |
+
|
| 22 |
+
class LexerActionExecutor(object):
|
| 23 |
+
__slots__ = ('lexerActions', 'hashCode')
|
| 24 |
+
|
| 25 |
+
def __init__(self, lexerActions:list=list()):
|
| 26 |
+
self.lexerActions = lexerActions
|
| 27 |
+
# Caches the result of {@link #hashCode} since the hash code is an element
|
| 28 |
+
# of the performance-critical {@link LexerATNConfig#hashCode} operation.
|
| 29 |
+
self.hashCode = hash("".join([str(la) for la in lexerActions]))
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
# Creates a {@link LexerActionExecutor} which executes the actions for
|
| 33 |
+
# the input {@code lexerActionExecutor} followed by a specified
|
| 34 |
+
# {@code lexerAction}.
|
| 35 |
+
#
|
| 36 |
+
# @param lexerActionExecutor The executor for actions already traversed by
|
| 37 |
+
# the lexer while matching a token within a particular
|
| 38 |
+
# {@link LexerATNConfig}. If this is {@code null}, the method behaves as
|
| 39 |
+
# though it were an empty executor.
|
| 40 |
+
# @param lexerAction The lexer action to execute after the actions
|
| 41 |
+
# specified in {@code lexerActionExecutor}.
|
| 42 |
+
#
|
| 43 |
+
# @return A {@link LexerActionExecutor} for executing the combine actions
|
| 44 |
+
# of {@code lexerActionExecutor} and {@code lexerAction}.
|
| 45 |
+
@staticmethod
|
| 46 |
+
def append(lexerActionExecutor:LexerActionExecutor , lexerAction:LexerAction ):
|
| 47 |
+
if lexerActionExecutor is None:
|
| 48 |
+
return LexerActionExecutor([ lexerAction ])
|
| 49 |
+
|
| 50 |
+
lexerActions = lexerActionExecutor.lexerActions + [ lexerAction ]
|
| 51 |
+
return LexerActionExecutor(lexerActions)
|
| 52 |
+
|
| 53 |
+
# Creates a {@link LexerActionExecutor} which encodes the current offset
|
| 54 |
+
# for position-dependent lexer actions.
|
| 55 |
+
#
|
| 56 |
+
# <p>Normally, when the executor encounters lexer actions where
|
| 57 |
+
# {@link LexerAction#isPositionDependent} returns {@code true}, it calls
|
| 58 |
+
# {@link IntStream#seek} on the input {@link CharStream} to set the input
|
| 59 |
+
# position to the <em>end</em> of the current token. This behavior provides
|
| 60 |
+
# for efficient DFA representation of lexer actions which appear at the end
|
| 61 |
+
# of a lexer rule, even when the lexer rule matches a variable number of
|
| 62 |
+
# characters.</p>
|
| 63 |
+
#
|
| 64 |
+
# <p>Prior to traversing a match transition in the ATN, the current offset
|
| 65 |
+
# from the token start index is assigned to all position-dependent lexer
|
| 66 |
+
# actions which have not already been assigned a fixed offset. By storing
|
| 67 |
+
# the offsets relative to the token start index, the DFA representation of
|
| 68 |
+
# lexer actions which appear in the middle of tokens remains efficient due
|
| 69 |
+
# to sharing among tokens of the same length, regardless of their absolute
|
| 70 |
+
# position in the input stream.</p>
|
| 71 |
+
#
|
| 72 |
+
# <p>If the current executor already has offsets assigned to all
|
| 73 |
+
# position-dependent lexer actions, the method returns {@code this}.</p>
|
| 74 |
+
#
|
| 75 |
+
# @param offset The current offset to assign to all position-dependent
|
| 76 |
+
# lexer actions which do not already have offsets assigned.
|
| 77 |
+
#
|
| 78 |
+
# @return A {@link LexerActionExecutor} which stores input stream offsets
|
| 79 |
+
# for all position-dependent lexer actions.
|
| 80 |
+
#/
|
| 81 |
+
def fixOffsetBeforeMatch(self, offset:int):
|
| 82 |
+
updatedLexerActions = None
|
| 83 |
+
for i in range(0, len(self.lexerActions)):
|
| 84 |
+
if self.lexerActions[i].isPositionDependent and not isinstance(self.lexerActions[i], LexerIndexedCustomAction):
|
| 85 |
+
if updatedLexerActions is None:
|
| 86 |
+
updatedLexerActions = [ la for la in self.lexerActions ]
|
| 87 |
+
updatedLexerActions[i] = LexerIndexedCustomAction(offset, self.lexerActions[i])
|
| 88 |
+
|
| 89 |
+
if updatedLexerActions is None:
|
| 90 |
+
return self
|
| 91 |
+
else:
|
| 92 |
+
return LexerActionExecutor(updatedLexerActions)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
# Execute the actions encapsulated by this executor within the context of a
|
| 96 |
+
# particular {@link Lexer}.
|
| 97 |
+
#
|
| 98 |
+
# <p>This method calls {@link IntStream#seek} to set the position of the
|
| 99 |
+
# {@code input} {@link CharStream} prior to calling
|
| 100 |
+
# {@link LexerAction#execute} on a position-dependent action. Before the
|
| 101 |
+
# method returns, the input position will be restored to the same position
|
| 102 |
+
# it was in when the method was invoked.</p>
|
| 103 |
+
#
|
| 104 |
+
# @param lexer The lexer instance.
|
| 105 |
+
# @param input The input stream which is the source for the current token.
|
| 106 |
+
# When this method is called, the current {@link IntStream#index} for
|
| 107 |
+
# {@code input} should be the start of the following token, i.e. 1
|
| 108 |
+
# character past the end of the current token.
|
| 109 |
+
# @param startIndex The token start index. This value may be passed to
|
| 110 |
+
# {@link IntStream#seek} to set the {@code input} position to the beginning
|
| 111 |
+
# of the token.
|
| 112 |
+
#/
|
| 113 |
+
def execute(self, lexer:Lexer, input:InputStream, startIndex:int):
|
| 114 |
+
requiresSeek = False
|
| 115 |
+
stopIndex = input.index
|
| 116 |
+
try:
|
| 117 |
+
for lexerAction in self.lexerActions:
|
| 118 |
+
if isinstance(lexerAction, LexerIndexedCustomAction):
|
| 119 |
+
offset = lexerAction.offset
|
| 120 |
+
input.seek(startIndex + offset)
|
| 121 |
+
lexerAction = lexerAction.action
|
| 122 |
+
requiresSeek = (startIndex + offset) != stopIndex
|
| 123 |
+
elif lexerAction.isPositionDependent:
|
| 124 |
+
input.seek(stopIndex)
|
| 125 |
+
requiresSeek = False
|
| 126 |
+
lexerAction.execute(lexer)
|
| 127 |
+
finally:
|
| 128 |
+
if requiresSeek:
|
| 129 |
+
input.seek(stopIndex)
|
| 130 |
+
|
| 131 |
+
def __hash__(self):
|
| 132 |
+
return self.hashCode
|
| 133 |
+
|
| 134 |
+
def __eq__(self, other):
|
| 135 |
+
if self is other:
|
| 136 |
+
return True
|
| 137 |
+
elif not isinstance(other, LexerActionExecutor):
|
| 138 |
+
return False
|
| 139 |
+
else:
|
| 140 |
+
return self.hashCode == other.hashCode \
|
| 141 |
+
and self.lexerActions == other.lexerActions
|
| 142 |
+
|
| 143 |
+
del Lexer
|
cameras/deps/antlr4/atn/ParserATNSimulator.py
ADDED
|
@@ -0,0 +1,1649 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
#
|
| 8 |
+
# The embodiment of the adaptive LL(*), ALL(*), parsing strategy.
|
| 9 |
+
#
|
| 10 |
+
# <p>
|
| 11 |
+
# The basic complexity of the adaptive strategy makes it harder to understand.
|
| 12 |
+
# We begin with ATN simulation to build paths in a DFA. Subsequent prediction
|
| 13 |
+
# requests go through the DFA first. If they reach a state without an edge for
|
| 14 |
+
# the current symbol, the algorithm fails over to the ATN simulation to
|
| 15 |
+
# complete the DFA path for the current input (until it finds a conflict state
|
| 16 |
+
# or uniquely predicting state).</p>
|
| 17 |
+
#
|
| 18 |
+
# <p>
|
| 19 |
+
# All of that is done without using the outer context because we want to create
|
| 20 |
+
# a DFA that is not dependent upon the rule invocation stack when we do a
|
| 21 |
+
# prediction. One DFA works in all contexts. We avoid using context not
|
| 22 |
+
# necessarily because it's slower, although it can be, but because of the DFA
|
| 23 |
+
# caching problem. The closure routine only considers the rule invocation stack
|
| 24 |
+
# created during prediction beginning in the decision rule. For example, if
|
| 25 |
+
# prediction occurs without invoking another rule's ATN, there are no context
|
| 26 |
+
# stacks in the configurations. When lack of context leads to a conflict, we
|
| 27 |
+
# don't know if it's an ambiguity or a weakness in the strong LL(*) parsing
|
| 28 |
+
# strategy (versus full LL(*)).</p>
|
| 29 |
+
#
|
| 30 |
+
# <p>
|
| 31 |
+
# When SLL yields a configuration set with conflict, we rewind the input and
|
| 32 |
+
# retry the ATN simulation, this time using full outer context without adding
|
| 33 |
+
# to the DFA. Configuration context stacks will be the full invocation stacks
|
| 34 |
+
# from the start rule. If we get a conflict using full context, then we can
|
| 35 |
+
# definitively say we have a true ambiguity for that input sequence. If we
|
| 36 |
+
# don't get a conflict, it implies that the decision is sensitive to the outer
|
| 37 |
+
# context. (It is not context-sensitive in the sense of context-sensitive
|
| 38 |
+
# grammars.)</p>
|
| 39 |
+
#
|
| 40 |
+
# <p>
|
| 41 |
+
# The next time we reach this DFA state with an SLL conflict, through DFA
|
| 42 |
+
# simulation, we will again retry the ATN simulation using full context mode.
|
| 43 |
+
# This is slow because we can't save the results and have to "interpret" the
|
| 44 |
+
# ATN each time we get that input.</p>
|
| 45 |
+
#
|
| 46 |
+
# <p>
|
| 47 |
+
# <strong>CACHING FULL CONTEXT PREDICTIONS</strong></p>
|
| 48 |
+
#
|
| 49 |
+
# <p>
|
| 50 |
+
# We could cache results from full context to predicted alternative easily and
|
| 51 |
+
# that saves a lot of time but doesn't work in presence of predicates. The set
|
| 52 |
+
# of visible predicates from the ATN start state changes depending on the
|
| 53 |
+
# context, because closure can fall off the end of a rule. I tried to cache
|
| 54 |
+
# tuples (stack context, semantic context, predicted alt) but it was slower
|
| 55 |
+
# than interpreting and much more complicated. Also required a huge amount of
|
| 56 |
+
# memory. The goal is not to create the world's fastest parser anyway. I'd like
|
| 57 |
+
# to keep this algorithm simple. By launching multiple threads, we can improve
|
| 58 |
+
# the speed of parsing across a large number of files.</p>
|
| 59 |
+
#
|
| 60 |
+
# <p>
|
| 61 |
+
# There is no strict ordering between the amount of input used by SLL vs LL,
|
| 62 |
+
# which makes it really hard to build a cache for full context. Let's say that
|
| 63 |
+
# we have input A B C that leads to an SLL conflict with full context X. That
|
| 64 |
+
# implies that using X we might only use A B but we could also use A B C D to
|
| 65 |
+
# resolve conflict. Input A B C D could predict alternative 1 in one position
|
| 66 |
+
# in the input and A B C E could predict alternative 2 in another position in
|
| 67 |
+
# input. The conflicting SLL configurations could still be non-unique in the
|
| 68 |
+
# full context prediction, which would lead us to requiring more input than the
|
| 69 |
+
# original A B C. To make a prediction cache work, we have to track the exact
|
| 70 |
+
# input used during the previous prediction. That amounts to a cache that maps
|
| 71 |
+
# X to a specific DFA for that context.</p>
|
| 72 |
+
#
|
| 73 |
+
# <p>
|
| 74 |
+
# Something should be done for left-recursive expression predictions. They are
|
| 75 |
+
# likely LL(1) + pred eval. Easier to do the whole SLL unless error and retry
|
| 76 |
+
# with full LL thing Sam does.</p>
|
| 77 |
+
#
|
| 78 |
+
# <p>
|
| 79 |
+
# <strong>AVOIDING FULL CONTEXT PREDICTION</strong></p>
|
| 80 |
+
#
|
| 81 |
+
# <p>
|
| 82 |
+
# We avoid doing full context retry when the outer context is empty, we did not
|
| 83 |
+
# dip into the outer context by falling off the end of the decision state rule,
|
| 84 |
+
# or when we force SLL mode.</p>
|
| 85 |
+
#
|
| 86 |
+
# <p>
|
| 87 |
+
# As an example of the not dip into outer context case, consider as super
|
| 88 |
+
# constructor calls versus function calls. One grammar might look like
|
| 89 |
+
# this:</p>
|
| 90 |
+
#
|
| 91 |
+
# <pre>
|
| 92 |
+
# ctorBody
|
| 93 |
+
# : '{' superCall? stat* '}'
|
| 94 |
+
# ;
|
| 95 |
+
# </pre>
|
| 96 |
+
#
|
| 97 |
+
# <p>
|
| 98 |
+
# Or, you might see something like</p>
|
| 99 |
+
#
|
| 100 |
+
# <pre>
|
| 101 |
+
# stat
|
| 102 |
+
# : superCall ';'
|
| 103 |
+
# | expression ';'
|
| 104 |
+
# | ...
|
| 105 |
+
# ;
|
| 106 |
+
# </pre>
|
| 107 |
+
#
|
| 108 |
+
# <p>
|
| 109 |
+
# In both cases I believe that no closure operations will dip into the outer
|
| 110 |
+
# context. In the first case ctorBody in the worst case will stop at the '}'.
|
| 111 |
+
# In the 2nd case it should stop at the ';'. Both cases should stay within the
|
| 112 |
+
# entry rule and not dip into the outer context.</p>
|
| 113 |
+
#
|
| 114 |
+
# <p>
|
| 115 |
+
# <strong>PREDICATES</strong></p>
|
| 116 |
+
#
|
| 117 |
+
# <p>
|
| 118 |
+
# Predicates are always evaluated if present in either SLL or LL both. SLL and
|
| 119 |
+
# LL simulation deals with predicates differently. SLL collects predicates as
|
| 120 |
+
# it performs closure operations like ANTLR v3 did. It delays predicate
|
| 121 |
+
# evaluation until it reaches and accept state. This allows us to cache the SLL
|
| 122 |
+
# ATN simulation whereas, if we had evaluated predicates on-the-fly during
|
| 123 |
+
# closure, the DFA state configuration sets would be different and we couldn't
|
| 124 |
+
# build up a suitable DFA.</p>
|
| 125 |
+
#
|
| 126 |
+
# <p>
|
| 127 |
+
# When building a DFA accept state during ATN simulation, we evaluate any
|
| 128 |
+
# predicates and return the sole semantically valid alternative. If there is
|
| 129 |
+
# more than 1 alternative, we report an ambiguity. If there are 0 alternatives,
|
| 130 |
+
# we throw an exception. Alternatives without predicates act like they have
|
| 131 |
+
# true predicates. The simple way to think about it is to strip away all
|
| 132 |
+
# alternatives with false predicates and choose the minimum alternative that
|
| 133 |
+
# remains.</p>
|
| 134 |
+
#
|
| 135 |
+
# <p>
|
| 136 |
+
# When we start in the DFA and reach an accept state that's predicated, we test
|
| 137 |
+
# those and return the minimum semantically viable alternative. If no
|
| 138 |
+
# alternatives are viable, we throw an exception.</p>
|
| 139 |
+
#
|
| 140 |
+
# <p>
|
| 141 |
+
# During full LL ATN simulation, closure always evaluates predicates and
|
| 142 |
+
# on-the-fly. This is crucial to reducing the configuration set size during
|
| 143 |
+
# closure. It hits a landmine when parsing with the Java grammar, for example,
|
| 144 |
+
# without this on-the-fly evaluation.</p>
|
| 145 |
+
#
|
| 146 |
+
# <p>
|
| 147 |
+
# <strong>SHARING DFA</strong></p>
|
| 148 |
+
#
|
| 149 |
+
# <p>
|
| 150 |
+
# All instances of the same parser share the same decision DFAs through a
|
| 151 |
+
# static field. Each instance gets its own ATN simulator but they share the
|
| 152 |
+
# same {@link #decisionToDFA} field. They also share a
|
| 153 |
+
# {@link PredictionContextCache} object that makes sure that all
|
| 154 |
+
# {@link PredictionContext} objects are shared among the DFA states. This makes
|
| 155 |
+
# a big size difference.</p>
|
| 156 |
+
#
|
| 157 |
+
# <p>
|
| 158 |
+
# <strong>THREAD SAFETY</strong></p>
|
| 159 |
+
#
|
| 160 |
+
# <p>
|
| 161 |
+
# The {@link ParserATNSimulator} locks on the {@link #decisionToDFA} field when
|
| 162 |
+
# it adds a new DFA object to that array. {@link #addDFAEdge}
|
| 163 |
+
# locks on the DFA for the current decision when setting the
|
| 164 |
+
# {@link DFAState#edges} field. {@link #addDFAState} locks on
|
| 165 |
+
# the DFA for the current decision when looking up a DFA state to see if it
|
| 166 |
+
# already exists. We must make sure that all requests to add DFA states that
|
| 167 |
+
# are equivalent result in the same shared DFA object. This is because lots of
|
| 168 |
+
# threads will be trying to update the DFA at once. The
|
| 169 |
+
# {@link #addDFAState} method also locks inside the DFA lock
|
| 170 |
+
# but this time on the shared context cache when it rebuilds the
|
| 171 |
+
# configurations' {@link PredictionContext} objects using cached
|
| 172 |
+
# subgraphs/nodes. No other locking occurs, even during DFA simulation. This is
|
| 173 |
+
# safe as long as we can guarantee that all threads referencing
|
| 174 |
+
# {@code s.edge[t]} get the same physical target {@link DFAState}, or
|
| 175 |
+
# {@code null}. Once into the DFA, the DFA simulation does not reference the
|
| 176 |
+
# {@link DFA#states} map. It follows the {@link DFAState#edges} field to new
|
| 177 |
+
# targets. The DFA simulator will either find {@link DFAState#edges} to be
|
| 178 |
+
# {@code null}, to be non-{@code null} and {@code dfa.edges[t]} null, or
|
| 179 |
+
# {@code dfa.edges[t]} to be non-null. The
|
| 180 |
+
# {@link #addDFAEdge} method could be racing to set the field
|
| 181 |
+
# but in either case the DFA simulator works; if {@code null}, and requests ATN
|
| 182 |
+
# simulation. It could also race trying to get {@code dfa.edges[t]}, but either
|
| 183 |
+
# way it will work because it's not doing a test and set operation.</p>
|
| 184 |
+
#
|
| 185 |
+
# <p>
|
| 186 |
+
# <strong>Starting with SLL then failing to combined SLL/LL (Two-Stage
|
| 187 |
+
# Parsing)</strong></p>
|
| 188 |
+
#
|
| 189 |
+
# <p>
|
| 190 |
+
# Sam pointed out that if SLL does not give a syntax error, then there is no
|
| 191 |
+
# point in doing full LL, which is slower. We only have to try LL if we get a
|
| 192 |
+
# syntax error. For maximum speed, Sam starts the parser set to pure SLL
|
| 193 |
+
# mode with the {@link BailErrorStrategy}:</p>
|
| 194 |
+
#
|
| 195 |
+
# <pre>
|
| 196 |
+
# parser.{@link Parser#getInterpreter() getInterpreter()}.{@link #setPredictionMode setPredictionMode}{@code (}{@link PredictionMode#SLL}{@code )};
|
| 197 |
+
# parser.{@link Parser#setErrorHandler setErrorHandler}(new {@link BailErrorStrategy}());
|
| 198 |
+
# </pre>
|
| 199 |
+
#
|
| 200 |
+
# <p>
|
| 201 |
+
# If it does not get a syntax error, then we're done. If it does get a syntax
|
| 202 |
+
# error, we need to retry with the combined SLL/LL strategy.</p>
|
| 203 |
+
#
|
| 204 |
+
# <p>
|
| 205 |
+
# The reason this works is as follows. If there are no SLL conflicts, then the
|
| 206 |
+
# grammar is SLL (at least for that input set). If there is an SLL conflict,
|
| 207 |
+
# the full LL analysis must yield a set of viable alternatives which is a
|
| 208 |
+
# subset of the alternatives reported by SLL. If the LL set is a singleton,
|
| 209 |
+
# then the grammar is LL but not SLL. If the LL set is the same size as the SLL
|
| 210 |
+
# set, the decision is SLL. If the LL set has size > 1, then that decision
|
| 211 |
+
# is truly ambiguous on the current input. If the LL set is smaller, then the
|
| 212 |
+
# SLL conflict resolution might choose an alternative that the full LL would
|
| 213 |
+
# rule out as a possibility based upon better context information. If that's
|
| 214 |
+
# the case, then the SLL parse will definitely get an error because the full LL
|
| 215 |
+
# analysis says it's not viable. If SLL conflict resolution chooses an
|
| 216 |
+
# alternative within the LL set, them both SLL and LL would choose the same
|
| 217 |
+
# alternative because they both choose the minimum of multiple conflicting
|
| 218 |
+
# alternatives.</p>
|
| 219 |
+
#
|
| 220 |
+
# <p>
|
| 221 |
+
# Let's say we have a set of SLL conflicting alternatives {@code {1, 2, 3}} and
|
| 222 |
+
# a smaller LL set called <em>s</em>. If <em>s</em> is {@code {2, 3}}, then SLL
|
| 223 |
+
# parsing will get an error because SLL will pursue alternative 1. If
|
| 224 |
+
# <em>s</em> is {@code {1, 2}} or {@code {1, 3}} then both SLL and LL will
|
| 225 |
+
# choose the same alternative because alternative one is the minimum of either
|
| 226 |
+
# set. If <em>s</em> is {@code {2}} or {@code {3}} then SLL will get a syntax
|
| 227 |
+
# error. If <em>s</em> is {@code {1}} then SLL will succeed.</p>
|
| 228 |
+
#
|
| 229 |
+
# <p>
|
| 230 |
+
# Of course, if the input is invalid, then we will get an error for sure in
|
| 231 |
+
# both SLL and LL parsing. Erroneous input will therefore require 2 passes over
|
| 232 |
+
# the input.</p>
|
| 233 |
+
#
|
| 234 |
+
import sys
|
| 235 |
+
from antlr4 import DFA
|
| 236 |
+
from antlr4.PredictionContext import PredictionContextCache, PredictionContext, SingletonPredictionContext, \
|
| 237 |
+
PredictionContextFromRuleContext
|
| 238 |
+
from antlr4.BufferedTokenStream import TokenStream
|
| 239 |
+
from antlr4.Parser import Parser
|
| 240 |
+
from antlr4.ParserRuleContext import ParserRuleContext
|
| 241 |
+
from antlr4.RuleContext import RuleContext
|
| 242 |
+
from antlr4.Token import Token
|
| 243 |
+
from antlr4.Utils import str_list
|
| 244 |
+
from antlr4.atn.ATN import ATN
|
| 245 |
+
from antlr4.atn.ATNConfig import ATNConfig
|
| 246 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet
|
| 247 |
+
from antlr4.atn.ATNSimulator import ATNSimulator
|
| 248 |
+
from antlr4.atn.ATNState import StarLoopEntryState, DecisionState, RuleStopState, ATNState
|
| 249 |
+
from antlr4.atn.PredictionMode import PredictionMode
|
| 250 |
+
from antlr4.atn.SemanticContext import SemanticContext, AND, andContext, orContext
|
| 251 |
+
from antlr4.atn.Transition import Transition, RuleTransition, ActionTransition, PrecedencePredicateTransition, \
|
| 252 |
+
PredicateTransition, AtomTransition, SetTransition, NotSetTransition
|
| 253 |
+
from antlr4.dfa.DFAState import DFAState, PredPrediction
|
| 254 |
+
from antlr4.error.Errors import NoViableAltException
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
class ParserATNSimulator(ATNSimulator):
|
| 258 |
+
__slots__ = (
|
| 259 |
+
'parser', 'decisionToDFA', 'predictionMode', '_input', '_startIndex',
|
| 260 |
+
'_outerContext', '_dfa', 'mergeCache'
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
debug = False
|
| 264 |
+
debug_list_atn_decisions = False
|
| 265 |
+
dfa_debug = False
|
| 266 |
+
retry_debug = False
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
def __init__(self, parser:Parser, atn:ATN, decisionToDFA:list, sharedContextCache:PredictionContextCache):
|
| 270 |
+
super().__init__(atn, sharedContextCache)
|
| 271 |
+
self.parser = parser
|
| 272 |
+
self.decisionToDFA = decisionToDFA
|
| 273 |
+
# SLL, LL, or LL + exact ambig detection?#
|
| 274 |
+
self.predictionMode = PredictionMode.LL
|
| 275 |
+
# LAME globals to avoid parameters!!!!! I need these down deep in predTransition
|
| 276 |
+
self._input = None
|
| 277 |
+
self._startIndex = 0
|
| 278 |
+
self._outerContext = None
|
| 279 |
+
self._dfa = None
|
| 280 |
+
# Each prediction operation uses a cache for merge of prediction contexts.
|
| 281 |
+
# Don't keep around as it wastes huge amounts of memory. DoubleKeyMap
|
| 282 |
+
# isn't synchronized but we're ok since two threads shouldn't reuse same
|
| 283 |
+
# parser/atnsim object because it can only handle one input at a time.
|
| 284 |
+
# This maps graphs a and b to merged result c. (a,b)→c. We can avoid
|
| 285 |
+
# the merge if we ever see a and b again. Note that (b,a)→c should
|
| 286 |
+
# also be examined during cache lookup.
|
| 287 |
+
#
|
| 288 |
+
self.mergeCache = None
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def reset(self):
|
| 292 |
+
pass
|
| 293 |
+
|
| 294 |
+
def adaptivePredict(self, input:TokenStream, decision:int, outerContext:ParserRuleContext):
|
| 295 |
+
if ParserATNSimulator.debug or ParserATNSimulator.debug_list_atn_decisions:
|
| 296 |
+
print("adaptivePredict decision " + str(decision) +
|
| 297 |
+
" exec LA(1)==" + self.getLookaheadName(input) +
|
| 298 |
+
" line " + str(input.LT(1).line) + ":" +
|
| 299 |
+
str(input.LT(1).column))
|
| 300 |
+
self._input = input
|
| 301 |
+
self._startIndex = input.index
|
| 302 |
+
self._outerContext = outerContext
|
| 303 |
+
|
| 304 |
+
dfa = self.decisionToDFA[decision]
|
| 305 |
+
self._dfa = dfa
|
| 306 |
+
m = input.mark()
|
| 307 |
+
index = input.index
|
| 308 |
+
|
| 309 |
+
# Now we are certain to have a specific decision's DFA
|
| 310 |
+
# But, do we still need an initial state?
|
| 311 |
+
try:
|
| 312 |
+
if dfa.precedenceDfa:
|
| 313 |
+
# the start state for a precedence DFA depends on the current
|
| 314 |
+
# parser precedence, and is provided by a DFA method.
|
| 315 |
+
s0 = dfa.getPrecedenceStartState(self.parser.getPrecedence())
|
| 316 |
+
else:
|
| 317 |
+
# the start state for a "regular" DFA is just s0
|
| 318 |
+
s0 = dfa.s0
|
| 319 |
+
|
| 320 |
+
if s0 is None:
|
| 321 |
+
if outerContext is None:
|
| 322 |
+
outerContext = ParserRuleContext.EMPTY
|
| 323 |
+
if ParserATNSimulator.debug or ParserATNSimulator.debug_list_atn_decisions:
|
| 324 |
+
print("predictATN decision " + str(dfa.decision) +
|
| 325 |
+
" exec LA(1)==" + self.getLookaheadName(input) +
|
| 326 |
+
", outerContext=" + outerContext.toString(self.parser.literalNames, None))
|
| 327 |
+
|
| 328 |
+
fullCtx = False
|
| 329 |
+
s0_closure = self.computeStartState(dfa.atnStartState, ParserRuleContext.EMPTY, fullCtx)
|
| 330 |
+
|
| 331 |
+
if dfa.precedenceDfa:
|
| 332 |
+
# If this is a precedence DFA, we use applyPrecedenceFilter
|
| 333 |
+
# to convert the computed start state to a precedence start
|
| 334 |
+
# state. We then use DFA.setPrecedenceStartState to set the
|
| 335 |
+
# appropriate start state for the precedence level rather
|
| 336 |
+
# than simply setting DFA.s0.
|
| 337 |
+
#
|
| 338 |
+
dfa.s0.configs = s0_closure # not used for prediction but useful to know start configs anyway
|
| 339 |
+
s0_closure = self.applyPrecedenceFilter(s0_closure)
|
| 340 |
+
s0 = self.addDFAState(dfa, DFAState(configs=s0_closure))
|
| 341 |
+
dfa.setPrecedenceStartState(self.parser.getPrecedence(), s0)
|
| 342 |
+
else:
|
| 343 |
+
s0 = self.addDFAState(dfa, DFAState(configs=s0_closure))
|
| 344 |
+
dfa.s0 = s0
|
| 345 |
+
|
| 346 |
+
alt = self.execATN(dfa, s0, input, index, outerContext)
|
| 347 |
+
if ParserATNSimulator.debug:
|
| 348 |
+
print("DFA after predictATN: " + dfa.toString(self.parser.literalNames))
|
| 349 |
+
return alt
|
| 350 |
+
finally:
|
| 351 |
+
self._dfa = None
|
| 352 |
+
self.mergeCache = None # wack cache after each prediction
|
| 353 |
+
input.seek(index)
|
| 354 |
+
input.release(m)
|
| 355 |
+
|
| 356 |
+
# Performs ATN simulation to compute a predicted alternative based
|
| 357 |
+
# upon the remaining input, but also updates the DFA cache to avoid
|
| 358 |
+
# having to traverse the ATN again for the same input sequence.
|
| 359 |
+
|
| 360 |
+
# There are some key conditions we're looking for after computing a new
|
| 361 |
+
# set of ATN configs (proposed DFA state):
|
| 362 |
+
# if the set is empty, there is no viable alternative for current symbol
|
| 363 |
+
# does the state uniquely predict an alternative?
|
| 364 |
+
# does the state have a conflict that would prevent us from
|
| 365 |
+
# putting it on the work list?
|
| 366 |
+
|
| 367 |
+
# We also have some key operations to do:
|
| 368 |
+
# add an edge from previous DFA state to potentially new DFA state, D,
|
| 369 |
+
# upon current symbol but only if adding to work list, which means in all
|
| 370 |
+
# cases except no viable alternative (and possibly non-greedy decisions?)
|
| 371 |
+
# collecting predicates and adding semantic context to DFA accept states
|
| 372 |
+
# adding rule context to context-sensitive DFA accept states
|
| 373 |
+
# consuming an input symbol
|
| 374 |
+
# reporting a conflict
|
| 375 |
+
# reporting an ambiguity
|
| 376 |
+
# reporting a context sensitivity
|
| 377 |
+
# reporting insufficient predicates
|
| 378 |
+
|
| 379 |
+
# cover these cases:
|
| 380 |
+
# dead end
|
| 381 |
+
# single alt
|
| 382 |
+
# single alt + preds
|
| 383 |
+
# conflict
|
| 384 |
+
# conflict + preds
|
| 385 |
+
#
|
| 386 |
+
def execATN(self, dfa:DFA, s0:DFAState, input:TokenStream, startIndex:int, outerContext:ParserRuleContext ):
|
| 387 |
+
if ParserATNSimulator.debug or ParserATNSimulator.debug_list_atn_decisions:
|
| 388 |
+
print("execATN decision " + str(dfa.decision) +
|
| 389 |
+
" exec LA(1)==" + self.getLookaheadName(input) +
|
| 390 |
+
" line " + str(input.LT(1).line) + ":" + str(input.LT(1).column))
|
| 391 |
+
|
| 392 |
+
previousD = s0
|
| 393 |
+
|
| 394 |
+
if ParserATNSimulator.debug:
|
| 395 |
+
print("s0 = " + str(s0))
|
| 396 |
+
|
| 397 |
+
t = input.LA(1)
|
| 398 |
+
|
| 399 |
+
while True: # while more work
|
| 400 |
+
D = self.getExistingTargetState(previousD, t)
|
| 401 |
+
if D is None:
|
| 402 |
+
D = self.computeTargetState(dfa, previousD, t)
|
| 403 |
+
if D is self.ERROR:
|
| 404 |
+
# if any configs in previous dipped into outer context, that
|
| 405 |
+
# means that input up to t actually finished entry rule
|
| 406 |
+
# at least for SLL decision. Full LL doesn't dip into outer
|
| 407 |
+
# so don't need special case.
|
| 408 |
+
# We will get an error no matter what so delay until after
|
| 409 |
+
# decision; better error message. Also, no reachable target
|
| 410 |
+
# ATN states in SLL implies LL will also get nowhere.
|
| 411 |
+
# If conflict in states that dip out, choose min since we
|
| 412 |
+
# will get error no matter what.
|
| 413 |
+
e = self.noViableAlt(input, outerContext, previousD.configs, startIndex)
|
| 414 |
+
input.seek(startIndex)
|
| 415 |
+
alt = self.getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext)
|
| 416 |
+
if alt!=ATN.INVALID_ALT_NUMBER:
|
| 417 |
+
return alt
|
| 418 |
+
raise e
|
| 419 |
+
|
| 420 |
+
if D.requiresFullContext and self.predictionMode != PredictionMode.SLL:
|
| 421 |
+
# IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error)
|
| 422 |
+
conflictingAlts = D.configs.conflictingAlts
|
| 423 |
+
if D.predicates is not None:
|
| 424 |
+
if ParserATNSimulator.debug:
|
| 425 |
+
print("DFA state has preds in DFA sim LL failover")
|
| 426 |
+
conflictIndex = input.index
|
| 427 |
+
if conflictIndex != startIndex:
|
| 428 |
+
input.seek(startIndex)
|
| 429 |
+
|
| 430 |
+
conflictingAlts = self.evalSemanticContext(D.predicates, outerContext, True)
|
| 431 |
+
if len(conflictingAlts)==1:
|
| 432 |
+
if ParserATNSimulator.debug:
|
| 433 |
+
print("Full LL avoided")
|
| 434 |
+
return min(conflictingAlts)
|
| 435 |
+
|
| 436 |
+
if conflictIndex != startIndex:
|
| 437 |
+
# restore the index so reporting the fallback to full
|
| 438 |
+
# context occurs with the index at the correct spot
|
| 439 |
+
input.seek(conflictIndex)
|
| 440 |
+
|
| 441 |
+
if ParserATNSimulator.dfa_debug:
|
| 442 |
+
print("ctx sensitive state " + str(outerContext) +" in " + str(D))
|
| 443 |
+
fullCtx = True
|
| 444 |
+
s0_closure = self.computeStartState(dfa.atnStartState, outerContext, fullCtx)
|
| 445 |
+
self.reportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.index)
|
| 446 |
+
alt = self.execATNWithFullContext(dfa, D, s0_closure, input, startIndex, outerContext)
|
| 447 |
+
return alt
|
| 448 |
+
|
| 449 |
+
if D.isAcceptState:
|
| 450 |
+
if D.predicates is None:
|
| 451 |
+
return D.prediction
|
| 452 |
+
|
| 453 |
+
stopIndex = input.index
|
| 454 |
+
input.seek(startIndex)
|
| 455 |
+
alts = self.evalSemanticContext(D.predicates, outerContext, True)
|
| 456 |
+
if len(alts)==0:
|
| 457 |
+
raise self.noViableAlt(input, outerContext, D.configs, startIndex)
|
| 458 |
+
elif len(alts)==1:
|
| 459 |
+
return min(alts)
|
| 460 |
+
else:
|
| 461 |
+
# report ambiguity after predicate evaluation to make sure the correct
|
| 462 |
+
# set of ambig alts is reported.
|
| 463 |
+
self.reportAmbiguity(dfa, D, startIndex, stopIndex, False, alts, D.configs)
|
| 464 |
+
return min(alts)
|
| 465 |
+
|
| 466 |
+
previousD = D
|
| 467 |
+
|
| 468 |
+
if t != Token.EOF:
|
| 469 |
+
input.consume()
|
| 470 |
+
t = input.LA(1)
|
| 471 |
+
|
| 472 |
+
#
|
| 473 |
+
# Get an existing target state for an edge in the DFA. If the target state
|
| 474 |
+
# for the edge has not yet been computed or is otherwise not available,
|
| 475 |
+
# this method returns {@code null}.
|
| 476 |
+
#
|
| 477 |
+
# @param previousD The current DFA state
|
| 478 |
+
# @param t The next input symbol
|
| 479 |
+
# @return The existing target DFA state for the given input symbol
|
| 480 |
+
# {@code t}, or {@code null} if the target state for this edge is not
|
| 481 |
+
# already cached
|
| 482 |
+
#
|
| 483 |
+
def getExistingTargetState(self, previousD:DFAState, t:int):
|
| 484 |
+
edges = previousD.edges
|
| 485 |
+
if edges is None or t + 1 < 0 or t + 1 >= len(edges):
|
| 486 |
+
return None
|
| 487 |
+
else:
|
| 488 |
+
return edges[t + 1]
|
| 489 |
+
|
| 490 |
+
#
|
| 491 |
+
# Compute a target state for an edge in the DFA, and attempt to add the
|
| 492 |
+
# computed state and corresponding edge to the DFA.
|
| 493 |
+
#
|
| 494 |
+
# @param dfa The DFA
|
| 495 |
+
# @param previousD The current DFA state
|
| 496 |
+
# @param t The next input symbol
|
| 497 |
+
#
|
| 498 |
+
# @return The computed target DFA state for the given input symbol
|
| 499 |
+
# {@code t}. If {@code t} does not lead to a valid DFA state, this method
|
| 500 |
+
# returns {@link #ERROR}.
|
| 501 |
+
#
|
| 502 |
+
def computeTargetState(self, dfa:DFA, previousD:DFAState, t:int):
|
| 503 |
+
reach = self.computeReachSet(previousD.configs, t, False)
|
| 504 |
+
if reach is None:
|
| 505 |
+
self.addDFAEdge(dfa, previousD, t, self.ERROR)
|
| 506 |
+
return self.ERROR
|
| 507 |
+
|
| 508 |
+
# create new target state; we'll add to DFA after it's complete
|
| 509 |
+
D = DFAState(configs=reach)
|
| 510 |
+
|
| 511 |
+
predictedAlt = self.getUniqueAlt(reach)
|
| 512 |
+
|
| 513 |
+
if ParserATNSimulator.debug:
|
| 514 |
+
altSubSets = PredictionMode.getConflictingAltSubsets(reach)
|
| 515 |
+
print("SLL altSubSets=" + str(altSubSets) + ", configs=" + str(reach) +
|
| 516 |
+
", predict=" + str(predictedAlt) + ", allSubsetsConflict=" +
|
| 517 |
+
str(PredictionMode.allSubsetsConflict(altSubSets)) + ", conflictingAlts=" +
|
| 518 |
+
str(self.getConflictingAlts(reach)))
|
| 519 |
+
|
| 520 |
+
if predictedAlt!=ATN.INVALID_ALT_NUMBER:
|
| 521 |
+
# NO CONFLICT, UNIQUELY PREDICTED ALT
|
| 522 |
+
D.isAcceptState = True
|
| 523 |
+
D.configs.uniqueAlt = predictedAlt
|
| 524 |
+
D.prediction = predictedAlt
|
| 525 |
+
elif PredictionMode.hasSLLConflictTerminatingPrediction(self.predictionMode, reach):
|
| 526 |
+
# MORE THAN ONE VIABLE ALTERNATIVE
|
| 527 |
+
D.configs.conflictingAlts = self.getConflictingAlts(reach)
|
| 528 |
+
D.requiresFullContext = True
|
| 529 |
+
# in SLL-only mode, we will stop at this state and return the minimum alt
|
| 530 |
+
D.isAcceptState = True
|
| 531 |
+
D.prediction = min(D.configs.conflictingAlts)
|
| 532 |
+
|
| 533 |
+
if D.isAcceptState and D.configs.hasSemanticContext:
|
| 534 |
+
self.predicateDFAState(D, self.atn.getDecisionState(dfa.decision))
|
| 535 |
+
if D.predicates is not None:
|
| 536 |
+
D.prediction = ATN.INVALID_ALT_NUMBER
|
| 537 |
+
|
| 538 |
+
# all adds to dfa are done after we've created full D state
|
| 539 |
+
D = self.addDFAEdge(dfa, previousD, t, D)
|
| 540 |
+
return D
|
| 541 |
+
|
| 542 |
+
def predicateDFAState(self, dfaState:DFAState, decisionState:DecisionState):
|
| 543 |
+
# We need to test all predicates, even in DFA states that
|
| 544 |
+
# uniquely predict alternative.
|
| 545 |
+
nalts = len(decisionState.transitions)
|
| 546 |
+
# Update DFA so reach becomes accept state with (predicate,alt)
|
| 547 |
+
# pairs if preds found for conflicting alts
|
| 548 |
+
altsToCollectPredsFrom = self.getConflictingAltsOrUniqueAlt(dfaState.configs)
|
| 549 |
+
altToPred = self.getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState.configs, nalts)
|
| 550 |
+
if altToPred is not None:
|
| 551 |
+
dfaState.predicates = self.getPredicatePredictions(altsToCollectPredsFrom, altToPred)
|
| 552 |
+
dfaState.prediction = ATN.INVALID_ALT_NUMBER # make sure we use preds
|
| 553 |
+
else:
|
| 554 |
+
# There are preds in configs but they might go away
|
| 555 |
+
# when OR'd together like {p}? || NONE == NONE. If neither
|
| 556 |
+
# alt has preds, resolve to min alt
|
| 557 |
+
dfaState.prediction = min(altsToCollectPredsFrom)
|
| 558 |
+
|
| 559 |
+
# comes back with reach.uniqueAlt set to a valid alt
|
| 560 |
+
def execATNWithFullContext(self, dfa:DFA, D:DFAState, # how far we got before failing over
|
| 561 |
+
s0:ATNConfigSet,
|
| 562 |
+
input:TokenStream,
|
| 563 |
+
startIndex:int,
|
| 564 |
+
outerContext:ParserRuleContext):
|
| 565 |
+
if ParserATNSimulator.debug or ParserATNSimulator.debug_list_atn_decisions:
|
| 566 |
+
print("execATNWithFullContext", str(s0))
|
| 567 |
+
fullCtx = True
|
| 568 |
+
foundExactAmbig = False
|
| 569 |
+
reach = None
|
| 570 |
+
previous = s0
|
| 571 |
+
input.seek(startIndex)
|
| 572 |
+
t = input.LA(1)
|
| 573 |
+
predictedAlt = -1
|
| 574 |
+
while (True): # while more work
|
| 575 |
+
reach = self.computeReachSet(previous, t, fullCtx)
|
| 576 |
+
if reach is None:
|
| 577 |
+
# if any configs in previous dipped into outer context, that
|
| 578 |
+
# means that input up to t actually finished entry rule
|
| 579 |
+
# at least for LL decision. Full LL doesn't dip into outer
|
| 580 |
+
# so don't need special case.
|
| 581 |
+
# We will get an error no matter what so delay until after
|
| 582 |
+
# decision; better error message. Also, no reachable target
|
| 583 |
+
# ATN states in SLL implies LL will also get nowhere.
|
| 584 |
+
# If conflict in states that dip out, choose min since we
|
| 585 |
+
# will get error no matter what.
|
| 586 |
+
e = self.noViableAlt(input, outerContext, previous, startIndex)
|
| 587 |
+
input.seek(startIndex)
|
| 588 |
+
alt = self.getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext)
|
| 589 |
+
if alt!=ATN.INVALID_ALT_NUMBER:
|
| 590 |
+
return alt
|
| 591 |
+
else:
|
| 592 |
+
raise e
|
| 593 |
+
|
| 594 |
+
altSubSets = PredictionMode.getConflictingAltSubsets(reach)
|
| 595 |
+
if ParserATNSimulator.debug:
|
| 596 |
+
print("LL altSubSets=" + str(altSubSets) + ", predict=" +
|
| 597 |
+
str(PredictionMode.getUniqueAlt(altSubSets)) + ", resolvesToJustOneViableAlt=" +
|
| 598 |
+
str(PredictionMode.resolvesToJustOneViableAlt(altSubSets)))
|
| 599 |
+
|
| 600 |
+
reach.uniqueAlt = self.getUniqueAlt(reach)
|
| 601 |
+
# unique prediction?
|
| 602 |
+
if reach.uniqueAlt!=ATN.INVALID_ALT_NUMBER:
|
| 603 |
+
predictedAlt = reach.uniqueAlt
|
| 604 |
+
break
|
| 605 |
+
elif self.predictionMode is not PredictionMode.LL_EXACT_AMBIG_DETECTION:
|
| 606 |
+
predictedAlt = PredictionMode.resolvesToJustOneViableAlt(altSubSets)
|
| 607 |
+
if predictedAlt != ATN.INVALID_ALT_NUMBER:
|
| 608 |
+
break
|
| 609 |
+
else:
|
| 610 |
+
# In exact ambiguity mode, we never try to terminate early.
|
| 611 |
+
# Just keeps scarfing until we know what the conflict is
|
| 612 |
+
if PredictionMode.allSubsetsConflict(altSubSets) and PredictionMode.allSubsetsEqual(altSubSets):
|
| 613 |
+
foundExactAmbig = True
|
| 614 |
+
predictedAlt = PredictionMode.getSingleViableAlt(altSubSets)
|
| 615 |
+
break
|
| 616 |
+
# else there are multiple non-conflicting subsets or
|
| 617 |
+
# we're not sure what the ambiguity is yet.
|
| 618 |
+
# So, keep going.
|
| 619 |
+
|
| 620 |
+
previous = reach
|
| 621 |
+
if t != Token.EOF:
|
| 622 |
+
input.consume()
|
| 623 |
+
t = input.LA(1)
|
| 624 |
+
|
| 625 |
+
# If the configuration set uniquely predicts an alternative,
|
| 626 |
+
# without conflict, then we know that it's a full LL decision
|
| 627 |
+
# not SLL.
|
| 628 |
+
if reach.uniqueAlt != ATN.INVALID_ALT_NUMBER :
|
| 629 |
+
self.reportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.index)
|
| 630 |
+
return predictedAlt
|
| 631 |
+
|
| 632 |
+
# We do not check predicates here because we have checked them
|
| 633 |
+
# on-the-fly when doing full context prediction.
|
| 634 |
+
|
| 635 |
+
#
|
| 636 |
+
# In non-exact ambiguity detection mode, we might actually be able to
|
| 637 |
+
# detect an exact ambiguity, but I'm not going to spend the cycles
|
| 638 |
+
# needed to check. We only emit ambiguity warnings in exact ambiguity
|
| 639 |
+
# mode.
|
| 640 |
+
#
|
| 641 |
+
# For example, we might know that we have conflicting configurations.
|
| 642 |
+
# But, that does not mean that there is no way forward without a
|
| 643 |
+
# conflict. It's possible to have nonconflicting alt subsets as in:
|
| 644 |
+
|
| 645 |
+
# altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}]
|
| 646 |
+
|
| 647 |
+
# from
|
| 648 |
+
#
|
| 649 |
+
# [(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]),
|
| 650 |
+
# (13,2,[5 10 $]), (21,2,[5 10 $]), (11,2,[$])]
|
| 651 |
+
#
|
| 652 |
+
# In this case, (17,1,[5 $]) indicates there is some next sequence that
|
| 653 |
+
# would resolve this without conflict to alternative 1. Any other viable
|
| 654 |
+
# next sequence, however, is associated with a conflict. We stop
|
| 655 |
+
# looking for input because no amount of further lookahead will alter
|
| 656 |
+
# the fact that we should predict alternative 1. We just can't say for
|
| 657 |
+
# sure that there is an ambiguity without looking further.
|
| 658 |
+
|
| 659 |
+
self.reportAmbiguity(dfa, D, startIndex, input.index, foundExactAmbig, None, reach)
|
| 660 |
+
|
| 661 |
+
return predictedAlt
|
| 662 |
+
|
| 663 |
+
def computeReachSet(self, closure:ATNConfigSet, t:int, fullCtx:bool):
|
| 664 |
+
if ParserATNSimulator.debug:
|
| 665 |
+
print("in computeReachSet, starting closure: " + str(closure))
|
| 666 |
+
|
| 667 |
+
if self.mergeCache is None:
|
| 668 |
+
self.mergeCache = dict()
|
| 669 |
+
|
| 670 |
+
intermediate = ATNConfigSet(fullCtx)
|
| 671 |
+
|
| 672 |
+
# Configurations already in a rule stop state indicate reaching the end
|
| 673 |
+
# of the decision rule (local context) or end of the start rule (full
|
| 674 |
+
# context). Once reached, these configurations are never updated by a
|
| 675 |
+
# closure operation, so they are handled separately for the performance
|
| 676 |
+
# advantage of having a smaller intermediate set when calling closure.
|
| 677 |
+
#
|
| 678 |
+
# For full-context reach operations, separate handling is required to
|
| 679 |
+
# ensure that the alternative matching the longest overall sequence is
|
| 680 |
+
# chosen when multiple such configurations can match the input.
|
| 681 |
+
|
| 682 |
+
skippedStopStates = None
|
| 683 |
+
|
| 684 |
+
# First figure out where we can reach on input t
|
| 685 |
+
for c in closure:
|
| 686 |
+
if ParserATNSimulator.debug:
|
| 687 |
+
print("testing " + self.getTokenName(t) + " at " + str(c))
|
| 688 |
+
|
| 689 |
+
if isinstance(c.state, RuleStopState):
|
| 690 |
+
if fullCtx or t == Token.EOF:
|
| 691 |
+
if skippedStopStates is None:
|
| 692 |
+
skippedStopStates = list()
|
| 693 |
+
skippedStopStates.append(c)
|
| 694 |
+
continue
|
| 695 |
+
|
| 696 |
+
for trans in c.state.transitions:
|
| 697 |
+
target = self.getReachableTarget(trans, t)
|
| 698 |
+
if target is not None:
|
| 699 |
+
intermediate.add(ATNConfig(state=target, config=c), self.mergeCache)
|
| 700 |
+
|
| 701 |
+
# Now figure out where the reach operation can take us...
|
| 702 |
+
|
| 703 |
+
reach = None
|
| 704 |
+
|
| 705 |
+
# This block optimizes the reach operation for intermediate sets which
|
| 706 |
+
# trivially indicate a termination state for the overall
|
| 707 |
+
# adaptivePredict operation.
|
| 708 |
+
#
|
| 709 |
+
# The conditions assume that intermediate
|
| 710 |
+
# contains all configurations relevant to the reach set, but this
|
| 711 |
+
# condition is not true when one or more configurations have been
|
| 712 |
+
# withheld in skippedStopStates, or when the current symbol is EOF.
|
| 713 |
+
#
|
| 714 |
+
if skippedStopStates is None and t!=Token.EOF:
|
| 715 |
+
if len(intermediate)==1:
|
| 716 |
+
# Don't pursue the closure if there is just one state.
|
| 717 |
+
# It can only have one alternative; just add to result
|
| 718 |
+
# Also don't pursue the closure if there is unique alternative
|
| 719 |
+
# among the configurations.
|
| 720 |
+
reach = intermediate
|
| 721 |
+
elif self.getUniqueAlt(intermediate)!=ATN.INVALID_ALT_NUMBER:
|
| 722 |
+
# Also don't pursue the closure if there is unique alternative
|
| 723 |
+
# among the configurations.
|
| 724 |
+
reach = intermediate
|
| 725 |
+
|
| 726 |
+
# If the reach set could not be trivially determined, perform a closure
|
| 727 |
+
# operation on the intermediate set to compute its initial value.
|
| 728 |
+
#
|
| 729 |
+
if reach is None:
|
| 730 |
+
reach = ATNConfigSet(fullCtx)
|
| 731 |
+
closureBusy = set()
|
| 732 |
+
treatEofAsEpsilon = t == Token.EOF
|
| 733 |
+
for c in intermediate:
|
| 734 |
+
self.closure(c, reach, closureBusy, False, fullCtx, treatEofAsEpsilon)
|
| 735 |
+
|
| 736 |
+
if t == Token.EOF:
|
| 737 |
+
# After consuming EOF no additional input is possible, so we are
|
| 738 |
+
# only interested in configurations which reached the end of the
|
| 739 |
+
# decision rule (local context) or end of the start rule (full
|
| 740 |
+
# context). Update reach to contain only these configurations. This
|
| 741 |
+
# handles both explicit EOF transitions in the grammar and implicit
|
| 742 |
+
# EOF transitions following the end of the decision or start rule.
|
| 743 |
+
#
|
| 744 |
+
# When reach==intermediate, no closure operation was performed. In
|
| 745 |
+
# this case, removeAllConfigsNotInRuleStopState needs to check for
|
| 746 |
+
# reachable rule stop states as well as configurations already in
|
| 747 |
+
# a rule stop state.
|
| 748 |
+
#
|
| 749 |
+
# This is handled before the configurations in skippedStopStates,
|
| 750 |
+
# because any configurations potentially added from that list are
|
| 751 |
+
# already guaranteed to meet this condition whether or not it's
|
| 752 |
+
# required.
|
| 753 |
+
#
|
| 754 |
+
reach = self.removeAllConfigsNotInRuleStopState(reach, reach is intermediate)
|
| 755 |
+
|
| 756 |
+
# If skippedStopStates is not null, then it contains at least one
|
| 757 |
+
# configuration. For full-context reach operations, these
|
| 758 |
+
# configurations reached the end of the start rule, in which case we
|
| 759 |
+
# only add them back to reach if no configuration during the current
|
| 760 |
+
# closure operation reached such a state. This ensures adaptivePredict
|
| 761 |
+
# chooses an alternative matching the longest overall sequence when
|
| 762 |
+
# multiple alternatives are viable.
|
| 763 |
+
#
|
| 764 |
+
if skippedStopStates is not None and ( (not fullCtx) or (not PredictionMode.hasConfigInRuleStopState(reach))):
|
| 765 |
+
for c in skippedStopStates:
|
| 766 |
+
reach.add(c, self.mergeCache)
|
| 767 |
+
if len(reach)==0:
|
| 768 |
+
return None
|
| 769 |
+
else:
|
| 770 |
+
return reach
|
| 771 |
+
|
| 772 |
+
#
|
| 773 |
+
# Return a configuration set containing only the configurations from
|
| 774 |
+
# {@code configs} which are in a {@link RuleStopState}. If all
|
| 775 |
+
# configurations in {@code configs} are already in a rule stop state, this
|
| 776 |
+
# method simply returns {@code configs}.
|
| 777 |
+
#
|
| 778 |
+
# <p>When {@code lookToEndOfRule} is true, this method uses
|
| 779 |
+
# {@link ATN#nextTokens} for each configuration in {@code configs} which is
|
| 780 |
+
# not already in a rule stop state to see if a rule stop state is reachable
|
| 781 |
+
# from the configuration via epsilon-only transitions.</p>
|
| 782 |
+
#
|
| 783 |
+
# @param configs the configuration set to update
|
| 784 |
+
# @param lookToEndOfRule when true, this method checks for rule stop states
|
| 785 |
+
# reachable by epsilon-only transitions from each configuration in
|
| 786 |
+
# {@code configs}.
|
| 787 |
+
#
|
| 788 |
+
# @return {@code configs} if all configurations in {@code configs} are in a
|
| 789 |
+
# rule stop state, otherwise return a new configuration set containing only
|
| 790 |
+
# the configurations from {@code configs} which are in a rule stop state
|
| 791 |
+
#
|
| 792 |
+
def removeAllConfigsNotInRuleStopState(self, configs:ATNConfigSet, lookToEndOfRule:bool):
|
| 793 |
+
if PredictionMode.allConfigsInRuleStopStates(configs):
|
| 794 |
+
return configs
|
| 795 |
+
result = ATNConfigSet(configs.fullCtx)
|
| 796 |
+
for config in configs:
|
| 797 |
+
if isinstance(config.state, RuleStopState):
|
| 798 |
+
result.add(config, self.mergeCache)
|
| 799 |
+
continue
|
| 800 |
+
if lookToEndOfRule and config.state.epsilonOnlyTransitions:
|
| 801 |
+
nextTokens = self.atn.nextTokens(config.state)
|
| 802 |
+
if Token.EPSILON in nextTokens:
|
| 803 |
+
endOfRuleState = self.atn.ruleToStopState[config.state.ruleIndex]
|
| 804 |
+
result.add(ATNConfig(state=endOfRuleState, config=config), self.mergeCache)
|
| 805 |
+
return result
|
| 806 |
+
|
| 807 |
+
def computeStartState(self, p:ATNState, ctx:RuleContext, fullCtx:bool):
|
| 808 |
+
# always at least the implicit call to start rule
|
| 809 |
+
initialContext = PredictionContextFromRuleContext(self.atn, ctx)
|
| 810 |
+
configs = ATNConfigSet(fullCtx)
|
| 811 |
+
|
| 812 |
+
for i in range(0, len(p.transitions)):
|
| 813 |
+
target = p.transitions[i].target
|
| 814 |
+
c = ATNConfig(target, i+1, initialContext)
|
| 815 |
+
closureBusy = set()
|
| 816 |
+
self.closure(c, configs, closureBusy, True, fullCtx, False)
|
| 817 |
+
return configs
|
| 818 |
+
|
| 819 |
+
#
|
| 820 |
+
# This method transforms the start state computed by
|
| 821 |
+
# {@link #computeStartState} to the special start state used by a
|
| 822 |
+
# precedence DFA for a particular precedence value. The transformation
|
| 823 |
+
# process applies the following changes to the start state's configuration
|
| 824 |
+
# set.
|
| 825 |
+
#
|
| 826 |
+
# <ol>
|
| 827 |
+
# <li>Evaluate the precedence predicates for each configuration using
|
| 828 |
+
# {@link SemanticContext#evalPrecedence}.</li>
|
| 829 |
+
# <li>Remove all configurations which predict an alternative greater than
|
| 830 |
+
# 1, for which another configuration that predicts alternative 1 is in the
|
| 831 |
+
# same ATN state with the same prediction context. This transformation is
|
| 832 |
+
# valid for the following reasons:
|
| 833 |
+
# <ul>
|
| 834 |
+
# <li>The closure block cannot contain any epsilon transitions which bypass
|
| 835 |
+
# the body of the closure, so all states reachable via alternative 1 are
|
| 836 |
+
# part of the precedence alternatives of the transformed left-recursive
|
| 837 |
+
# rule.</li>
|
| 838 |
+
# <li>The "primary" portion of a left recursive rule cannot contain an
|
| 839 |
+
# epsilon transition, so the only way an alternative other than 1 can exist
|
| 840 |
+
# in a state that is also reachable via alternative 1 is by nesting calls
|
| 841 |
+
# to the left-recursive rule, with the outer calls not being at the
|
| 842 |
+
# preferred precedence level.</li>
|
| 843 |
+
# </ul>
|
| 844 |
+
# </li>
|
| 845 |
+
# </ol>
|
| 846 |
+
#
|
| 847 |
+
# <p>
|
| 848 |
+
# The prediction context must be considered by this filter to address
|
| 849 |
+
# situations like the following.
|
| 850 |
+
# </p>
|
| 851 |
+
# <code>
|
| 852 |
+
# <pre>
|
| 853 |
+
# grammar TA;
|
| 854 |
+
# prog: statement* EOF;
|
| 855 |
+
# statement: letterA | statement letterA 'b' ;
|
| 856 |
+
# letterA: 'a';
|
| 857 |
+
# </pre>
|
| 858 |
+
# </code>
|
| 859 |
+
# <p>
|
| 860 |
+
# If the above grammar, the ATN state immediately before the token
|
| 861 |
+
# reference {@code 'a'} in {@code letterA} is reachable from the left edge
|
| 862 |
+
# of both the primary and closure blocks of the left-recursive rule
|
| 863 |
+
# {@code statement}. The prediction context associated with each of these
|
| 864 |
+
# configurations distinguishes between them, and prevents the alternative
|
| 865 |
+
# which stepped out to {@code prog} (and then back in to {@code statement}
|
| 866 |
+
# from being eliminated by the filter.
|
| 867 |
+
# </p>
|
| 868 |
+
#
|
| 869 |
+
# @param configs The configuration set computed by
|
| 870 |
+
# {@link #computeStartState} as the start state for the DFA.
|
| 871 |
+
# @return The transformed configuration set representing the start state
|
| 872 |
+
# for a precedence DFA at a particular precedence level (determined by
|
| 873 |
+
# calling {@link Parser#getPrecedence}).
|
| 874 |
+
#
|
| 875 |
+
def applyPrecedenceFilter(self, configs:ATNConfigSet):
|
| 876 |
+
statesFromAlt1 = dict()
|
| 877 |
+
configSet = ATNConfigSet(configs.fullCtx)
|
| 878 |
+
for config in configs:
|
| 879 |
+
# handle alt 1 first
|
| 880 |
+
if config.alt != 1:
|
| 881 |
+
continue
|
| 882 |
+
updatedContext = config.semanticContext.evalPrecedence(self.parser, self._outerContext)
|
| 883 |
+
if updatedContext is None:
|
| 884 |
+
# the configuration was eliminated
|
| 885 |
+
continue
|
| 886 |
+
|
| 887 |
+
statesFromAlt1[config.state.stateNumber] = config.context
|
| 888 |
+
if updatedContext is not config.semanticContext:
|
| 889 |
+
configSet.add(ATNConfig(config=config, semantic=updatedContext), self.mergeCache)
|
| 890 |
+
else:
|
| 891 |
+
configSet.add(config, self.mergeCache)
|
| 892 |
+
|
| 893 |
+
for config in configs:
|
| 894 |
+
if config.alt == 1:
|
| 895 |
+
# already handled
|
| 896 |
+
continue
|
| 897 |
+
|
| 898 |
+
# In the future, this elimination step could be updated to also
|
| 899 |
+
# filter the prediction context for alternatives predicting alt>1
|
| 900 |
+
# (basically a graph subtraction algorithm).
|
| 901 |
+
#
|
| 902 |
+
if not config.precedenceFilterSuppressed:
|
| 903 |
+
context = statesFromAlt1.get(config.state.stateNumber, None)
|
| 904 |
+
if context==config.context:
|
| 905 |
+
# eliminated
|
| 906 |
+
continue
|
| 907 |
+
|
| 908 |
+
configSet.add(config, self.mergeCache)
|
| 909 |
+
|
| 910 |
+
return configSet
|
| 911 |
+
|
| 912 |
+
def getReachableTarget(self, trans:Transition, ttype:int):
|
| 913 |
+
if trans.matches(ttype, 0, self.atn.maxTokenType):
|
| 914 |
+
return trans.target
|
| 915 |
+
else:
|
| 916 |
+
return None
|
| 917 |
+
|
| 918 |
+
def getPredsForAmbigAlts(self, ambigAlts:set, configs:ATNConfigSet, nalts:int):
|
| 919 |
+
# REACH=[1|1|[]|0:0, 1|2|[]|0:1]
|
| 920 |
+
# altToPred starts as an array of all null contexts. The entry at index i
|
| 921 |
+
# corresponds to alternative i. altToPred[i] may have one of three values:
|
| 922 |
+
# 1. null: no ATNConfig c is found such that c.alt==i
|
| 923 |
+
# 2. SemanticContext.NONE: At least one ATNConfig c exists such that
|
| 924 |
+
# c.alt==i and c.semanticContext==SemanticContext.NONE. In other words,
|
| 925 |
+
# alt i has at least one unpredicated config.
|
| 926 |
+
# 3. Non-NONE Semantic Context: There exists at least one, and for all
|
| 927 |
+
# ATNConfig c such that c.alt==i, c.semanticContext!=SemanticContext.NONE.
|
| 928 |
+
#
|
| 929 |
+
# From this, it is clear that NONE||anything==NONE.
|
| 930 |
+
#
|
| 931 |
+
altToPred = [None] * (nalts + 1)
|
| 932 |
+
for c in configs:
|
| 933 |
+
if c.alt in ambigAlts:
|
| 934 |
+
altToPred[c.alt] = orContext(altToPred[c.alt], c.semanticContext)
|
| 935 |
+
|
| 936 |
+
nPredAlts = 0
|
| 937 |
+
for i in range(1, nalts+1):
|
| 938 |
+
if altToPred[i] is None:
|
| 939 |
+
altToPred[i] = SemanticContext.NONE
|
| 940 |
+
elif altToPred[i] is not SemanticContext.NONE:
|
| 941 |
+
nPredAlts += 1
|
| 942 |
+
|
| 943 |
+
# nonambig alts are null in altToPred
|
| 944 |
+
if nPredAlts==0:
|
| 945 |
+
altToPred = None
|
| 946 |
+
if ParserATNSimulator.debug:
|
| 947 |
+
print("getPredsForAmbigAlts result " + str_list(altToPred))
|
| 948 |
+
return altToPred
|
| 949 |
+
|
| 950 |
+
def getPredicatePredictions(self, ambigAlts:set, altToPred:list):
|
| 951 |
+
pairs = []
|
| 952 |
+
containsPredicate = False
|
| 953 |
+
for i in range(1, len(altToPred)):
|
| 954 |
+
pred = altToPred[i]
|
| 955 |
+
# unpredicated is indicated by SemanticContext.NONE
|
| 956 |
+
if ambigAlts is not None and i in ambigAlts:
|
| 957 |
+
pairs.append(PredPrediction(pred, i))
|
| 958 |
+
if pred is not SemanticContext.NONE:
|
| 959 |
+
containsPredicate = True
|
| 960 |
+
|
| 961 |
+
if not containsPredicate:
|
| 962 |
+
return None
|
| 963 |
+
|
| 964 |
+
return pairs
|
| 965 |
+
|
| 966 |
+
#
|
| 967 |
+
# This method is used to improve the localization of error messages by
|
| 968 |
+
# choosing an alternative rather than throwing a
|
| 969 |
+
# {@link NoViableAltException} in particular prediction scenarios where the
|
| 970 |
+
# {@link #ERROR} state was reached during ATN simulation.
|
| 971 |
+
#
|
| 972 |
+
# <p>
|
| 973 |
+
# The default implementation of this method uses the following
|
| 974 |
+
# algorithm to identify an ATN configuration which successfully parsed the
|
| 975 |
+
# decision entry rule. Choosing such an alternative ensures that the
|
| 976 |
+
# {@link ParserRuleContext} returned by the calling rule will be complete
|
| 977 |
+
# and valid, and the syntax error will be reported later at a more
|
| 978 |
+
# localized location.</p>
|
| 979 |
+
#
|
| 980 |
+
# <ul>
|
| 981 |
+
# <li>If a syntactically valid path or paths reach the end of the decision rule and
|
| 982 |
+
# they are semantically valid if predicated, return the min associated alt.</li>
|
| 983 |
+
# <li>Else, if a semantically invalid but syntactically valid path exist
|
| 984 |
+
# or paths exist, return the minimum associated alt.
|
| 985 |
+
# </li>
|
| 986 |
+
# <li>Otherwise, return {@link ATN#INVALID_ALT_NUMBER}.</li>
|
| 987 |
+
# </ul>
|
| 988 |
+
#
|
| 989 |
+
# <p>
|
| 990 |
+
# In some scenarios, the algorithm described above could predict an
|
| 991 |
+
# alternative which will result in a {@link FailedPredicateException} in
|
| 992 |
+
# the parser. Specifically, this could occur if the <em>only</em> configuration
|
| 993 |
+
# capable of successfully parsing to the end of the decision rule is
|
| 994 |
+
# blocked by a semantic predicate. By choosing this alternative within
|
| 995 |
+
# {@link #adaptivePredict} instead of throwing a
|
| 996 |
+
# {@link NoViableAltException}, the resulting
|
| 997 |
+
# {@link FailedPredicateException} in the parser will identify the specific
|
| 998 |
+
# predicate which is preventing the parser from successfully parsing the
|
| 999 |
+
# decision rule, which helps developers identify and correct logic errors
|
| 1000 |
+
# in semantic predicates.
|
| 1001 |
+
# </p>
|
| 1002 |
+
#
|
| 1003 |
+
# @param configs The ATN configurations which were valid immediately before
|
| 1004 |
+
# the {@link #ERROR} state was reached
|
| 1005 |
+
# @param outerContext The is the \gamma_0 initial parser context from the paper
|
| 1006 |
+
# or the parser stack at the instant before prediction commences.
|
| 1007 |
+
#
|
| 1008 |
+
# @return The value to return from {@link #adaptivePredict}, or
|
| 1009 |
+
# {@link ATN#INVALID_ALT_NUMBER} if a suitable alternative was not
|
| 1010 |
+
# identified and {@link #adaptivePredict} should report an error instead.
|
| 1011 |
+
#
|
| 1012 |
+
def getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(self, configs:ATNConfigSet, outerContext:ParserRuleContext):
|
| 1013 |
+
semValidConfigs, semInvalidConfigs = self.splitAccordingToSemanticValidity(configs, outerContext)
|
| 1014 |
+
alt = self.getAltThatFinishedDecisionEntryRule(semValidConfigs)
|
| 1015 |
+
if alt!=ATN.INVALID_ALT_NUMBER: # semantically/syntactically viable path exists
|
| 1016 |
+
return alt
|
| 1017 |
+
# Is there a syntactically valid path with a failed pred?
|
| 1018 |
+
if len(semInvalidConfigs)>0:
|
| 1019 |
+
alt = self.getAltThatFinishedDecisionEntryRule(semInvalidConfigs)
|
| 1020 |
+
if alt!=ATN.INVALID_ALT_NUMBER: # syntactically viable path exists
|
| 1021 |
+
return alt
|
| 1022 |
+
return ATN.INVALID_ALT_NUMBER
|
| 1023 |
+
|
| 1024 |
+
def getAltThatFinishedDecisionEntryRule(self, configs:ATNConfigSet):
|
| 1025 |
+
alts = set()
|
| 1026 |
+
for c in configs:
|
| 1027 |
+
if c.reachesIntoOuterContext>0 or (isinstance(c.state, RuleStopState) and c.context.hasEmptyPath() ):
|
| 1028 |
+
alts.add(c.alt)
|
| 1029 |
+
if len(alts)==0:
|
| 1030 |
+
return ATN.INVALID_ALT_NUMBER
|
| 1031 |
+
else:
|
| 1032 |
+
return min(alts)
|
| 1033 |
+
|
| 1034 |
+
# Walk the list of configurations and split them according to
|
| 1035 |
+
# those that have preds evaluating to true/false. If no pred, assume
|
| 1036 |
+
# true pred and include in succeeded set. Returns Pair of sets.
|
| 1037 |
+
#
|
| 1038 |
+
# Create a new set so as not to alter the incoming parameter.
|
| 1039 |
+
#
|
| 1040 |
+
# Assumption: the input stream has been restored to the starting point
|
| 1041 |
+
# prediction, which is where predicates need to evaluate.
|
| 1042 |
+
#
|
| 1043 |
+
def splitAccordingToSemanticValidity(self, configs:ATNConfigSet, outerContext:ParserRuleContext):
|
| 1044 |
+
succeeded = ATNConfigSet(configs.fullCtx)
|
| 1045 |
+
failed = ATNConfigSet(configs.fullCtx)
|
| 1046 |
+
for c in configs:
|
| 1047 |
+
if c.semanticContext is not SemanticContext.NONE:
|
| 1048 |
+
predicateEvaluationResult = c.semanticContext.eval(self.parser, outerContext)
|
| 1049 |
+
if predicateEvaluationResult:
|
| 1050 |
+
succeeded.add(c)
|
| 1051 |
+
else:
|
| 1052 |
+
failed.add(c)
|
| 1053 |
+
else:
|
| 1054 |
+
succeeded.add(c)
|
| 1055 |
+
return (succeeded,failed)
|
| 1056 |
+
|
| 1057 |
+
# Look through a list of predicate/alt pairs, returning alts for the
|
| 1058 |
+
# pairs that win. A {@code NONE} predicate indicates an alt containing an
|
| 1059 |
+
# unpredicated config which behaves as "always true." If !complete
|
| 1060 |
+
# then we stop at the first predicate that evaluates to true. This
|
| 1061 |
+
# includes pairs with null predicates.
|
| 1062 |
+
#
|
| 1063 |
+
def evalSemanticContext(self, predPredictions:list, outerContext:ParserRuleContext, complete:bool):
|
| 1064 |
+
predictions = set()
|
| 1065 |
+
for pair in predPredictions:
|
| 1066 |
+
if pair.pred is SemanticContext.NONE:
|
| 1067 |
+
predictions.add(pair.alt)
|
| 1068 |
+
if not complete:
|
| 1069 |
+
break
|
| 1070 |
+
continue
|
| 1071 |
+
predicateEvaluationResult = pair.pred.eval(self.parser, outerContext)
|
| 1072 |
+
if ParserATNSimulator.debug or ParserATNSimulator.dfa_debug:
|
| 1073 |
+
print("eval pred " + str(pair) + "=" + str(predicateEvaluationResult))
|
| 1074 |
+
|
| 1075 |
+
if predicateEvaluationResult:
|
| 1076 |
+
if ParserATNSimulator.debug or ParserATNSimulator.dfa_debug:
|
| 1077 |
+
print("PREDICT " + str(pair.alt))
|
| 1078 |
+
predictions.add(pair.alt)
|
| 1079 |
+
if not complete:
|
| 1080 |
+
break
|
| 1081 |
+
return predictions
|
| 1082 |
+
|
| 1083 |
+
|
| 1084 |
+
# TODO: If we are doing predicates, there is no point in pursuing
|
| 1085 |
+
# closure operations if we reach a DFA state that uniquely predicts
|
| 1086 |
+
# alternative. We will not be caching that DFA state and it is a
|
| 1087 |
+
# waste to pursue the closure. Might have to advance when we do
|
| 1088 |
+
# ambig detection thought :(
|
| 1089 |
+
#
|
| 1090 |
+
|
| 1091 |
+
def closure(self, config:ATNConfig, configs:ATNConfigSet, closureBusy:set, collectPredicates:bool, fullCtx:bool, treatEofAsEpsilon:bool):
|
| 1092 |
+
initialDepth = 0
|
| 1093 |
+
self.closureCheckingStopState(config, configs, closureBusy, collectPredicates,
|
| 1094 |
+
fullCtx, initialDepth, treatEofAsEpsilon)
|
| 1095 |
+
|
| 1096 |
+
|
| 1097 |
+
def closureCheckingStopState(self, config:ATNConfig, configs:ATNConfigSet, closureBusy:set, collectPredicates:bool, fullCtx:bool, depth:int, treatEofAsEpsilon:bool):
|
| 1098 |
+
if ParserATNSimulator.debug:
|
| 1099 |
+
print("closure(" + str(config) + ")")
|
| 1100 |
+
|
| 1101 |
+
if isinstance(config.state, RuleStopState):
|
| 1102 |
+
# We hit rule end. If we have context info, use it
|
| 1103 |
+
# run thru all possible stack tops in ctx
|
| 1104 |
+
if not config.context.isEmpty():
|
| 1105 |
+
for i in range(0, len(config.context)):
|
| 1106 |
+
state = config.context.getReturnState(i)
|
| 1107 |
+
if state is PredictionContext.EMPTY_RETURN_STATE:
|
| 1108 |
+
if fullCtx:
|
| 1109 |
+
configs.add(ATNConfig(state=config.state, context=PredictionContext.EMPTY, config=config), self.mergeCache)
|
| 1110 |
+
continue
|
| 1111 |
+
else:
|
| 1112 |
+
# we have no context info, just chase follow links (if greedy)
|
| 1113 |
+
if ParserATNSimulator.debug:
|
| 1114 |
+
print("FALLING off rule " + self.getRuleName(config.state.ruleIndex))
|
| 1115 |
+
self.closure_(config, configs, closureBusy, collectPredicates,
|
| 1116 |
+
fullCtx, depth, treatEofAsEpsilon)
|
| 1117 |
+
continue
|
| 1118 |
+
returnState = self.atn.states[state]
|
| 1119 |
+
newContext = config.context.getParent(i) # "pop" return state
|
| 1120 |
+
c = ATNConfig(state=returnState, alt=config.alt, context=newContext, semantic=config.semanticContext)
|
| 1121 |
+
# While we have context to pop back from, we may have
|
| 1122 |
+
# gotten that context AFTER having falling off a rule.
|
| 1123 |
+
# Make sure we track that we are now out of context.
|
| 1124 |
+
c.reachesIntoOuterContext = config.reachesIntoOuterContext
|
| 1125 |
+
self.closureCheckingStopState(c, configs, closureBusy, collectPredicates, fullCtx, depth - 1, treatEofAsEpsilon)
|
| 1126 |
+
return
|
| 1127 |
+
elif fullCtx:
|
| 1128 |
+
# reached end of start rule
|
| 1129 |
+
configs.add(config, self.mergeCache)
|
| 1130 |
+
return
|
| 1131 |
+
else:
|
| 1132 |
+
# else if we have no context info, just chase follow links (if greedy)
|
| 1133 |
+
if ParserATNSimulator.debug:
|
| 1134 |
+
print("FALLING off rule " + self.getRuleName(config.state.ruleIndex))
|
| 1135 |
+
|
| 1136 |
+
self.closure_(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEofAsEpsilon)
|
| 1137 |
+
|
| 1138 |
+
# Do the actual work of walking epsilon edges#
|
| 1139 |
+
def closure_(self, config:ATNConfig, configs:ATNConfigSet, closureBusy:set, collectPredicates:bool, fullCtx:bool, depth:int, treatEofAsEpsilon:bool):
|
| 1140 |
+
p = config.state
|
| 1141 |
+
# optimization
|
| 1142 |
+
if not p.epsilonOnlyTransitions:
|
| 1143 |
+
configs.add(config, self.mergeCache)
|
| 1144 |
+
# make sure to not return here, because EOF transitions can act as
|
| 1145 |
+
# both epsilon transitions and non-epsilon transitions.
|
| 1146 |
+
|
| 1147 |
+
first = True
|
| 1148 |
+
for t in p.transitions:
|
| 1149 |
+
if first:
|
| 1150 |
+
first = False
|
| 1151 |
+
if self.canDropLoopEntryEdgeInLeftRecursiveRule(config):
|
| 1152 |
+
continue
|
| 1153 |
+
|
| 1154 |
+
continueCollecting = collectPredicates and not isinstance(t, ActionTransition)
|
| 1155 |
+
c = self.getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon)
|
| 1156 |
+
if c is not None:
|
| 1157 |
+
newDepth = depth
|
| 1158 |
+
if isinstance( config.state, RuleStopState):
|
| 1159 |
+
# target fell off end of rule; mark resulting c as having dipped into outer context
|
| 1160 |
+
# We can't get here if incoming config was rule stop and we had context
|
| 1161 |
+
# track how far we dip into outer context. Might
|
| 1162 |
+
# come in handy and we avoid evaluating context dependent
|
| 1163 |
+
# preds if this is > 0.
|
| 1164 |
+
if self._dfa is not None and self._dfa.precedenceDfa:
|
| 1165 |
+
if t.outermostPrecedenceReturn == self._dfa.atnStartState.ruleIndex:
|
| 1166 |
+
c.precedenceFilterSuppressed = True
|
| 1167 |
+
c.reachesIntoOuterContext += 1
|
| 1168 |
+
if c in closureBusy:
|
| 1169 |
+
# avoid infinite recursion for right-recursive rules
|
| 1170 |
+
continue
|
| 1171 |
+
closureBusy.add(c)
|
| 1172 |
+
configs.dipsIntoOuterContext = True # TODO: can remove? only care when we add to set per middle of this method
|
| 1173 |
+
newDepth -= 1
|
| 1174 |
+
if ParserATNSimulator.debug:
|
| 1175 |
+
print("dips into outer ctx: " + str(c))
|
| 1176 |
+
else:
|
| 1177 |
+
if not t.isEpsilon:
|
| 1178 |
+
if c in closureBusy:
|
| 1179 |
+
# avoid infinite recursion for EOF* and EOF+
|
| 1180 |
+
continue
|
| 1181 |
+
closureBusy.add(c)
|
| 1182 |
+
if isinstance(t, RuleTransition):
|
| 1183 |
+
# latch when newDepth goes negative - once we step out of the entry context we can't return
|
| 1184 |
+
if newDepth >= 0:
|
| 1185 |
+
newDepth += 1
|
| 1186 |
+
|
| 1187 |
+
self.closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon)
|
| 1188 |
+
|
| 1189 |
+
|
| 1190 |
+
|
| 1191 |
+
# Implements first-edge (loop entry) elimination as an optimization
|
| 1192 |
+
# during closure operations. See antlr/antlr4#1398.
|
| 1193 |
+
#
|
| 1194 |
+
# The optimization is to avoid adding the loop entry config when
|
| 1195 |
+
# the exit path can only lead back to the same
|
| 1196 |
+
# StarLoopEntryState after popping context at the rule end state
|
| 1197 |
+
# (traversing only epsilon edges, so we're still in closure, in
|
| 1198 |
+
# this same rule).
|
| 1199 |
+
#
|
| 1200 |
+
# We need to detect any state that can reach loop entry on
|
| 1201 |
+
# epsilon w/o exiting rule. We don't have to look at FOLLOW
|
| 1202 |
+
# links, just ensure that all stack tops for config refer to key
|
| 1203 |
+
# states in LR rule.
|
| 1204 |
+
#
|
| 1205 |
+
# To verify we are in the right situation we must first check
|
| 1206 |
+
# closure is at a StarLoopEntryState generated during LR removal.
|
| 1207 |
+
# Then we check that each stack top of context is a return state
|
| 1208 |
+
# from one of these cases:
|
| 1209 |
+
#
|
| 1210 |
+
# 1. 'not' expr, '(' type ')' expr. The return state points at loop entry state
|
| 1211 |
+
# 2. expr op expr. The return state is the block end of internal block of (...)*
|
| 1212 |
+
# 3. 'between' expr 'and' expr. The return state of 2nd expr reference.
|
| 1213 |
+
# That state points at block end of internal block of (...)*.
|
| 1214 |
+
# 4. expr '?' expr ':' expr. The return state points at block end,
|
| 1215 |
+
# which points at loop entry state.
|
| 1216 |
+
#
|
| 1217 |
+
# If any is true for each stack top, then closure does not add a
|
| 1218 |
+
# config to the current config set for edge[0], the loop entry branch.
|
| 1219 |
+
#
|
| 1220 |
+
# Conditions fail if any context for the current config is:
|
| 1221 |
+
#
|
| 1222 |
+
# a. empty (we'd fall out of expr to do a global FOLLOW which could
|
| 1223 |
+
# even be to some weird spot in expr) or,
|
| 1224 |
+
# b. lies outside of expr or,
|
| 1225 |
+
# c. lies within expr but at a state not the BlockEndState
|
| 1226 |
+
# generated during LR removal
|
| 1227 |
+
#
|
| 1228 |
+
# Do we need to evaluate predicates ever in closure for this case?
|
| 1229 |
+
#
|
| 1230 |
+
# No. Predicates, including precedence predicates, are only
|
| 1231 |
+
# evaluated when computing a DFA start state. I.e., only before
|
| 1232 |
+
# the lookahead (but not parser) consumes a token.
|
| 1233 |
+
#
|
| 1234 |
+
# There are no epsilon edges allowed in LR rule alt blocks or in
|
| 1235 |
+
# the "primary" part (ID here). If closure is in
|
| 1236 |
+
# StarLoopEntryState any lookahead operation will have consumed a
|
| 1237 |
+
# token as there are no epsilon-paths that lead to
|
| 1238 |
+
# StarLoopEntryState. We do not have to evaluate predicates
|
| 1239 |
+
# therefore if we are in the generated StarLoopEntryState of a LR
|
| 1240 |
+
# rule. Note that when making a prediction starting at that
|
| 1241 |
+
# decision point, decision d=2, compute-start-state performs
|
| 1242 |
+
# closure starting at edges[0], edges[1] emanating from
|
| 1243 |
+
# StarLoopEntryState. That means it is not performing closure on
|
| 1244 |
+
# StarLoopEntryState during compute-start-state.
|
| 1245 |
+
#
|
| 1246 |
+
# How do we know this always gives same prediction answer?
|
| 1247 |
+
#
|
| 1248 |
+
# Without predicates, loop entry and exit paths are ambiguous
|
| 1249 |
+
# upon remaining input +b (in, say, a+b). Either paths lead to
|
| 1250 |
+
# valid parses. Closure can lead to consuming + immediately or by
|
| 1251 |
+
# falling out of this call to expr back into expr and loop back
|
| 1252 |
+
# again to StarLoopEntryState to match +b. In this special case,
|
| 1253 |
+
# we choose the more efficient path, which is to take the bypass
|
| 1254 |
+
# path.
|
| 1255 |
+
#
|
| 1256 |
+
# The lookahead language has not changed because closure chooses
|
| 1257 |
+
# one path over the other. Both paths lead to consuming the same
|
| 1258 |
+
# remaining input during a lookahead operation. If the next token
|
| 1259 |
+
# is an operator, lookahead will enter the choice block with
|
| 1260 |
+
# operators. If it is not, lookahead will exit expr. Same as if
|
| 1261 |
+
# closure had chosen to enter the choice block immediately.
|
| 1262 |
+
#
|
| 1263 |
+
# Closure is examining one config (some loopentrystate, some alt,
|
| 1264 |
+
# context) which means it is considering exactly one alt. Closure
|
| 1265 |
+
# always copies the same alt to any derived configs.
|
| 1266 |
+
#
|
| 1267 |
+
# How do we know this optimization doesn't mess up precedence in
|
| 1268 |
+
# our parse trees?
|
| 1269 |
+
#
|
| 1270 |
+
# Looking through expr from left edge of stat only has to confirm
|
| 1271 |
+
# that an input, say, a+b+c; begins with any valid interpretation
|
| 1272 |
+
# of an expression. The precedence actually doesn't matter when
|
| 1273 |
+
# making a decision in stat seeing through expr. It is only when
|
| 1274 |
+
# parsing rule expr that we must use the precedence to get the
|
| 1275 |
+
# right interpretation and, hence, parse tree.
|
| 1276 |
+
#
|
| 1277 |
+
# @since 4.6
|
| 1278 |
+
#
|
| 1279 |
+
def canDropLoopEntryEdgeInLeftRecursiveRule(self, config):
|
| 1280 |
+
# return False
|
| 1281 |
+
p = config.state
|
| 1282 |
+
# First check to see if we are in StarLoopEntryState generated during
|
| 1283 |
+
# left-recursion elimination. For efficiency, also check if
|
| 1284 |
+
# the context has an empty stack case. If so, it would mean
|
| 1285 |
+
# global FOLLOW so we can't perform optimization
|
| 1286 |
+
# Are we the special loop entry/exit state? or SLL wildcard
|
| 1287 |
+
if p.stateType != ATNState.STAR_LOOP_ENTRY \
|
| 1288 |
+
or not p.isPrecedenceDecision \
|
| 1289 |
+
or config.context.isEmpty() \
|
| 1290 |
+
or config.context.hasEmptyPath():
|
| 1291 |
+
return False
|
| 1292 |
+
|
| 1293 |
+
# Require all return states to return back to the same rule
|
| 1294 |
+
# that p is in.
|
| 1295 |
+
numCtxs = len(config.context)
|
| 1296 |
+
for i in range(0, numCtxs): # for each stack context
|
| 1297 |
+
returnState = self.atn.states[config.context.getReturnState(i)]
|
| 1298 |
+
if returnState.ruleIndex != p.ruleIndex:
|
| 1299 |
+
return False
|
| 1300 |
+
|
| 1301 |
+
decisionStartState = p.transitions[0].target
|
| 1302 |
+
blockEndStateNum = decisionStartState.endState.stateNumber
|
| 1303 |
+
blockEndState = self.atn.states[blockEndStateNum]
|
| 1304 |
+
|
| 1305 |
+
# Verify that the top of each stack context leads to loop entry/exit
|
| 1306 |
+
# state through epsilon edges and w/o leaving rule.
|
| 1307 |
+
for i in range(0, numCtxs): # for each stack context
|
| 1308 |
+
returnStateNumber = config.context.getReturnState(i)
|
| 1309 |
+
returnState = self.atn.states[returnStateNumber]
|
| 1310 |
+
# all states must have single outgoing epsilon edge
|
| 1311 |
+
if len(returnState.transitions) != 1 or not returnState.transitions[0].isEpsilon:
|
| 1312 |
+
return False
|
| 1313 |
+
|
| 1314 |
+
# Look for prefix op case like 'not expr', (' type ')' expr
|
| 1315 |
+
returnStateTarget = returnState.transitions[0].target
|
| 1316 |
+
if returnState.stateType == ATNState.BLOCK_END and returnStateTarget is p:
|
| 1317 |
+
continue
|
| 1318 |
+
|
| 1319 |
+
# Look for 'expr op expr' or case where expr's return state is block end
|
| 1320 |
+
# of (...)* internal block; the block end points to loop back
|
| 1321 |
+
# which points to p but we don't need to check that
|
| 1322 |
+
if returnState is blockEndState:
|
| 1323 |
+
continue
|
| 1324 |
+
|
| 1325 |
+
# Look for ternary expr ? expr : expr. The return state points at block end,
|
| 1326 |
+
# which points at loop entry state
|
| 1327 |
+
if returnStateTarget is blockEndState:
|
| 1328 |
+
continue
|
| 1329 |
+
|
| 1330 |
+
# Look for complex prefix 'between expr and expr' case where 2nd expr's
|
| 1331 |
+
# return state points at block end state of (...)* internal block
|
| 1332 |
+
if returnStateTarget.stateType == ATNState.BLOCK_END \
|
| 1333 |
+
and len(returnStateTarget.transitions) == 1 \
|
| 1334 |
+
and returnStateTarget.transitions[0].isEpsilon \
|
| 1335 |
+
and returnStateTarget.transitions[0].target is p:
|
| 1336 |
+
continue
|
| 1337 |
+
|
| 1338 |
+
# anything else ain't conforming
|
| 1339 |
+
return False
|
| 1340 |
+
|
| 1341 |
+
return True
|
| 1342 |
+
|
| 1343 |
+
|
| 1344 |
+
def getRuleName(self, index:int):
|
| 1345 |
+
if self.parser is not None and index>=0:
|
| 1346 |
+
return self.parser.ruleNames[index]
|
| 1347 |
+
else:
|
| 1348 |
+
return "<rule " + str(index) + ">"
|
| 1349 |
+
|
| 1350 |
+
epsilonTargetMethods = dict()
|
| 1351 |
+
epsilonTargetMethods[Transition.RULE] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1352 |
+
sim.ruleTransition(config, t)
|
| 1353 |
+
epsilonTargetMethods[Transition.PRECEDENCE] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1354 |
+
sim.precedenceTransition(config, t, collectPredicates, inContext, fullCtx)
|
| 1355 |
+
epsilonTargetMethods[Transition.PREDICATE] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1356 |
+
sim.predTransition(config, t, collectPredicates, inContext, fullCtx)
|
| 1357 |
+
epsilonTargetMethods[Transition.ACTION] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1358 |
+
sim.actionTransition(config, t)
|
| 1359 |
+
epsilonTargetMethods[Transition.EPSILON] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1360 |
+
ATNConfig(state=t.target, config=config)
|
| 1361 |
+
epsilonTargetMethods[Transition.ATOM] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1362 |
+
ATNConfig(state=t.target, config=config) if treatEofAsEpsilon and t.matches(Token.EOF, 0, 1) else None
|
| 1363 |
+
epsilonTargetMethods[Transition.RANGE] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1364 |
+
ATNConfig(state=t.target, config=config) if treatEofAsEpsilon and t.matches(Token.EOF, 0, 1) else None
|
| 1365 |
+
epsilonTargetMethods[Transition.SET] = lambda sim, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon: \
|
| 1366 |
+
ATNConfig(state=t.target, config=config) if treatEofAsEpsilon and t.matches(Token.EOF, 0, 1) else None
|
| 1367 |
+
|
| 1368 |
+
def getEpsilonTarget(self, config:ATNConfig, t:Transition, collectPredicates:bool, inContext:bool, fullCtx:bool, treatEofAsEpsilon:bool):
|
| 1369 |
+
m = self.epsilonTargetMethods.get(t.serializationType, None)
|
| 1370 |
+
if m is None:
|
| 1371 |
+
return None
|
| 1372 |
+
else:
|
| 1373 |
+
return m(self, config, t, collectPredicates, inContext, fullCtx, treatEofAsEpsilon)
|
| 1374 |
+
|
| 1375 |
+
def actionTransition(self, config:ATNConfig, t:ActionTransition):
|
| 1376 |
+
if ParserATNSimulator.debug:
|
| 1377 |
+
print("ACTION edge " + str(t.ruleIndex) + ":" + str(t.actionIndex))
|
| 1378 |
+
return ATNConfig(state=t.target, config=config)
|
| 1379 |
+
|
| 1380 |
+
def precedenceTransition(self, config:ATNConfig, pt:PrecedencePredicateTransition, collectPredicates:bool, inContext:bool, fullCtx:bool):
|
| 1381 |
+
if ParserATNSimulator.debug:
|
| 1382 |
+
print("PRED (collectPredicates=" + str(collectPredicates) + ") " +
|
| 1383 |
+
str(pt.precedence) + ">=_p, ctx dependent=true")
|
| 1384 |
+
if self.parser is not None:
|
| 1385 |
+
print("context surrounding pred is " + str(self.parser.getRuleInvocationStack()))
|
| 1386 |
+
|
| 1387 |
+
c = None
|
| 1388 |
+
if collectPredicates and inContext:
|
| 1389 |
+
if fullCtx:
|
| 1390 |
+
# In full context mode, we can evaluate predicates on-the-fly
|
| 1391 |
+
# during closure, which dramatically reduces the size of
|
| 1392 |
+
# the config sets. It also obviates the need to test predicates
|
| 1393 |
+
# later during conflict resolution.
|
| 1394 |
+
currentPosition = self._input.index
|
| 1395 |
+
self._input.seek(self._startIndex)
|
| 1396 |
+
predSucceeds = pt.getPredicate().eval(self.parser, self._outerContext)
|
| 1397 |
+
self._input.seek(currentPosition)
|
| 1398 |
+
if predSucceeds:
|
| 1399 |
+
c = ATNConfig(state=pt.target, config=config) # no pred context
|
| 1400 |
+
else:
|
| 1401 |
+
newSemCtx = andContext(config.semanticContext, pt.getPredicate())
|
| 1402 |
+
c = ATNConfig(state=pt.target, semantic=newSemCtx, config=config)
|
| 1403 |
+
else:
|
| 1404 |
+
c = ATNConfig(state=pt.target, config=config)
|
| 1405 |
+
|
| 1406 |
+
if ParserATNSimulator.debug:
|
| 1407 |
+
print("config from pred transition=" + str(c))
|
| 1408 |
+
return c
|
| 1409 |
+
|
| 1410 |
+
def predTransition(self, config:ATNConfig, pt:PredicateTransition, collectPredicates:bool, inContext:bool, fullCtx:bool):
|
| 1411 |
+
if ParserATNSimulator.debug:
|
| 1412 |
+
print("PRED (collectPredicates=" + str(collectPredicates) + ") " + str(pt.ruleIndex) +
|
| 1413 |
+
":" + str(pt.predIndex) + ", ctx dependent=" + str(pt.isCtxDependent))
|
| 1414 |
+
if self.parser is not None:
|
| 1415 |
+
print("context surrounding pred is " + str(self.parser.getRuleInvocationStack()))
|
| 1416 |
+
|
| 1417 |
+
c = None
|
| 1418 |
+
if collectPredicates and (not pt.isCtxDependent or (pt.isCtxDependent and inContext)):
|
| 1419 |
+
if fullCtx:
|
| 1420 |
+
# In full context mode, we can evaluate predicates on-the-fly
|
| 1421 |
+
# during closure, which dramatically reduces the size of
|
| 1422 |
+
# the config sets. It also obviates the need to test predicates
|
| 1423 |
+
# later during conflict resolution.
|
| 1424 |
+
currentPosition = self._input.index
|
| 1425 |
+
self._input.seek(self._startIndex)
|
| 1426 |
+
predSucceeds = pt.getPredicate().eval(self.parser, self._outerContext)
|
| 1427 |
+
self._input.seek(currentPosition)
|
| 1428 |
+
if predSucceeds:
|
| 1429 |
+
c = ATNConfig(state=pt.target, config=config) # no pred context
|
| 1430 |
+
else:
|
| 1431 |
+
newSemCtx = andContext(config.semanticContext, pt.getPredicate())
|
| 1432 |
+
c = ATNConfig(state=pt.target, semantic=newSemCtx, config=config)
|
| 1433 |
+
else:
|
| 1434 |
+
c = ATNConfig(state=pt.target, config=config)
|
| 1435 |
+
|
| 1436 |
+
if ParserATNSimulator.debug:
|
| 1437 |
+
print("config from pred transition=" + str(c))
|
| 1438 |
+
return c
|
| 1439 |
+
|
| 1440 |
+
def ruleTransition(self, config:ATNConfig, t:RuleTransition):
|
| 1441 |
+
if ParserATNSimulator.debug:
|
| 1442 |
+
print("CALL rule " + self.getRuleName(t.target.ruleIndex) + ", ctx=" + str(config.context))
|
| 1443 |
+
returnState = t.followState
|
| 1444 |
+
newContext = SingletonPredictionContext.create(config.context, returnState.stateNumber)
|
| 1445 |
+
return ATNConfig(state=t.target, context=newContext, config=config )
|
| 1446 |
+
|
| 1447 |
+
def getConflictingAlts(self, configs:ATNConfigSet):
|
| 1448 |
+
altsets = PredictionMode.getConflictingAltSubsets(configs)
|
| 1449 |
+
return PredictionMode.getAlts(altsets)
|
| 1450 |
+
|
| 1451 |
+
# Sam pointed out a problem with the previous definition, v3, of
|
| 1452 |
+
# ambiguous states. If we have another state associated with conflicting
|
| 1453 |
+
# alternatives, we should keep going. For example, the following grammar
|
| 1454 |
+
#
|
| 1455 |
+
# s : (ID | ID ID?) ';' ;
|
| 1456 |
+
#
|
| 1457 |
+
# When the ATN simulation reaches the state before ';', it has a DFA
|
| 1458 |
+
# state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally
|
| 1459 |
+
# 12|1|[] and 12|2|[] conflict, but we cannot stop processing this node
|
| 1460 |
+
# because alternative to has another way to continue, via [6|2|[]].
|
| 1461 |
+
# The key is that we have a single state that has config's only associated
|
| 1462 |
+
# with a single alternative, 2, and crucially the state transitions
|
| 1463 |
+
# among the configurations are all non-epsilon transitions. That means
|
| 1464 |
+
# we don't consider any conflicts that include alternative 2. So, we
|
| 1465 |
+
# ignore the conflict between alts 1 and 2. We ignore a set of
|
| 1466 |
+
# conflicting alts when there is an intersection with an alternative
|
| 1467 |
+
# associated with a single alt state in the state→config-list map.
|
| 1468 |
+
#
|
| 1469 |
+
# It's also the case that we might have two conflicting configurations but
|
| 1470 |
+
# also a 3rd nonconflicting configuration for a different alternative:
|
| 1471 |
+
# [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar:
|
| 1472 |
+
#
|
| 1473 |
+
# a : A | A | A B ;
|
| 1474 |
+
#
|
| 1475 |
+
# After matching input A, we reach the stop state for rule A, state 1.
|
| 1476 |
+
# State 8 is the state right before B. Clearly alternatives 1 and 2
|
| 1477 |
+
# conflict and no amount of further lookahead will separate the two.
|
| 1478 |
+
# However, alternative 3 will be able to continue and so we do not
|
| 1479 |
+
# stop working on this state. In the previous example, we're concerned
|
| 1480 |
+
# with states associated with the conflicting alternatives. Here alt
|
| 1481 |
+
# 3 is not associated with the conflicting configs, but since we can continue
|
| 1482 |
+
# looking for input reasonably, I don't declare the state done. We
|
| 1483 |
+
# ignore a set of conflicting alts when we have an alternative
|
| 1484 |
+
# that we still need to pursue.
|
| 1485 |
+
#
|
| 1486 |
+
|
| 1487 |
+
def getConflictingAltsOrUniqueAlt(self, configs:ATNConfigSet):
|
| 1488 |
+
conflictingAlts = None
|
| 1489 |
+
if configs.uniqueAlt!= ATN.INVALID_ALT_NUMBER:
|
| 1490 |
+
conflictingAlts = set()
|
| 1491 |
+
conflictingAlts.add(configs.uniqueAlt)
|
| 1492 |
+
else:
|
| 1493 |
+
conflictingAlts = configs.conflictingAlts
|
| 1494 |
+
return conflictingAlts
|
| 1495 |
+
|
| 1496 |
+
def getTokenName(self, t:int):
|
| 1497 |
+
if t==Token.EOF:
|
| 1498 |
+
return "EOF"
|
| 1499 |
+
if self.parser is not None and \
|
| 1500 |
+
self.parser.literalNames is not None and \
|
| 1501 |
+
t < len(self.parser.literalNames):
|
| 1502 |
+
return self.parser.literalNames[t] + "<" + str(t) + ">"
|
| 1503 |
+
else:
|
| 1504 |
+
return str(t)
|
| 1505 |
+
|
| 1506 |
+
def getLookaheadName(self, input:TokenStream):
|
| 1507 |
+
return self.getTokenName(input.LA(1))
|
| 1508 |
+
|
| 1509 |
+
# Used for debugging in adaptivePredict around execATN but I cut
|
| 1510 |
+
# it out for clarity now that alg. works well. We can leave this
|
| 1511 |
+
# "dead" code for a bit.
|
| 1512 |
+
#
|
| 1513 |
+
def dumpDeadEndConfigs(self, nvae:NoViableAltException):
|
| 1514 |
+
print("dead end configs: ")
|
| 1515 |
+
for c in nvae.getDeadEndConfigs():
|
| 1516 |
+
trans = "no edges"
|
| 1517 |
+
if len(c.state.transitions)>0:
|
| 1518 |
+
t = c.state.transitions[0]
|
| 1519 |
+
if isinstance(t, AtomTransition):
|
| 1520 |
+
trans = "Atom "+ self.getTokenName(t.label)
|
| 1521 |
+
elif isinstance(t, SetTransition):
|
| 1522 |
+
neg = isinstance(t, NotSetTransition)
|
| 1523 |
+
trans = ("~" if neg else "")+"Set "+ str(t.set)
|
| 1524 |
+
print(c.toString(self.parser, True) + ":" + trans, file=sys.stderr)
|
| 1525 |
+
|
| 1526 |
+
def noViableAlt(self, input:TokenStream, outerContext:ParserRuleContext, configs:ATNConfigSet, startIndex:int):
|
| 1527 |
+
return NoViableAltException(self.parser, input, input.get(startIndex), input.LT(1), configs, outerContext)
|
| 1528 |
+
|
| 1529 |
+
def getUniqueAlt(self, configs:ATNConfigSet):
|
| 1530 |
+
alt = ATN.INVALID_ALT_NUMBER
|
| 1531 |
+
for c in configs:
|
| 1532 |
+
if alt == ATN.INVALID_ALT_NUMBER:
|
| 1533 |
+
alt = c.alt # found first alt
|
| 1534 |
+
elif c.alt!=alt:
|
| 1535 |
+
return ATN.INVALID_ALT_NUMBER
|
| 1536 |
+
return alt
|
| 1537 |
+
|
| 1538 |
+
#
|
| 1539 |
+
# Add an edge to the DFA, if possible. This method calls
|
| 1540 |
+
# {@link #addDFAState} to ensure the {@code to} state is present in the
|
| 1541 |
+
# DFA. If {@code from} is {@code null}, or if {@code t} is outside the
|
| 1542 |
+
# range of edges that can be represented in the DFA tables, this method
|
| 1543 |
+
# returns without adding the edge to the DFA.
|
| 1544 |
+
#
|
| 1545 |
+
# <p>If {@code to} is {@code null}, this method returns {@code null}.
|
| 1546 |
+
# Otherwise, this method returns the {@link DFAState} returned by calling
|
| 1547 |
+
# {@link #addDFAState} for the {@code to} state.</p>
|
| 1548 |
+
#
|
| 1549 |
+
# @param dfa The DFA
|
| 1550 |
+
# @param from The source state for the edge
|
| 1551 |
+
# @param t The input symbol
|
| 1552 |
+
# @param to The target state for the edge
|
| 1553 |
+
#
|
| 1554 |
+
# @return If {@code to} is {@code null}, this method returns {@code null};
|
| 1555 |
+
# otherwise this method returns the result of calling {@link #addDFAState}
|
| 1556 |
+
# on {@code to}
|
| 1557 |
+
#
|
| 1558 |
+
def addDFAEdge(self, dfa:DFA, from_:DFAState, t:int, to:DFAState):
|
| 1559 |
+
if ParserATNSimulator.debug:
|
| 1560 |
+
print("EDGE " + str(from_) + " -> " + str(to) + " upon " + self.getTokenName(t))
|
| 1561 |
+
|
| 1562 |
+
if to is None:
|
| 1563 |
+
return None
|
| 1564 |
+
|
| 1565 |
+
to = self.addDFAState(dfa, to) # used existing if possible not incoming
|
| 1566 |
+
if from_ is None or t < -1 or t > self.atn.maxTokenType:
|
| 1567 |
+
return to
|
| 1568 |
+
|
| 1569 |
+
if from_.edges is None:
|
| 1570 |
+
from_.edges = [None] * (self.atn.maxTokenType + 2)
|
| 1571 |
+
from_.edges[t+1] = to # connect
|
| 1572 |
+
|
| 1573 |
+
if ParserATNSimulator.debug:
|
| 1574 |
+
names = None if self.parser is None else self.parser.literalNames
|
| 1575 |
+
print("DFA=\n" + dfa.toString(names))
|
| 1576 |
+
|
| 1577 |
+
return to
|
| 1578 |
+
|
| 1579 |
+
#
|
| 1580 |
+
# Add state {@code D} to the DFA if it is not already present, and return
|
| 1581 |
+
# the actual instance stored in the DFA. If a state equivalent to {@code D}
|
| 1582 |
+
# is already in the DFA, the existing state is returned. Otherwise this
|
| 1583 |
+
# method returns {@code D} after adding it to the DFA.
|
| 1584 |
+
#
|
| 1585 |
+
# <p>If {@code D} is {@link #ERROR}, this method returns {@link #ERROR} and
|
| 1586 |
+
# does not change the DFA.</p>
|
| 1587 |
+
#
|
| 1588 |
+
# @param dfa The dfa
|
| 1589 |
+
# @param D The DFA state to add
|
| 1590 |
+
# @return The state stored in the DFA. This will be either the existing
|
| 1591 |
+
# state if {@code D} is already in the DFA, or {@code D} itself if the
|
| 1592 |
+
# state was not already present.
|
| 1593 |
+
#
|
| 1594 |
+
def addDFAState(self, dfa:DFA, D:DFAState):
|
| 1595 |
+
if D is self.ERROR:
|
| 1596 |
+
return D
|
| 1597 |
+
|
| 1598 |
+
|
| 1599 |
+
existing = dfa.states.get(D, None)
|
| 1600 |
+
if existing is not None:
|
| 1601 |
+
return existing
|
| 1602 |
+
|
| 1603 |
+
D.stateNumber = len(dfa.states)
|
| 1604 |
+
if not D.configs.readonly:
|
| 1605 |
+
D.configs.optimizeConfigs(self)
|
| 1606 |
+
D.configs.setReadonly(True)
|
| 1607 |
+
dfa.states[D] = D
|
| 1608 |
+
if ParserATNSimulator.debug:
|
| 1609 |
+
print("adding new DFA state: " + str(D))
|
| 1610 |
+
return D
|
| 1611 |
+
|
| 1612 |
+
def reportAttemptingFullContext(self, dfa:DFA, conflictingAlts:set, configs:ATNConfigSet, startIndex:int, stopIndex:int):
|
| 1613 |
+
if ParserATNSimulator.debug or ParserATNSimulator.retry_debug:
|
| 1614 |
+
print("reportAttemptingFullContext decision=" + str(dfa.decision) + ":" + str(configs) +
|
| 1615 |
+
", input=" + self.parser.getTokenStream().getText(startIndex, stopIndex))
|
| 1616 |
+
if self.parser is not None:
|
| 1617 |
+
self.parser.getErrorListenerDispatch().reportAttemptingFullContext(self.parser, dfa, startIndex, stopIndex, conflictingAlts, configs)
|
| 1618 |
+
|
| 1619 |
+
def reportContextSensitivity(self, dfa:DFA, prediction:int, configs:ATNConfigSet, startIndex:int, stopIndex:int):
|
| 1620 |
+
if ParserATNSimulator.debug or ParserATNSimulator.retry_debug:
|
| 1621 |
+
print("reportContextSensitivity decision=" + str(dfa.decision) + ":" + str(configs) +
|
| 1622 |
+
", input=" + self.parser.getTokenStream().getText(startIndex, stopIndex))
|
| 1623 |
+
if self.parser is not None:
|
| 1624 |
+
self.parser.getErrorListenerDispatch().reportContextSensitivity(self.parser, dfa, startIndex, stopIndex, prediction, configs)
|
| 1625 |
+
|
| 1626 |
+
# If context sensitive parsing, we know it's ambiguity not conflict#
|
| 1627 |
+
def reportAmbiguity(self, dfa:DFA, D:DFAState, startIndex:int, stopIndex:int,
|
| 1628 |
+
exact:bool, ambigAlts:set, configs:ATNConfigSet ):
|
| 1629 |
+
if ParserATNSimulator.debug or ParserATNSimulator.retry_debug:
|
| 1630 |
+
# ParserATNPathFinder finder = new ParserATNPathFinder(parser, atn);
|
| 1631 |
+
# int i = 1;
|
| 1632 |
+
# for (Transition t : dfa.atnStartState.transitions) {
|
| 1633 |
+
# print("ALT "+i+"=");
|
| 1634 |
+
# print(startIndex+".."+stopIndex+", len(input)="+parser.getInputStream().size());
|
| 1635 |
+
# TraceTree path = finder.trace(t.target, parser.getContext(), (TokenStream)parser.getInputStream(),
|
| 1636 |
+
# startIndex, stopIndex);
|
| 1637 |
+
# if ( path!=null ) {
|
| 1638 |
+
# print("path = "+path.toStringTree());
|
| 1639 |
+
# for (TraceTree leaf : path.leaves) {
|
| 1640 |
+
# List<ATNState> states = path.getPathToNode(leaf);
|
| 1641 |
+
# print("states="+states);
|
| 1642 |
+
# }
|
| 1643 |
+
# }
|
| 1644 |
+
# i++;
|
| 1645 |
+
# }
|
| 1646 |
+
print("reportAmbiguity " + str(ambigAlts) + ":" + str(configs) +
|
| 1647 |
+
", input=" + self.parser.getTokenStream().getText(startIndex, stopIndex))
|
| 1648 |
+
if self.parser is not None:
|
| 1649 |
+
self.parser.getErrorListenerDispatch().reportAmbiguity(self.parser, dfa, startIndex, stopIndex, exact, ambigAlts, configs)
|
cameras/deps/antlr4/atn/PredictionMode.py
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
#
|
| 7 |
+
# This enumeration defines the prediction modes available in ANTLR 4 along with
|
| 8 |
+
# utility methods for analyzing configuration sets for conflicts and/or
|
| 9 |
+
# ambiguities.
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
from enum import Enum
|
| 13 |
+
from antlr4.atn.ATN import ATN
|
| 14 |
+
from antlr4.atn.ATNConfig import ATNConfig
|
| 15 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet
|
| 16 |
+
from antlr4.atn.ATNState import RuleStopState
|
| 17 |
+
from antlr4.atn.SemanticContext import SemanticContext
|
| 18 |
+
|
| 19 |
+
PredictionMode = None
|
| 20 |
+
|
| 21 |
+
class PredictionMode(Enum):
|
| 22 |
+
#
|
| 23 |
+
# The SLL(*) prediction mode. This prediction mode ignores the current
|
| 24 |
+
# parser context when making predictions. This is the fastest prediction
|
| 25 |
+
# mode, and provides correct results for many grammars. This prediction
|
| 26 |
+
# mode is more powerful than the prediction mode provided by ANTLR 3, but
|
| 27 |
+
# may result in syntax errors for grammar and input combinations which are
|
| 28 |
+
# not SLL.
|
| 29 |
+
#
|
| 30 |
+
# <p>
|
| 31 |
+
# When using this prediction mode, the parser will either return a correct
|
| 32 |
+
# parse tree (i.e. the same parse tree that would be returned with the
|
| 33 |
+
# {@link #LL} prediction mode), or it will report a syntax error. If a
|
| 34 |
+
# syntax error is encountered when using the {@link #SLL} prediction mode,
|
| 35 |
+
# it may be due to either an actual syntax error in the input or indicate
|
| 36 |
+
# that the particular combination of grammar and input requires the more
|
| 37 |
+
# powerful {@link #LL} prediction abilities to complete successfully.</p>
|
| 38 |
+
#
|
| 39 |
+
# <p>
|
| 40 |
+
# This prediction mode does not provide any guarantees for prediction
|
| 41 |
+
# behavior for syntactically-incorrect inputs.</p>
|
| 42 |
+
#
|
| 43 |
+
SLL = 0
|
| 44 |
+
#
|
| 45 |
+
# The LL(*) prediction mode. This prediction mode allows the current parser
|
| 46 |
+
# context to be used for resolving SLL conflicts that occur during
|
| 47 |
+
# prediction. This is the fastest prediction mode that guarantees correct
|
| 48 |
+
# parse results for all combinations of grammars with syntactically correct
|
| 49 |
+
# inputs.
|
| 50 |
+
#
|
| 51 |
+
# <p>
|
| 52 |
+
# When using this prediction mode, the parser will make correct decisions
|
| 53 |
+
# for all syntactically-correct grammar and input combinations. However, in
|
| 54 |
+
# cases where the grammar is truly ambiguous this prediction mode might not
|
| 55 |
+
# report a precise answer for <em>exactly which</em> alternatives are
|
| 56 |
+
# ambiguous.</p>
|
| 57 |
+
#
|
| 58 |
+
# <p>
|
| 59 |
+
# This prediction mode does not provide any guarantees for prediction
|
| 60 |
+
# behavior for syntactically-incorrect inputs.</p>
|
| 61 |
+
#
|
| 62 |
+
LL = 1
|
| 63 |
+
#
|
| 64 |
+
# The LL(*) prediction mode with exact ambiguity detection. In addition to
|
| 65 |
+
# the correctness guarantees provided by the {@link #LL} prediction mode,
|
| 66 |
+
# this prediction mode instructs the prediction algorithm to determine the
|
| 67 |
+
# complete and exact set of ambiguous alternatives for every ambiguous
|
| 68 |
+
# decision encountered while parsing.
|
| 69 |
+
#
|
| 70 |
+
# <p>
|
| 71 |
+
# This prediction mode may be used for diagnosing ambiguities during
|
| 72 |
+
# grammar development. Due to the performance overhead of calculating sets
|
| 73 |
+
# of ambiguous alternatives, this prediction mode should be avoided when
|
| 74 |
+
# the exact results are not necessary.</p>
|
| 75 |
+
#
|
| 76 |
+
# <p>
|
| 77 |
+
# This prediction mode does not provide any guarantees for prediction
|
| 78 |
+
# behavior for syntactically-incorrect inputs.</p>
|
| 79 |
+
#
|
| 80 |
+
LL_EXACT_AMBIG_DETECTION = 2
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
#
|
| 84 |
+
# Computes the SLL prediction termination condition.
|
| 85 |
+
#
|
| 86 |
+
# <p>
|
| 87 |
+
# This method computes the SLL prediction termination condition for both of
|
| 88 |
+
# the following cases.</p>
|
| 89 |
+
#
|
| 90 |
+
# <ul>
|
| 91 |
+
# <li>The usual SLL+LL fallback upon SLL conflict</li>
|
| 92 |
+
# <li>Pure SLL without LL fallback</li>
|
| 93 |
+
# </ul>
|
| 94 |
+
#
|
| 95 |
+
# <p><strong>COMBINED SLL+LL PARSING</strong></p>
|
| 96 |
+
#
|
| 97 |
+
# <p>When LL-fallback is enabled upon SLL conflict, correct predictions are
|
| 98 |
+
# ensured regardless of how the termination condition is computed by this
|
| 99 |
+
# method. Due to the substantially higher cost of LL prediction, the
|
| 100 |
+
# prediction should only fall back to LL when the additional lookahead
|
| 101 |
+
# cannot lead to a unique SLL prediction.</p>
|
| 102 |
+
#
|
| 103 |
+
# <p>Assuming combined SLL+LL parsing, an SLL configuration set with only
|
| 104 |
+
# conflicting subsets should fall back to full LL, even if the
|
| 105 |
+
# configuration sets don't resolve to the same alternative (e.g.
|
| 106 |
+
# {@code {1,2}} and {@code {3,4}}. If there is at least one non-conflicting
|
| 107 |
+
# configuration, SLL could continue with the hopes that more lookahead will
|
| 108 |
+
# resolve via one of those non-conflicting configurations.</p>
|
| 109 |
+
#
|
| 110 |
+
# <p>Here's the prediction termination rule them: SLL (for SLL+LL parsing)
|
| 111 |
+
# stops when it sees only conflicting configuration subsets. In contrast,
|
| 112 |
+
# full LL keeps going when there is uncertainty.</p>
|
| 113 |
+
#
|
| 114 |
+
# <p><strong>HEURISTIC</strong></p>
|
| 115 |
+
#
|
| 116 |
+
# <p>As a heuristic, we stop prediction when we see any conflicting subset
|
| 117 |
+
# unless we see a state that only has one alternative associated with it.
|
| 118 |
+
# The single-alt-state thing lets prediction continue upon rules like
|
| 119 |
+
# (otherwise, it would admit defeat too soon):</p>
|
| 120 |
+
#
|
| 121 |
+
# <p>{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ';' ;}</p>
|
| 122 |
+
#
|
| 123 |
+
# <p>When the ATN simulation reaches the state before {@code ';'}, it has a
|
| 124 |
+
# DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally
|
| 125 |
+
# {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop
|
| 126 |
+
# processing this node because alternative to has another way to continue,
|
| 127 |
+
# via {@code [6|2|[]]}.</p>
|
| 128 |
+
#
|
| 129 |
+
# <p>It also let's us continue for this rule:</p>
|
| 130 |
+
#
|
| 131 |
+
# <p>{@code [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B ;}</p>
|
| 132 |
+
#
|
| 133 |
+
# <p>After matching input A, we reach the stop state for rule A, state 1.
|
| 134 |
+
# State 8 is the state right before B. Clearly alternatives 1 and 2
|
| 135 |
+
# conflict and no amount of further lookahead will separate the two.
|
| 136 |
+
# However, alternative 3 will be able to continue and so we do not stop
|
| 137 |
+
# working on this state. In the previous example, we're concerned with
|
| 138 |
+
# states associated with the conflicting alternatives. Here alt 3 is not
|
| 139 |
+
# associated with the conflicting configs, but since we can continue
|
| 140 |
+
# looking for input reasonably, don't declare the state done.</p>
|
| 141 |
+
#
|
| 142 |
+
# <p><strong>PURE SLL PARSING</strong></p>
|
| 143 |
+
#
|
| 144 |
+
# <p>To handle pure SLL parsing, all we have to do is make sure that we
|
| 145 |
+
# combine stack contexts for configurations that differ only by semantic
|
| 146 |
+
# predicate. From there, we can do the usual SLL termination heuristic.</p>
|
| 147 |
+
#
|
| 148 |
+
# <p><strong>PREDICATES IN SLL+LL PARSING</strong></p>
|
| 149 |
+
#
|
| 150 |
+
# <p>SLL decisions don't evaluate predicates until after they reach DFA stop
|
| 151 |
+
# states because they need to create the DFA cache that works in all
|
| 152 |
+
# semantic situations. In contrast, full LL evaluates predicates collected
|
| 153 |
+
# during start state computation so it can ignore predicates thereafter.
|
| 154 |
+
# This means that SLL termination detection can totally ignore semantic
|
| 155 |
+
# predicates.</p>
|
| 156 |
+
#
|
| 157 |
+
# <p>Implementation-wise, {@link ATNConfigSet} combines stack contexts but not
|
| 158 |
+
# semantic predicate contexts so we might see two configurations like the
|
| 159 |
+
# following.</p>
|
| 160 |
+
#
|
| 161 |
+
# <p>{@code (s, 1, x, {}), (s, 1, x', {p})}</p>
|
| 162 |
+
#
|
| 163 |
+
# <p>Before testing these configurations against others, we have to merge
|
| 164 |
+
# {@code x} and {@code x'} (without modifying the existing configurations).
|
| 165 |
+
# For example, we test {@code (x+x')==x''} when looking for conflicts in
|
| 166 |
+
# the following configurations.</p>
|
| 167 |
+
#
|
| 168 |
+
# <p>{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}</p>
|
| 169 |
+
#
|
| 170 |
+
# <p>If the configuration set has predicates (as indicated by
|
| 171 |
+
# {@link ATNConfigSet#hasSemanticContext}), this algorithm makes a copy of
|
| 172 |
+
# the configurations to strip out all of the predicates so that a standard
|
| 173 |
+
# {@link ATNConfigSet} will merge everything ignoring predicates.</p>
|
| 174 |
+
#
|
| 175 |
+
@classmethod
|
| 176 |
+
def hasSLLConflictTerminatingPrediction(cls, mode:PredictionMode, configs:ATNConfigSet):
|
| 177 |
+
# Configs in rule stop states indicate reaching the end of the decision
|
| 178 |
+
# rule (local context) or end of start rule (full context). If all
|
| 179 |
+
# configs meet this condition, then none of the configurations is able
|
| 180 |
+
# to match additional input so we terminate prediction.
|
| 181 |
+
#
|
| 182 |
+
if cls.allConfigsInRuleStopStates(configs):
|
| 183 |
+
return True
|
| 184 |
+
|
| 185 |
+
# pure SLL mode parsing
|
| 186 |
+
if mode == PredictionMode.SLL:
|
| 187 |
+
# Don't bother with combining configs from different semantic
|
| 188 |
+
# contexts if we can fail over to full LL; costs more time
|
| 189 |
+
# since we'll often fail over anyway.
|
| 190 |
+
if configs.hasSemanticContext:
|
| 191 |
+
# dup configs, tossing out semantic predicates
|
| 192 |
+
dup = ATNConfigSet()
|
| 193 |
+
for c in configs:
|
| 194 |
+
c = ATNConfig(config=c, semantic=SemanticContext.NONE)
|
| 195 |
+
dup.add(c)
|
| 196 |
+
configs = dup
|
| 197 |
+
# now we have combined contexts for configs with dissimilar preds
|
| 198 |
+
|
| 199 |
+
# pure SLL or combined SLL+LL mode parsing
|
| 200 |
+
altsets = cls.getConflictingAltSubsets(configs)
|
| 201 |
+
return cls.hasConflictingAltSet(altsets) and not cls.hasStateAssociatedWithOneAlt(configs)
|
| 202 |
+
|
| 203 |
+
# Checks if any configuration in {@code configs} is in a
|
| 204 |
+
# {@link RuleStopState}. Configurations meeting this condition have reached
|
| 205 |
+
# the end of the decision rule (local context) or end of start rule (full
|
| 206 |
+
# context).
|
| 207 |
+
#
|
| 208 |
+
# @param configs the configuration set to test
|
| 209 |
+
# @return {@code true} if any configuration in {@code configs} is in a
|
| 210 |
+
# {@link RuleStopState}, otherwise {@code false}
|
| 211 |
+
@classmethod
|
| 212 |
+
def hasConfigInRuleStopState(cls, configs:ATNConfigSet):
|
| 213 |
+
return any(isinstance(cfg.state, RuleStopState) for cfg in configs)
|
| 214 |
+
|
| 215 |
+
# Checks if all configurations in {@code configs} are in a
|
| 216 |
+
# {@link RuleStopState}. Configurations meeting this condition have reached
|
| 217 |
+
# the end of the decision rule (local context) or end of start rule (full
|
| 218 |
+
# context).
|
| 219 |
+
#
|
| 220 |
+
# @param configs the configuration set to test
|
| 221 |
+
# @return {@code true} if all configurations in {@code configs} are in a
|
| 222 |
+
# {@link RuleStopState}, otherwise {@code false}
|
| 223 |
+
@classmethod
|
| 224 |
+
def allConfigsInRuleStopStates(cls, configs:ATNConfigSet):
|
| 225 |
+
return all(isinstance(cfg.state, RuleStopState) for cfg in configs)
|
| 226 |
+
|
| 227 |
+
#
|
| 228 |
+
# Full LL prediction termination.
|
| 229 |
+
#
|
| 230 |
+
# <p>Can we stop looking ahead during ATN simulation or is there some
|
| 231 |
+
# uncertainty as to which alternative we will ultimately pick, after
|
| 232 |
+
# consuming more input? Even if there are partial conflicts, we might know
|
| 233 |
+
# that everything is going to resolve to the same minimum alternative. That
|
| 234 |
+
# means we can stop since no more lookahead will change that fact. On the
|
| 235 |
+
# other hand, there might be multiple conflicts that resolve to different
|
| 236 |
+
# minimums. That means we need more look ahead to decide which of those
|
| 237 |
+
# alternatives we should predict.</p>
|
| 238 |
+
#
|
| 239 |
+
# <p>The basic idea is to split the set of configurations {@code C}, into
|
| 240 |
+
# conflicting subsets {@code (s, _, ctx, _)} and singleton subsets with
|
| 241 |
+
# non-conflicting configurations. Two configurations conflict if they have
|
| 242 |
+
# identical {@link ATNConfig#state} and {@link ATNConfig#context} values
|
| 243 |
+
# but different {@link ATNConfig#alt} value, e.g. {@code (s, i, ctx, _)}
|
| 244 |
+
# and {@code (s, j, ctx, _)} for {@code i!=j}.</p>
|
| 245 |
+
#
|
| 246 |
+
# <p>Reduce these configuration subsets to the set of possible alternatives.
|
| 247 |
+
# You can compute the alternative subsets in one pass as follows:</p>
|
| 248 |
+
#
|
| 249 |
+
# <p>{@code A_s,ctx = {i | (s, i, ctx, _)}} for each configuration in
|
| 250 |
+
# {@code C} holding {@code s} and {@code ctx} fixed.</p>
|
| 251 |
+
#
|
| 252 |
+
# <p>Or in pseudo-code, for each configuration {@code c} in {@code C}:</p>
|
| 253 |
+
#
|
| 254 |
+
# <pre>
|
| 255 |
+
# map[c] U= c.{@link ATNConfig#alt alt} # map hash/equals uses s and x, not
|
| 256 |
+
# alt and not pred
|
| 257 |
+
# </pre>
|
| 258 |
+
#
|
| 259 |
+
# <p>The values in {@code map} are the set of {@code A_s,ctx} sets.</p>
|
| 260 |
+
#
|
| 261 |
+
# <p>If {@code |A_s,ctx|=1} then there is no conflict associated with
|
| 262 |
+
# {@code s} and {@code ctx}.</p>
|
| 263 |
+
#
|
| 264 |
+
# <p>Reduce the subsets to singletons by choosing a minimum of each subset. If
|
| 265 |
+
# the union of these alternative subsets is a singleton, then no amount of
|
| 266 |
+
# more lookahead will help us. We will always pick that alternative. If,
|
| 267 |
+
# however, there is more than one alternative, then we are uncertain which
|
| 268 |
+
# alternative to predict and must continue looking for resolution. We may
|
| 269 |
+
# or may not discover an ambiguity in the future, even if there are no
|
| 270 |
+
# conflicting subsets this round.</p>
|
| 271 |
+
#
|
| 272 |
+
# <p>The biggest sin is to terminate early because it means we've made a
|
| 273 |
+
# decision but were uncertain as to the eventual outcome. We haven't used
|
| 274 |
+
# enough lookahead. On the other hand, announcing a conflict too late is no
|
| 275 |
+
# big deal; you will still have the conflict. It's just inefficient. It
|
| 276 |
+
# might even look until the end of file.</p>
|
| 277 |
+
#
|
| 278 |
+
# <p>No special consideration for semantic predicates is required because
|
| 279 |
+
# predicates are evaluated on-the-fly for full LL prediction, ensuring that
|
| 280 |
+
# no configuration contains a semantic context during the termination
|
| 281 |
+
# check.</p>
|
| 282 |
+
#
|
| 283 |
+
# <p><strong>CONFLICTING CONFIGS</strong></p>
|
| 284 |
+
#
|
| 285 |
+
# <p>Two configurations {@code (s, i, x)} and {@code (s, j, x')}, conflict
|
| 286 |
+
# when {@code i!=j} but {@code x=x'}. Because we merge all
|
| 287 |
+
# {@code (s, i, _)} configurations together, that means that there are at
|
| 288 |
+
# most {@code n} configurations associated with state {@code s} for
|
| 289 |
+
# {@code n} possible alternatives in the decision. The merged stacks
|
| 290 |
+
# complicate the comparison of configuration contexts {@code x} and
|
| 291 |
+
# {@code x'}. Sam checks to see if one is a subset of the other by calling
|
| 292 |
+
# merge and checking to see if the merged result is either {@code x} or
|
| 293 |
+
# {@code x'}. If the {@code x} associated with lowest alternative {@code i}
|
| 294 |
+
# is the superset, then {@code i} is the only possible prediction since the
|
| 295 |
+
# others resolve to {@code min(i)} as well. However, if {@code x} is
|
| 296 |
+
# associated with {@code j>i} then at least one stack configuration for
|
| 297 |
+
# {@code j} is not in conflict with alternative {@code i}. The algorithm
|
| 298 |
+
# should keep going, looking for more lookahead due to the uncertainty.</p>
|
| 299 |
+
#
|
| 300 |
+
# <p>For simplicity, I'm doing a equality check between {@code x} and
|
| 301 |
+
# {@code x'} that lets the algorithm continue to consume lookahead longer
|
| 302 |
+
# than necessary. The reason I like the equality is of course the
|
| 303 |
+
# simplicity but also because that is the test you need to detect the
|
| 304 |
+
# alternatives that are actually in conflict.</p>
|
| 305 |
+
#
|
| 306 |
+
# <p><strong>CONTINUE/STOP RULE</strong></p>
|
| 307 |
+
#
|
| 308 |
+
# <p>Continue if union of resolved alternative sets from non-conflicting and
|
| 309 |
+
# conflicting alternative subsets has more than one alternative. We are
|
| 310 |
+
# uncertain about which alternative to predict.</p>
|
| 311 |
+
#
|
| 312 |
+
# <p>The complete set of alternatives, {@code [i for (_,i,_)]}, tells us which
|
| 313 |
+
# alternatives are still in the running for the amount of input we've
|
| 314 |
+
# consumed at this point. The conflicting sets let us to strip away
|
| 315 |
+
# configurations that won't lead to more states because we resolve
|
| 316 |
+
# conflicts to the configuration with a minimum alternate for the
|
| 317 |
+
# conflicting set.</p>
|
| 318 |
+
#
|
| 319 |
+
# <p><strong>CASES</strong></p>
|
| 320 |
+
#
|
| 321 |
+
# <ul>
|
| 322 |
+
#
|
| 323 |
+
# <li>no conflicts and more than 1 alternative in set => continue</li>
|
| 324 |
+
#
|
| 325 |
+
# <li> {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s, 3, z)},
|
| 326 |
+
# {@code (s', 1, y)}, {@code (s', 2, y)} yields non-conflicting set
|
| 327 |
+
# {@code {3}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
|
| 328 |
+
# {@code {1,3}} => continue
|
| 329 |
+
# </li>
|
| 330 |
+
#
|
| 331 |
+
# <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
|
| 332 |
+
# {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set
|
| 333 |
+
# {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
|
| 334 |
+
# {@code {1}} => stop and predict 1</li>
|
| 335 |
+
#
|
| 336 |
+
# <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
|
| 337 |
+
# {@code (s', 2, y)} yields conflicting, reduced sets {@code {1}} U
|
| 338 |
+
# {@code {1}} = {@code {1}} => stop and predict 1, can announce
|
| 339 |
+
# ambiguity {@code {1,2}}</li>
|
| 340 |
+
#
|
| 341 |
+
# <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 2, y)},
|
| 342 |
+
# {@code (s', 3, y)} yields conflicting, reduced sets {@code {1}} U
|
| 343 |
+
# {@code {2}} = {@code {1,2}} => continue</li>
|
| 344 |
+
#
|
| 345 |
+
# <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 3, y)},
|
| 346 |
+
# {@code (s', 4, y)} yields conflicting, reduced sets {@code {1}} U
|
| 347 |
+
# {@code {3}} = {@code {1,3}} => continue</li>
|
| 348 |
+
#
|
| 349 |
+
# </ul>
|
| 350 |
+
#
|
| 351 |
+
# <p><strong>EXACT AMBIGUITY DETECTION</strong></p>
|
| 352 |
+
#
|
| 353 |
+
# <p>If all states report the same conflicting set of alternatives, then we
|
| 354 |
+
# know we have the exact ambiguity set.</p>
|
| 355 |
+
#
|
| 356 |
+
# <p><code>|A_<em>i</em>|>1</code> and
|
| 357 |
+
# <code>A_<em>i</em> = A_<em>j</em></code> for all <em>i</em>, <em>j</em>.</p>
|
| 358 |
+
#
|
| 359 |
+
# <p>In other words, we continue examining lookahead until all {@code A_i}
|
| 360 |
+
# have more than one alternative and all {@code A_i} are the same. If
|
| 361 |
+
# {@code A={{1,2}, {1,3}}}, then regular LL prediction would terminate
|
| 362 |
+
# because the resolved set is {@code {1}}. To determine what the real
|
| 363 |
+
# ambiguity is, we have to know whether the ambiguity is between one and
|
| 364 |
+
# two or one and three so we keep going. We can only stop prediction when
|
| 365 |
+
# we need exact ambiguity detection when the sets look like
|
| 366 |
+
# {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...</p>
|
| 367 |
+
#
|
| 368 |
+
@classmethod
|
| 369 |
+
def resolvesToJustOneViableAlt(cls, altsets:list):
|
| 370 |
+
return cls.getSingleViableAlt(altsets)
|
| 371 |
+
|
| 372 |
+
#
|
| 373 |
+
# Determines if every alternative subset in {@code altsets} contains more
|
| 374 |
+
# than one alternative.
|
| 375 |
+
#
|
| 376 |
+
# @param altsets a collection of alternative subsets
|
| 377 |
+
# @return {@code true} if every {@link BitSet} in {@code altsets} has
|
| 378 |
+
# {@link BitSet#cardinality cardinality} > 1, otherwise {@code false}
|
| 379 |
+
#
|
| 380 |
+
@classmethod
|
| 381 |
+
def allSubsetsConflict(cls, altsets:list):
|
| 382 |
+
return not cls.hasNonConflictingAltSet(altsets)
|
| 383 |
+
|
| 384 |
+
#
|
| 385 |
+
# Determines if any single alternative subset in {@code altsets} contains
|
| 386 |
+
# exactly one alternative.
|
| 387 |
+
#
|
| 388 |
+
# @param altsets a collection of alternative subsets
|
| 389 |
+
# @return {@code true} if {@code altsets} contains a {@link BitSet} with
|
| 390 |
+
# {@link BitSet#cardinality cardinality} 1, otherwise {@code false}
|
| 391 |
+
#
|
| 392 |
+
@classmethod
|
| 393 |
+
def hasNonConflictingAltSet(cls, altsets:list):
|
| 394 |
+
return any(len(alts) == 1 for alts in altsets)
|
| 395 |
+
|
| 396 |
+
#
|
| 397 |
+
# Determines if any single alternative subset in {@code altsets} contains
|
| 398 |
+
# more than one alternative.
|
| 399 |
+
#
|
| 400 |
+
# @param altsets a collection of alternative subsets
|
| 401 |
+
# @return {@code true} if {@code altsets} contains a {@link BitSet} with
|
| 402 |
+
# {@link BitSet#cardinality cardinality} > 1, otherwise {@code false}
|
| 403 |
+
#
|
| 404 |
+
@classmethod
|
| 405 |
+
def hasConflictingAltSet(cls, altsets:list):
|
| 406 |
+
return any(len(alts) > 1 for alts in altsets)
|
| 407 |
+
|
| 408 |
+
#
|
| 409 |
+
# Determines if every alternative subset in {@code altsets} is equivalent.
|
| 410 |
+
#
|
| 411 |
+
# @param altsets a collection of alternative subsets
|
| 412 |
+
# @return {@code true} if every member of {@code altsets} is equal to the
|
| 413 |
+
# others, otherwise {@code false}
|
| 414 |
+
#
|
| 415 |
+
@classmethod
|
| 416 |
+
def allSubsetsEqual(cls, altsets:list):
|
| 417 |
+
if not altsets:
|
| 418 |
+
return True
|
| 419 |
+
first = next(iter(altsets))
|
| 420 |
+
return all(alts == first for alts in iter(altsets))
|
| 421 |
+
|
| 422 |
+
#
|
| 423 |
+
# Returns the unique alternative predicted by all alternative subsets in
|
| 424 |
+
# {@code altsets}. If no such alternative exists, this method returns
|
| 425 |
+
# {@link ATN#INVALID_ALT_NUMBER}.
|
| 426 |
+
#
|
| 427 |
+
# @param altsets a collection of alternative subsets
|
| 428 |
+
#
|
| 429 |
+
@classmethod
|
| 430 |
+
def getUniqueAlt(cls, altsets:list):
|
| 431 |
+
all = cls.getAlts(altsets)
|
| 432 |
+
if len(all)==1:
|
| 433 |
+
return next(iter(all))
|
| 434 |
+
return ATN.INVALID_ALT_NUMBER
|
| 435 |
+
|
| 436 |
+
# Gets the complete set of represented alternatives for a collection of
|
| 437 |
+
# alternative subsets. This method returns the union of each {@link BitSet}
|
| 438 |
+
# in {@code altsets}.
|
| 439 |
+
#
|
| 440 |
+
# @param altsets a collection of alternative subsets
|
| 441 |
+
# @return the set of represented alternatives in {@code altsets}
|
| 442 |
+
#
|
| 443 |
+
@classmethod
|
| 444 |
+
def getAlts(cls, altsets:list):
|
| 445 |
+
return set.union(*altsets)
|
| 446 |
+
|
| 447 |
+
#
|
| 448 |
+
# This function gets the conflicting alt subsets from a configuration set.
|
| 449 |
+
# For each configuration {@code c} in {@code configs}:
|
| 450 |
+
#
|
| 451 |
+
# <pre>
|
| 452 |
+
# map[c] U= c.{@link ATNConfig#alt alt} # map hash/equals uses s and x, not
|
| 453 |
+
# alt and not pred
|
| 454 |
+
# </pre>
|
| 455 |
+
#
|
| 456 |
+
@classmethod
|
| 457 |
+
def getConflictingAltSubsets(cls, configs:ATNConfigSet):
|
| 458 |
+
configToAlts = dict()
|
| 459 |
+
for c in configs:
|
| 460 |
+
h = hash((c.state.stateNumber, c.context))
|
| 461 |
+
alts = configToAlts.get(h, None)
|
| 462 |
+
if alts is None:
|
| 463 |
+
alts = set()
|
| 464 |
+
configToAlts[h] = alts
|
| 465 |
+
alts.add(c.alt)
|
| 466 |
+
return configToAlts.values()
|
| 467 |
+
|
| 468 |
+
#
|
| 469 |
+
# Get a map from state to alt subset from a configuration set. For each
|
| 470 |
+
# configuration {@code c} in {@code configs}:
|
| 471 |
+
#
|
| 472 |
+
# <pre>
|
| 473 |
+
# map[c.{@link ATNConfig#state state}] U= c.{@link ATNConfig#alt alt}
|
| 474 |
+
# </pre>
|
| 475 |
+
#
|
| 476 |
+
@classmethod
|
| 477 |
+
def getStateToAltMap(cls, configs:ATNConfigSet):
|
| 478 |
+
m = dict()
|
| 479 |
+
for c in configs:
|
| 480 |
+
alts = m.get(c.state, None)
|
| 481 |
+
if alts is None:
|
| 482 |
+
alts = set()
|
| 483 |
+
m[c.state] = alts
|
| 484 |
+
alts.add(c.alt)
|
| 485 |
+
return m
|
| 486 |
+
|
| 487 |
+
@classmethod
|
| 488 |
+
def hasStateAssociatedWithOneAlt(cls, configs:ATNConfigSet):
|
| 489 |
+
return any(len(alts) == 1 for alts in cls.getStateToAltMap(configs).values())
|
| 490 |
+
|
| 491 |
+
@classmethod
|
| 492 |
+
def getSingleViableAlt(cls, altsets:list):
|
| 493 |
+
viableAlts = set()
|
| 494 |
+
for alts in altsets:
|
| 495 |
+
minAlt = min(alts)
|
| 496 |
+
viableAlts.add(minAlt)
|
| 497 |
+
if len(viableAlts)>1 : # more than 1 viable alt
|
| 498 |
+
return ATN.INVALID_ALT_NUMBER
|
| 499 |
+
return min(viableAlts)
|
cameras/deps/antlr4/atn/SemanticContext.py
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
# A tree structure used to record the semantic context in which
|
| 8 |
+
# an ATN configuration is valid. It's either a single predicate,
|
| 9 |
+
# a conjunction {@code p1&&p2}, or a sum of products {@code p1||p2}.
|
| 10 |
+
#
|
| 11 |
+
# <p>I have scoped the {@link AND}, {@link OR}, and {@link Predicate} subclasses of
|
| 12 |
+
# {@link SemanticContext} within the scope of this outer class.</p>
|
| 13 |
+
#
|
| 14 |
+
from antlr4.Recognizer import Recognizer
|
| 15 |
+
from antlr4.RuleContext import RuleContext
|
| 16 |
+
from io import StringIO
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class SemanticContext(object):
|
| 20 |
+
#
|
| 21 |
+
# The default {@link SemanticContext}, which is semantically equivalent to
|
| 22 |
+
# a predicate of the form {@code {true}?}.
|
| 23 |
+
#
|
| 24 |
+
NONE = None
|
| 25 |
+
|
| 26 |
+
#
|
| 27 |
+
# For context independent predicates, we evaluate them without a local
|
| 28 |
+
# context (i.e., null context). That way, we can evaluate them without
|
| 29 |
+
# having to create proper rule-specific context during prediction (as
|
| 30 |
+
# opposed to the parser, which creates them naturally). In a practical
|
| 31 |
+
# sense, this avoids a cast exception from RuleContext to myruleContext.
|
| 32 |
+
#
|
| 33 |
+
# <p>For context dependent predicates, we must pass in a local context so that
|
| 34 |
+
# references such as $arg evaluate properly as _localctx.arg. We only
|
| 35 |
+
# capture context dependent predicates in the context in which we begin
|
| 36 |
+
# prediction, so we passed in the outer context here in case of context
|
| 37 |
+
# dependent predicate evaluation.</p>
|
| 38 |
+
#
|
| 39 |
+
def eval(self, parser:Recognizer , outerContext:RuleContext ):
|
| 40 |
+
pass
|
| 41 |
+
|
| 42 |
+
#
|
| 43 |
+
# Evaluate the precedence predicates for the context and reduce the result.
|
| 44 |
+
#
|
| 45 |
+
# @param parser The parser instance.
|
| 46 |
+
# @param outerContext The current parser context object.
|
| 47 |
+
# @return The simplified semantic context after precedence predicates are
|
| 48 |
+
# evaluated, which will be one of the following values.
|
| 49 |
+
# <ul>
|
| 50 |
+
# <li>{@link #NONE}: if the predicate simplifies to {@code true} after
|
| 51 |
+
# precedence predicates are evaluated.</li>
|
| 52 |
+
# <li>{@code null}: if the predicate simplifies to {@code false} after
|
| 53 |
+
# precedence predicates are evaluated.</li>
|
| 54 |
+
# <li>{@code this}: if the semantic context is not changed as a result of
|
| 55 |
+
# precedence predicate evaluation.</li>
|
| 56 |
+
# <li>A non-{@code null} {@link SemanticContext}: the new simplified
|
| 57 |
+
# semantic context after precedence predicates are evaluated.</li>
|
| 58 |
+
# </ul>
|
| 59 |
+
#
|
| 60 |
+
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
|
| 61 |
+
return self
|
| 62 |
+
|
| 63 |
+
# need forward declaration
|
| 64 |
+
AND = None
|
| 65 |
+
|
| 66 |
+
def andContext(a:SemanticContext, b:SemanticContext):
|
| 67 |
+
if a is None or a is SemanticContext.NONE:
|
| 68 |
+
return b
|
| 69 |
+
if b is None or b is SemanticContext.NONE:
|
| 70 |
+
return a
|
| 71 |
+
result = AND(a, b)
|
| 72 |
+
if len(result.opnds) == 1:
|
| 73 |
+
return result.opnds[0]
|
| 74 |
+
else:
|
| 75 |
+
return result
|
| 76 |
+
|
| 77 |
+
# need forward declaration
|
| 78 |
+
OR = None
|
| 79 |
+
|
| 80 |
+
def orContext(a:SemanticContext, b:SemanticContext):
|
| 81 |
+
if a is None:
|
| 82 |
+
return b
|
| 83 |
+
if b is None:
|
| 84 |
+
return a
|
| 85 |
+
if a is SemanticContext.NONE or b is SemanticContext.NONE:
|
| 86 |
+
return SemanticContext.NONE
|
| 87 |
+
result = OR(a, b)
|
| 88 |
+
if len(result.opnds) == 1:
|
| 89 |
+
return result.opnds[0]
|
| 90 |
+
else:
|
| 91 |
+
return result
|
| 92 |
+
|
| 93 |
+
def filterPrecedencePredicates(collection:set):
|
| 94 |
+
return [context for context in collection if isinstance(context, PrecedencePredicate)]
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
class Predicate(SemanticContext):
|
| 98 |
+
__slots__ = ('ruleIndex', 'predIndex', 'isCtxDependent')
|
| 99 |
+
|
| 100 |
+
def __init__(self, ruleIndex:int=-1, predIndex:int=-1, isCtxDependent:bool=False):
|
| 101 |
+
self.ruleIndex = ruleIndex
|
| 102 |
+
self.predIndex = predIndex
|
| 103 |
+
self.isCtxDependent = isCtxDependent # e.g., $i ref in pred
|
| 104 |
+
|
| 105 |
+
def eval(self, parser:Recognizer , outerContext:RuleContext ):
|
| 106 |
+
localctx = outerContext if self.isCtxDependent else None
|
| 107 |
+
return parser.sempred(localctx, self.ruleIndex, self.predIndex)
|
| 108 |
+
|
| 109 |
+
def __hash__(self):
|
| 110 |
+
return hash((self.ruleIndex, self.predIndex, self.isCtxDependent))
|
| 111 |
+
|
| 112 |
+
def __eq__(self, other):
|
| 113 |
+
if self is other:
|
| 114 |
+
return True
|
| 115 |
+
elif not isinstance(other, Predicate):
|
| 116 |
+
return False
|
| 117 |
+
return self.ruleIndex == other.ruleIndex and \
|
| 118 |
+
self.predIndex == other.predIndex and \
|
| 119 |
+
self.isCtxDependent == other.isCtxDependent
|
| 120 |
+
|
| 121 |
+
def __str__(self):
|
| 122 |
+
return "{" + str(self.ruleIndex) + ":" + str(self.predIndex) + "}?"
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
class PrecedencePredicate(SemanticContext):
|
| 126 |
+
|
| 127 |
+
def __init__(self, precedence:int=0):
|
| 128 |
+
self.precedence = precedence
|
| 129 |
+
|
| 130 |
+
def eval(self, parser:Recognizer , outerContext:RuleContext ):
|
| 131 |
+
return parser.precpred(outerContext, self.precedence)
|
| 132 |
+
|
| 133 |
+
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
|
| 134 |
+
if parser.precpred(outerContext, self.precedence):
|
| 135 |
+
return SemanticContext.NONE
|
| 136 |
+
else:
|
| 137 |
+
return None
|
| 138 |
+
|
| 139 |
+
def __lt__(self, other):
|
| 140 |
+
return self.precedence < other.precedence
|
| 141 |
+
|
| 142 |
+
def __hash__(self):
|
| 143 |
+
return 31
|
| 144 |
+
|
| 145 |
+
def __eq__(self, other):
|
| 146 |
+
if self is other:
|
| 147 |
+
return True
|
| 148 |
+
elif not isinstance(other, PrecedencePredicate):
|
| 149 |
+
return False
|
| 150 |
+
else:
|
| 151 |
+
return self.precedence == other.precedence
|
| 152 |
+
|
| 153 |
+
# A semantic context which is true whenever none of the contained contexts
|
| 154 |
+
# is false.
|
| 155 |
+
del AND
|
| 156 |
+
class AND(SemanticContext):
|
| 157 |
+
__slots__ = 'opnds'
|
| 158 |
+
|
| 159 |
+
def __init__(self, a:SemanticContext, b:SemanticContext):
|
| 160 |
+
operands = set()
|
| 161 |
+
if isinstance( a, AND ):
|
| 162 |
+
operands.update(a.opnds)
|
| 163 |
+
else:
|
| 164 |
+
operands.add(a)
|
| 165 |
+
if isinstance( b, AND ):
|
| 166 |
+
operands.update(b.opnds)
|
| 167 |
+
else:
|
| 168 |
+
operands.add(b)
|
| 169 |
+
|
| 170 |
+
precedencePredicates = filterPrecedencePredicates(operands)
|
| 171 |
+
if len(precedencePredicates)>0:
|
| 172 |
+
# interested in the transition with the lowest precedence
|
| 173 |
+
reduced = min(precedencePredicates)
|
| 174 |
+
operands.add(reduced)
|
| 175 |
+
|
| 176 |
+
self.opnds = list(operands)
|
| 177 |
+
|
| 178 |
+
def __eq__(self, other):
|
| 179 |
+
if self is other:
|
| 180 |
+
return True
|
| 181 |
+
elif not isinstance(other, AND):
|
| 182 |
+
return False
|
| 183 |
+
else:
|
| 184 |
+
return self.opnds == other.opnds
|
| 185 |
+
|
| 186 |
+
def __hash__(self):
|
| 187 |
+
h = 0
|
| 188 |
+
for o in self.opnds:
|
| 189 |
+
h = hash((h, o))
|
| 190 |
+
return hash((h, "AND"))
|
| 191 |
+
|
| 192 |
+
#
|
| 193 |
+
# {@inheritDoc}
|
| 194 |
+
#
|
| 195 |
+
# <p>
|
| 196 |
+
# The evaluation of predicates by this context is short-circuiting, but
|
| 197 |
+
# unordered.</p>
|
| 198 |
+
#
|
| 199 |
+
def eval(self, parser:Recognizer, outerContext:RuleContext):
|
| 200 |
+
return all(opnd.eval(parser, outerContext) for opnd in self.opnds)
|
| 201 |
+
|
| 202 |
+
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
|
| 203 |
+
differs = False
|
| 204 |
+
operands = []
|
| 205 |
+
for context in self.opnds:
|
| 206 |
+
evaluated = context.evalPrecedence(parser, outerContext)
|
| 207 |
+
differs |= evaluated is not context
|
| 208 |
+
if evaluated is None:
|
| 209 |
+
# The AND context is false if any element is false
|
| 210 |
+
return None
|
| 211 |
+
elif evaluated is not SemanticContext.NONE:
|
| 212 |
+
# Reduce the result by skipping true elements
|
| 213 |
+
operands.append(evaluated)
|
| 214 |
+
|
| 215 |
+
if not differs:
|
| 216 |
+
return self
|
| 217 |
+
|
| 218 |
+
if len(operands)==0:
|
| 219 |
+
# all elements were true, so the AND context is true
|
| 220 |
+
return SemanticContext.NONE
|
| 221 |
+
|
| 222 |
+
result = None
|
| 223 |
+
for o in operands:
|
| 224 |
+
result = o if result is None else andContext(result, o)
|
| 225 |
+
|
| 226 |
+
return result
|
| 227 |
+
|
| 228 |
+
def __str__(self):
|
| 229 |
+
with StringIO() as buf:
|
| 230 |
+
first = True
|
| 231 |
+
for o in self.opnds:
|
| 232 |
+
if not first:
|
| 233 |
+
buf.write("&&")
|
| 234 |
+
buf.write(str(o))
|
| 235 |
+
first = False
|
| 236 |
+
return buf.getvalue()
|
| 237 |
+
|
| 238 |
+
#
|
| 239 |
+
# A semantic context which is true whenever at least one of the contained
|
| 240 |
+
# contexts is true.
|
| 241 |
+
del OR
|
| 242 |
+
class OR (SemanticContext):
|
| 243 |
+
__slots__ = 'opnds'
|
| 244 |
+
|
| 245 |
+
def __init__(self, a:SemanticContext, b:SemanticContext):
|
| 246 |
+
operands = set()
|
| 247 |
+
if isinstance( a, OR ):
|
| 248 |
+
operands.update(a.opnds)
|
| 249 |
+
else:
|
| 250 |
+
operands.add(a)
|
| 251 |
+
if isinstance( b, OR ):
|
| 252 |
+
operands.update(b.opnds)
|
| 253 |
+
else:
|
| 254 |
+
operands.add(b)
|
| 255 |
+
|
| 256 |
+
precedencePredicates = filterPrecedencePredicates(operands)
|
| 257 |
+
if len(precedencePredicates)>0:
|
| 258 |
+
# interested in the transition with the highest precedence
|
| 259 |
+
s = sorted(precedencePredicates)
|
| 260 |
+
reduced = s[-1]
|
| 261 |
+
operands.add(reduced)
|
| 262 |
+
|
| 263 |
+
self.opnds = list(operands)
|
| 264 |
+
|
| 265 |
+
def __eq__(self, other):
|
| 266 |
+
if self is other:
|
| 267 |
+
return True
|
| 268 |
+
elif not isinstance(other, OR):
|
| 269 |
+
return False
|
| 270 |
+
else:
|
| 271 |
+
return self.opnds == other.opnds
|
| 272 |
+
|
| 273 |
+
def __hash__(self):
|
| 274 |
+
h = 0
|
| 275 |
+
for o in self.opnds:
|
| 276 |
+
h = hash((h, o))
|
| 277 |
+
return hash((h, "OR"))
|
| 278 |
+
|
| 279 |
+
# <p>
|
| 280 |
+
# The evaluation of predicates by this context is short-circuiting, but
|
| 281 |
+
# unordered.</p>
|
| 282 |
+
#
|
| 283 |
+
def eval(self, parser:Recognizer, outerContext:RuleContext):
|
| 284 |
+
return any(opnd.eval(parser, outerContext) for opnd in self.opnds)
|
| 285 |
+
|
| 286 |
+
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
|
| 287 |
+
differs = False
|
| 288 |
+
operands = []
|
| 289 |
+
for context in self.opnds:
|
| 290 |
+
evaluated = context.evalPrecedence(parser, outerContext)
|
| 291 |
+
differs |= evaluated is not context
|
| 292 |
+
if evaluated is SemanticContext.NONE:
|
| 293 |
+
# The OR context is true if any element is true
|
| 294 |
+
return SemanticContext.NONE
|
| 295 |
+
elif evaluated is not None:
|
| 296 |
+
# Reduce the result by skipping false elements
|
| 297 |
+
operands.append(evaluated)
|
| 298 |
+
|
| 299 |
+
if not differs:
|
| 300 |
+
return self
|
| 301 |
+
|
| 302 |
+
if len(operands)==0:
|
| 303 |
+
# all elements were false, so the OR context is false
|
| 304 |
+
return None
|
| 305 |
+
|
| 306 |
+
result = None
|
| 307 |
+
for o in operands:
|
| 308 |
+
result = o if result is None else orContext(result, o)
|
| 309 |
+
|
| 310 |
+
return result
|
| 311 |
+
|
| 312 |
+
def __str__(self):
|
| 313 |
+
with StringIO() as buf:
|
| 314 |
+
first = True
|
| 315 |
+
for o in self.opnds:
|
| 316 |
+
if not first:
|
| 317 |
+
buf.write("||")
|
| 318 |
+
buf.write(str(o))
|
| 319 |
+
first = False
|
| 320 |
+
return buf.getvalue()
|
| 321 |
+
|
| 322 |
+
|
| 323 |
+
SemanticContext.NONE = Predicate()
|
cameras/deps/antlr4/atn/Transition.py
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
# An ATN transition between any two ATN states. Subclasses define
|
| 8 |
+
# atom, set, epsilon, action, predicate, rule transitions.
|
| 9 |
+
#
|
| 10 |
+
# <p>This is a one way link. It emanates from a state (usually via a list of
|
| 11 |
+
# transitions) and has a target state.</p>
|
| 12 |
+
#
|
| 13 |
+
# <p>Since we never have to change the ATN transitions once we construct it,
|
| 14 |
+
# we can fix these transitions as specific classes. The DFA transitions
|
| 15 |
+
# on the other hand need to update the labels as it adds transitions to
|
| 16 |
+
# the states. We'll use the term Edge for the DFA to distinguish them from
|
| 17 |
+
# ATN transitions.</p>
|
| 18 |
+
#
|
| 19 |
+
from antlr4.IntervalSet import IntervalSet
|
| 20 |
+
from antlr4.Token import Token
|
| 21 |
+
|
| 22 |
+
# need forward declarations
|
| 23 |
+
from antlr4.atn.SemanticContext import Predicate, PrecedencePredicate
|
| 24 |
+
|
| 25 |
+
ATNState = None
|
| 26 |
+
RuleStartState = None
|
| 27 |
+
|
| 28 |
+
class Transition (object):
|
| 29 |
+
__slots__ = ('target','isEpsilon','label')
|
| 30 |
+
|
| 31 |
+
# constants for serialization
|
| 32 |
+
EPSILON = 1
|
| 33 |
+
RANGE = 2
|
| 34 |
+
RULE = 3
|
| 35 |
+
PREDICATE = 4 # e.g., {isType(input.LT(1))}?
|
| 36 |
+
ATOM = 5
|
| 37 |
+
ACTION = 6
|
| 38 |
+
SET = 7 # ~(A|B) or ~atom, wildcard, which convert to next 2
|
| 39 |
+
NOT_SET = 8
|
| 40 |
+
WILDCARD = 9
|
| 41 |
+
PRECEDENCE = 10
|
| 42 |
+
|
| 43 |
+
serializationNames = [
|
| 44 |
+
"INVALID",
|
| 45 |
+
"EPSILON",
|
| 46 |
+
"RANGE",
|
| 47 |
+
"RULE",
|
| 48 |
+
"PREDICATE",
|
| 49 |
+
"ATOM",
|
| 50 |
+
"ACTION",
|
| 51 |
+
"SET",
|
| 52 |
+
"NOT_SET",
|
| 53 |
+
"WILDCARD",
|
| 54 |
+
"PRECEDENCE"
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
serializationTypes = dict()
|
| 58 |
+
|
| 59 |
+
def __init__(self, target:ATNState):
|
| 60 |
+
# The target of this transition.
|
| 61 |
+
if target is None:
|
| 62 |
+
raise Exception("target cannot be null.")
|
| 63 |
+
self.target = target
|
| 64 |
+
# Are we epsilon, action, sempred?
|
| 65 |
+
self.isEpsilon = False
|
| 66 |
+
self.label = None
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# TODO: make all transitions sets? no, should remove set edges
|
| 70 |
+
class AtomTransition(Transition):
|
| 71 |
+
__slots__ = ('label_', 'serializationType')
|
| 72 |
+
|
| 73 |
+
def __init__(self, target:ATNState, label:int):
|
| 74 |
+
super().__init__(target)
|
| 75 |
+
self.label_ = label # The token type or character value; or, signifies special label.
|
| 76 |
+
self.label = self.makeLabel()
|
| 77 |
+
self.serializationType = self.ATOM
|
| 78 |
+
|
| 79 |
+
def makeLabel(self):
|
| 80 |
+
s = IntervalSet()
|
| 81 |
+
s.addOne(self.label_)
|
| 82 |
+
return s
|
| 83 |
+
|
| 84 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 85 |
+
return self.label_ == symbol
|
| 86 |
+
|
| 87 |
+
def __str__(self):
|
| 88 |
+
return str(self.label_)
|
| 89 |
+
|
| 90 |
+
class RuleTransition(Transition):
|
| 91 |
+
__slots__ = ('ruleIndex', 'precedence', 'followState', 'serializationType')
|
| 92 |
+
|
| 93 |
+
def __init__(self, ruleStart:RuleStartState, ruleIndex:int, precedence:int, followState:ATNState):
|
| 94 |
+
super().__init__(ruleStart)
|
| 95 |
+
self.ruleIndex = ruleIndex # ptr to the rule definition object for this rule ref
|
| 96 |
+
self.precedence = precedence
|
| 97 |
+
self.followState = followState # what node to begin computations following ref to rule
|
| 98 |
+
self.serializationType = self.RULE
|
| 99 |
+
self.isEpsilon = True
|
| 100 |
+
|
| 101 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 102 |
+
return False
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
class EpsilonTransition(Transition):
|
| 106 |
+
__slots__ = ('serializationType', 'outermostPrecedenceReturn')
|
| 107 |
+
|
| 108 |
+
def __init__(self, target, outermostPrecedenceReturn=-1):
|
| 109 |
+
super(EpsilonTransition, self).__init__(target)
|
| 110 |
+
self.serializationType = self.EPSILON
|
| 111 |
+
self.isEpsilon = True
|
| 112 |
+
self.outermostPrecedenceReturn = outermostPrecedenceReturn
|
| 113 |
+
|
| 114 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 115 |
+
return False
|
| 116 |
+
|
| 117 |
+
def __str__(self):
|
| 118 |
+
return "epsilon"
|
| 119 |
+
|
| 120 |
+
class RangeTransition(Transition):
|
| 121 |
+
__slots__ = ('serializationType', 'start', 'stop')
|
| 122 |
+
|
| 123 |
+
def __init__(self, target:ATNState, start:int, stop:int):
|
| 124 |
+
super().__init__(target)
|
| 125 |
+
self.serializationType = self.RANGE
|
| 126 |
+
self.start = start
|
| 127 |
+
self.stop = stop
|
| 128 |
+
self.label = self.makeLabel()
|
| 129 |
+
|
| 130 |
+
def makeLabel(self):
|
| 131 |
+
s = IntervalSet()
|
| 132 |
+
s.addRange(range(self.start, self.stop + 1))
|
| 133 |
+
return s
|
| 134 |
+
|
| 135 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 136 |
+
return symbol >= self.start and symbol <= self.stop
|
| 137 |
+
|
| 138 |
+
def __str__(self):
|
| 139 |
+
return "'" + chr(self.start) + "'..'" + chr(self.stop) + "'"
|
| 140 |
+
|
| 141 |
+
class AbstractPredicateTransition(Transition):
|
| 142 |
+
|
| 143 |
+
def __init__(self, target:ATNState):
|
| 144 |
+
super().__init__(target)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
class PredicateTransition(AbstractPredicateTransition):
|
| 148 |
+
__slots__ = ('serializationType', 'ruleIndex', 'predIndex', 'isCtxDependent')
|
| 149 |
+
|
| 150 |
+
def __init__(self, target:ATNState, ruleIndex:int, predIndex:int, isCtxDependent:bool):
|
| 151 |
+
super().__init__(target)
|
| 152 |
+
self.serializationType = self.PREDICATE
|
| 153 |
+
self.ruleIndex = ruleIndex
|
| 154 |
+
self.predIndex = predIndex
|
| 155 |
+
self.isCtxDependent = isCtxDependent # e.g., $i ref in pred
|
| 156 |
+
self.isEpsilon = True
|
| 157 |
+
|
| 158 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 159 |
+
return False
|
| 160 |
+
|
| 161 |
+
def getPredicate(self):
|
| 162 |
+
return Predicate(self.ruleIndex, self.predIndex, self.isCtxDependent)
|
| 163 |
+
|
| 164 |
+
def __str__(self):
|
| 165 |
+
return "pred_" + str(self.ruleIndex) + ":" + str(self.predIndex)
|
| 166 |
+
|
| 167 |
+
class ActionTransition(Transition):
|
| 168 |
+
__slots__ = ('serializationType', 'ruleIndex', 'actionIndex', 'isCtxDependent')
|
| 169 |
+
|
| 170 |
+
def __init__(self, target:ATNState, ruleIndex:int, actionIndex:int=-1, isCtxDependent:bool=False):
|
| 171 |
+
super().__init__(target)
|
| 172 |
+
self.serializationType = self.ACTION
|
| 173 |
+
self.ruleIndex = ruleIndex
|
| 174 |
+
self.actionIndex = actionIndex
|
| 175 |
+
self.isCtxDependent = isCtxDependent # e.g., $i ref in pred
|
| 176 |
+
self.isEpsilon = True
|
| 177 |
+
|
| 178 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 179 |
+
return False
|
| 180 |
+
|
| 181 |
+
def __str__(self):
|
| 182 |
+
return "action_"+self.ruleIndex+":"+self.actionIndex
|
| 183 |
+
|
| 184 |
+
# A transition containing a set of values.
|
| 185 |
+
class SetTransition(Transition):
|
| 186 |
+
__slots__ = 'serializationType'
|
| 187 |
+
|
| 188 |
+
def __init__(self, target:ATNState, set:IntervalSet):
|
| 189 |
+
super().__init__(target)
|
| 190 |
+
self.serializationType = self.SET
|
| 191 |
+
if set is not None:
|
| 192 |
+
self.label = set
|
| 193 |
+
else:
|
| 194 |
+
self.label = IntervalSet()
|
| 195 |
+
self.label.addRange(range(Token.INVALID_TYPE, Token.INVALID_TYPE + 1))
|
| 196 |
+
|
| 197 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 198 |
+
return symbol in self.label
|
| 199 |
+
|
| 200 |
+
def __str__(self):
|
| 201 |
+
return str(self.label)
|
| 202 |
+
|
| 203 |
+
class NotSetTransition(SetTransition):
|
| 204 |
+
|
| 205 |
+
def __init__(self, target:ATNState, set:IntervalSet):
|
| 206 |
+
super().__init__(target, set)
|
| 207 |
+
self.serializationType = self.NOT_SET
|
| 208 |
+
|
| 209 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 210 |
+
return symbol >= minVocabSymbol \
|
| 211 |
+
and symbol <= maxVocabSymbol \
|
| 212 |
+
and not super(type(self), self).matches(symbol, minVocabSymbol, maxVocabSymbol)
|
| 213 |
+
|
| 214 |
+
def __str__(self):
|
| 215 |
+
return '~' + super(type(self), self).__str__()
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
class WildcardTransition(Transition):
|
| 219 |
+
__slots__ = 'serializationType'
|
| 220 |
+
|
| 221 |
+
def __init__(self, target:ATNState):
|
| 222 |
+
super().__init__(target)
|
| 223 |
+
self.serializationType = self.WILDCARD
|
| 224 |
+
|
| 225 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 226 |
+
return symbol >= minVocabSymbol and symbol <= maxVocabSymbol
|
| 227 |
+
|
| 228 |
+
def __str__(self):
|
| 229 |
+
return "."
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
class PrecedencePredicateTransition(AbstractPredicateTransition):
|
| 233 |
+
__slots__ = ('serializationType', 'precedence')
|
| 234 |
+
|
| 235 |
+
def __init__(self, target:ATNState, precedence:int):
|
| 236 |
+
super().__init__(target)
|
| 237 |
+
self.serializationType = self.PRECEDENCE
|
| 238 |
+
self.precedence = precedence
|
| 239 |
+
self.isEpsilon = True
|
| 240 |
+
|
| 241 |
+
def matches( self, symbol:int, minVocabSymbol:int, maxVocabSymbol:int):
|
| 242 |
+
return False
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
def getPredicate(self):
|
| 246 |
+
return PrecedencePredicate(self.precedence)
|
| 247 |
+
|
| 248 |
+
def __str__(self):
|
| 249 |
+
return self.precedence + " >= _p"
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
Transition.serializationTypes = {
|
| 253 |
+
EpsilonTransition: Transition.EPSILON,
|
| 254 |
+
RangeTransition: Transition.RANGE,
|
| 255 |
+
RuleTransition: Transition.RULE,
|
| 256 |
+
PredicateTransition: Transition.PREDICATE,
|
| 257 |
+
AtomTransition: Transition.ATOM,
|
| 258 |
+
ActionTransition: Transition.ACTION,
|
| 259 |
+
SetTransition: Transition.SET,
|
| 260 |
+
NotSetTransition: Transition.NOT_SET,
|
| 261 |
+
WildcardTransition: Transition.WILDCARD,
|
| 262 |
+
PrecedencePredicateTransition: Transition.PRECEDENCE
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
del ATNState
|
| 266 |
+
del RuleStartState
|
| 267 |
+
|
| 268 |
+
from antlr4.atn.ATNState import *
|
cameras/deps/antlr4/atn/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__author__ = 'ericvergnaud'
|
cameras/deps/antlr4/dfa/DFA.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
from antlr4.atn.ATNState import StarLoopEntryState
|
| 6 |
+
|
| 7 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet
|
| 8 |
+
from antlr4.atn.ATNState import DecisionState
|
| 9 |
+
from antlr4.dfa.DFAState import DFAState
|
| 10 |
+
from antlr4.error.Errors import IllegalStateException
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class DFA(object):
|
| 14 |
+
__slots__ = ('atnStartState', 'decision', '_states', 's0', 'precedenceDfa')
|
| 15 |
+
|
| 16 |
+
def __init__(self, atnStartState:DecisionState, decision:int=0):
|
| 17 |
+
# From which ATN state did we create this DFA?
|
| 18 |
+
self.atnStartState = atnStartState
|
| 19 |
+
self.decision = decision
|
| 20 |
+
# A set of all DFA states. Use {@link Map} so we can get old state back
|
| 21 |
+
# ({@link Set} only allows you to see if it's there).
|
| 22 |
+
self._states = dict()
|
| 23 |
+
self.s0 = None
|
| 24 |
+
# {@code true} if this DFA is for a precedence decision; otherwise,
|
| 25 |
+
# {@code false}. This is the backing field for {@link #isPrecedenceDfa},
|
| 26 |
+
# {@link #setPrecedenceDfa}.
|
| 27 |
+
self.precedenceDfa = False
|
| 28 |
+
|
| 29 |
+
if isinstance(atnStartState, StarLoopEntryState):
|
| 30 |
+
if atnStartState.isPrecedenceDecision:
|
| 31 |
+
self.precedenceDfa = True
|
| 32 |
+
precedenceState = DFAState(configs=ATNConfigSet())
|
| 33 |
+
precedenceState.edges = []
|
| 34 |
+
precedenceState.isAcceptState = False
|
| 35 |
+
precedenceState.requiresFullContext = False
|
| 36 |
+
self.s0 = precedenceState
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
# Get the start state for a specific precedence value.
|
| 40 |
+
#
|
| 41 |
+
# @param precedence The current precedence.
|
| 42 |
+
# @return The start state corresponding to the specified precedence, or
|
| 43 |
+
# {@code null} if no start state exists for the specified precedence.
|
| 44 |
+
#
|
| 45 |
+
# @throws IllegalStateException if this is not a precedence DFA.
|
| 46 |
+
# @see #isPrecedenceDfa()
|
| 47 |
+
|
| 48 |
+
def getPrecedenceStartState(self, precedence:int):
|
| 49 |
+
if not self.precedenceDfa:
|
| 50 |
+
raise IllegalStateException("Only precedence DFAs may contain a precedence start state.")
|
| 51 |
+
|
| 52 |
+
# s0.edges is never null for a precedence DFA
|
| 53 |
+
if precedence < 0 or precedence >= len(self.s0.edges):
|
| 54 |
+
return None
|
| 55 |
+
return self.s0.edges[precedence]
|
| 56 |
+
|
| 57 |
+
# Set the start state for a specific precedence value.
|
| 58 |
+
#
|
| 59 |
+
# @param precedence The current precedence.
|
| 60 |
+
# @param startState The start state corresponding to the specified
|
| 61 |
+
# precedence.
|
| 62 |
+
#
|
| 63 |
+
# @throws IllegalStateException if this is not a precedence DFA.
|
| 64 |
+
# @see #isPrecedenceDfa()
|
| 65 |
+
#
|
| 66 |
+
def setPrecedenceStartState(self, precedence:int, startState:DFAState):
|
| 67 |
+
if not self.precedenceDfa:
|
| 68 |
+
raise IllegalStateException("Only precedence DFAs may contain a precedence start state.")
|
| 69 |
+
|
| 70 |
+
if precedence < 0:
|
| 71 |
+
return
|
| 72 |
+
|
| 73 |
+
# synchronization on s0 here is ok. when the DFA is turned into a
|
| 74 |
+
# precedence DFA, s0 will be initialized once and not updated again
|
| 75 |
+
# s0.edges is never null for a precedence DFA
|
| 76 |
+
if precedence >= len(self.s0.edges):
|
| 77 |
+
ext = [None] * (precedence + 1 - len(self.s0.edges))
|
| 78 |
+
self.s0.edges.extend(ext)
|
| 79 |
+
self.s0.edges[precedence] = startState
|
| 80 |
+
#
|
| 81 |
+
# Sets whether this is a precedence DFA. If the specified value differs
|
| 82 |
+
# from the current DFA configuration, the following actions are taken;
|
| 83 |
+
# otherwise no changes are made to the current DFA.
|
| 84 |
+
#
|
| 85 |
+
# <ul>
|
| 86 |
+
# <li>The {@link #states} map is cleared</li>
|
| 87 |
+
# <li>If {@code precedenceDfa} is {@code false}, the initial state
|
| 88 |
+
# {@link #s0} is set to {@code null}; otherwise, it is initialized to a new
|
| 89 |
+
# {@link DFAState} with an empty outgoing {@link DFAState#edges} array to
|
| 90 |
+
# store the start states for individual precedence values.</li>
|
| 91 |
+
# <li>The {@link #precedenceDfa} field is updated</li>
|
| 92 |
+
# </ul>
|
| 93 |
+
#
|
| 94 |
+
# @param precedenceDfa {@code true} if this is a precedence DFA; otherwise,
|
| 95 |
+
# {@code false}
|
| 96 |
+
|
| 97 |
+
def setPrecedenceDfa(self, precedenceDfa:bool):
|
| 98 |
+
if self.precedenceDfa != precedenceDfa:
|
| 99 |
+
self._states = dict()
|
| 100 |
+
if precedenceDfa:
|
| 101 |
+
precedenceState = DFAState(configs=ATNConfigSet())
|
| 102 |
+
precedenceState.edges = []
|
| 103 |
+
precedenceState.isAcceptState = False
|
| 104 |
+
precedenceState.requiresFullContext = False
|
| 105 |
+
self.s0 = precedenceState
|
| 106 |
+
else:
|
| 107 |
+
self.s0 = None
|
| 108 |
+
self.precedenceDfa = precedenceDfa
|
| 109 |
+
|
| 110 |
+
@property
|
| 111 |
+
def states(self):
|
| 112 |
+
return self._states
|
| 113 |
+
|
| 114 |
+
# Return a list of all states in this DFA, ordered by state number.
|
| 115 |
+
def sortedStates(self):
|
| 116 |
+
return sorted(self._states.keys(), key=lambda state: state.stateNumber)
|
| 117 |
+
|
| 118 |
+
def __str__(self):
|
| 119 |
+
return self.toString(None)
|
| 120 |
+
|
| 121 |
+
def toString(self, literalNames:list=None, symbolicNames:list=None):
|
| 122 |
+
if self.s0 is None:
|
| 123 |
+
return ""
|
| 124 |
+
from antlr4.dfa.DFASerializer import DFASerializer
|
| 125 |
+
serializer = DFASerializer(self,literalNames,symbolicNames)
|
| 126 |
+
return str(serializer)
|
| 127 |
+
|
| 128 |
+
def toLexerString(self):
|
| 129 |
+
if self.s0 is None:
|
| 130 |
+
return ""
|
| 131 |
+
from antlr4.dfa.DFASerializer import LexerDFASerializer
|
| 132 |
+
serializer = LexerDFASerializer(self)
|
| 133 |
+
return str(serializer)
|
cameras/deps/antlr4/dfa/DFASerializer.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
# A DFA walker that knows how to dump them to serialized strings.#/
|
| 8 |
+
from io import StringIO
|
| 9 |
+
from antlr4 import DFA
|
| 10 |
+
from antlr4.Utils import str_list
|
| 11 |
+
from antlr4.dfa.DFAState import DFAState
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class DFASerializer(object):
|
| 15 |
+
__slots__ = ('dfa', 'literalNames', 'symbolicNames')
|
| 16 |
+
|
| 17 |
+
def __init__(self, dfa:DFA, literalNames:list=None, symbolicNames:list=None):
|
| 18 |
+
self.dfa = dfa
|
| 19 |
+
self.literalNames = literalNames
|
| 20 |
+
self.symbolicNames = symbolicNames
|
| 21 |
+
|
| 22 |
+
def __str__(self):
|
| 23 |
+
if self.dfa.s0 is None:
|
| 24 |
+
return None
|
| 25 |
+
with StringIO() as buf:
|
| 26 |
+
for s in self.dfa.sortedStates():
|
| 27 |
+
n = 0
|
| 28 |
+
if s.edges is not None:
|
| 29 |
+
n = len(s.edges)
|
| 30 |
+
for i in range(0, n):
|
| 31 |
+
t = s.edges[i]
|
| 32 |
+
if t is not None and t.stateNumber != 0x7FFFFFFF:
|
| 33 |
+
buf.write(self.getStateString(s))
|
| 34 |
+
label = self.getEdgeLabel(i)
|
| 35 |
+
buf.write("-")
|
| 36 |
+
buf.write(label)
|
| 37 |
+
buf.write("->")
|
| 38 |
+
buf.write(self.getStateString(t))
|
| 39 |
+
buf.write('\n')
|
| 40 |
+
output = buf.getvalue()
|
| 41 |
+
if len(output)==0:
|
| 42 |
+
return None
|
| 43 |
+
else:
|
| 44 |
+
return output
|
| 45 |
+
|
| 46 |
+
def getEdgeLabel(self, i:int):
|
| 47 |
+
if i==0:
|
| 48 |
+
return "EOF"
|
| 49 |
+
if self.literalNames is not None and i<=len(self.literalNames):
|
| 50 |
+
return self.literalNames[i-1]
|
| 51 |
+
elif self.symbolicNames is not None and i<=len(self.symbolicNames):
|
| 52 |
+
return self.symbolicNames[i-1]
|
| 53 |
+
else:
|
| 54 |
+
return str(i-1)
|
| 55 |
+
|
| 56 |
+
def getStateString(self, s:DFAState):
|
| 57 |
+
n = s.stateNumber
|
| 58 |
+
baseStateStr = ( ":" if s.isAcceptState else "") + "s" + str(n) + ( "^" if s.requiresFullContext else "")
|
| 59 |
+
if s.isAcceptState:
|
| 60 |
+
if s.predicates is not None:
|
| 61 |
+
return baseStateStr + "=>" + str_list(s.predicates)
|
| 62 |
+
else:
|
| 63 |
+
return baseStateStr + "=>" + str(s.prediction)
|
| 64 |
+
else:
|
| 65 |
+
return baseStateStr
|
| 66 |
+
|
| 67 |
+
class LexerDFASerializer(DFASerializer):
|
| 68 |
+
|
| 69 |
+
def __init__(self, dfa:DFA):
|
| 70 |
+
super().__init__(dfa, None)
|
| 71 |
+
|
| 72 |
+
def getEdgeLabel(self, i:int):
|
| 73 |
+
return "'" + chr(i) + "'"
|
cameras/deps/antlr4/dfa/DFAState.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
| 3 |
+
# Use of this file is governed by the BSD 3-clause license that
|
| 4 |
+
# can be found in the LICENSE.txt file in the project root.
|
| 5 |
+
#/
|
| 6 |
+
|
| 7 |
+
# Map a predicate to a predicted alternative.#/
|
| 8 |
+
from io import StringIO
|
| 9 |
+
from antlr4.atn.ATNConfigSet import ATNConfigSet
|
| 10 |
+
from antlr4.atn.SemanticContext import SemanticContext
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class PredPrediction(object):
|
| 14 |
+
__slots__ = ('alt', 'pred')
|
| 15 |
+
|
| 16 |
+
def __init__(self, pred:SemanticContext, alt:int):
|
| 17 |
+
self.alt = alt
|
| 18 |
+
self.pred = pred
|
| 19 |
+
|
| 20 |
+
def __str__(self):
|
| 21 |
+
return "(" + str(self.pred) + ", " + str(self.alt) + ")"
|
| 22 |
+
|
| 23 |
+
# A DFA state represents a set of possible ATN configurations.
|
| 24 |
+
# As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
|
| 25 |
+
# to keep track of all possible states the ATN can be in after
|
| 26 |
+
# reading each input symbol. That is to say, after reading
|
| 27 |
+
# input a1a2..an, the DFA is in a state that represents the
|
| 28 |
+
# subset T of the states of the ATN that are reachable from the
|
| 29 |
+
# ATN's start state along some path labeled a1a2..an."
|
| 30 |
+
# In conventional NFA→DFA conversion, therefore, the subset T
|
| 31 |
+
# would be a bitset representing the set of states the
|
| 32 |
+
# ATN could be in. We need to track the alt predicted by each
|
| 33 |
+
# state as well, however. More importantly, we need to maintain
|
| 34 |
+
# a stack of states, tracking the closure operations as they
|
| 35 |
+
# jump from rule to rule, emulating rule invocations (method calls).
|
| 36 |
+
# I have to add a stack to simulate the proper lookahead sequences for
|
| 37 |
+
# the underlying LL grammar from which the ATN was derived.
|
| 38 |
+
#
|
| 39 |
+
# <p>I use a set of ATNConfig objects not simple states. An ATNConfig
|
| 40 |
+
# is both a state (ala normal conversion) and a RuleContext describing
|
| 41 |
+
# the chain of rules (if any) followed to arrive at that state.</p>
|
| 42 |
+
#
|
| 43 |
+
# <p>A DFA state may have multiple references to a particular state,
|
| 44 |
+
# but with different ATN contexts (with same or different alts)
|
| 45 |
+
# meaning that state was reached via a different set of rule invocations.</p>
|
| 46 |
+
#/
|
| 47 |
+
class DFAState(object):
|
| 48 |
+
__slots__ = (
|
| 49 |
+
'stateNumber', 'configs', 'edges', 'isAcceptState', 'prediction',
|
| 50 |
+
'lexerActionExecutor', 'requiresFullContext', 'predicates'
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
def __init__(self, stateNumber:int=-1, configs:ATNConfigSet=ATNConfigSet()):
|
| 54 |
+
self.stateNumber = stateNumber
|
| 55 |
+
self.configs = configs
|
| 56 |
+
# {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1)
|
| 57 |
+
# {@link Token#EOF} maps to {@code edges[0]}.
|
| 58 |
+
self.edges = None
|
| 59 |
+
self.isAcceptState = False
|
| 60 |
+
# if accept state, what ttype do we match or alt do we predict?
|
| 61 |
+
# This is set to {@link ATN#INVALID_ALT_NUMBER} when {@link #predicates}{@code !=null} or
|
| 62 |
+
# {@link #requiresFullContext}.
|
| 63 |
+
self.prediction = 0
|
| 64 |
+
self.lexerActionExecutor = None
|
| 65 |
+
# Indicates that this state was created during SLL prediction that
|
| 66 |
+
# discovered a conflict between the configurations in the state. Future
|
| 67 |
+
# {@link ParserATNSimulator#execATN} invocations immediately jumped doing
|
| 68 |
+
# full context prediction if this field is true.
|
| 69 |
+
self.requiresFullContext = False
|
| 70 |
+
# During SLL parsing, this is a list of predicates associated with the
|
| 71 |
+
# ATN configurations of the DFA state. When we have predicates,
|
| 72 |
+
# {@link #requiresFullContext} is {@code false} since full context prediction evaluates predicates
|
| 73 |
+
# on-the-fly. If this is not null, then {@link #prediction} is
|
| 74 |
+
# {@link ATN#INVALID_ALT_NUMBER}.
|
| 75 |
+
#
|
| 76 |
+
# <p>We only use these for non-{@link #requiresFullContext} but conflicting states. That
|
| 77 |
+
# means we know from the context (it's $ or we don't dip into outer
|
| 78 |
+
# context) that it's an ambiguity not a conflict.</p>
|
| 79 |
+
#
|
| 80 |
+
# <p>This list is computed by {@link ParserATNSimulator#predicateDFAState}.</p>
|
| 81 |
+
self.predicates = None
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
# Get the set of all alts mentioned by all ATN configurations in this
|
| 86 |
+
# DFA state.
|
| 87 |
+
def getAltSet(self):
|
| 88 |
+
if self.configs is not None:
|
| 89 |
+
return set(cfg.alt for cfg in self.configs) or None
|
| 90 |
+
return None
|
| 91 |
+
|
| 92 |
+
def __hash__(self):
|
| 93 |
+
return hash(self.configs)
|
| 94 |
+
|
| 95 |
+
# Two {@link DFAState} instances are equal if their ATN configuration sets
|
| 96 |
+
# are the same. This method is used to see if a state already exists.
|
| 97 |
+
#
|
| 98 |
+
# <p>Because the number of alternatives and number of ATN configurations are
|
| 99 |
+
# finite, there is a finite number of DFA states that can be processed.
|
| 100 |
+
# This is necessary to show that the algorithm terminates.</p>
|
| 101 |
+
#
|
| 102 |
+
# <p>Cannot test the DFA state numbers here because in
|
| 103 |
+
# {@link ParserATNSimulator#addDFAState} we need to know if any other state
|
| 104 |
+
# exists that has this exact set of ATN configurations. The
|
| 105 |
+
# {@link #stateNumber} is irrelevant.</p>
|
| 106 |
+
def __eq__(self, other):
|
| 107 |
+
# compare set of ATN configurations in this set with other
|
| 108 |
+
if self is other:
|
| 109 |
+
return True
|
| 110 |
+
elif not isinstance(other, DFAState):
|
| 111 |
+
return False
|
| 112 |
+
else:
|
| 113 |
+
return self.configs==other.configs
|
| 114 |
+
|
| 115 |
+
def __str__(self):
|
| 116 |
+
with StringIO() as buf:
|
| 117 |
+
buf.write(str(self.stateNumber))
|
| 118 |
+
buf.write(":")
|
| 119 |
+
buf.write(str(self.configs))
|
| 120 |
+
if self.isAcceptState:
|
| 121 |
+
buf.write("=>")
|
| 122 |
+
if self.predicates is not None:
|
| 123 |
+
buf.write(str(self.predicates))
|
| 124 |
+
else:
|
| 125 |
+
buf.write(str(self.prediction))
|
| 126 |
+
return buf.getvalue()
|