varphi-devkit 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- varphi_devkit-1.0.0/LICENSE +28 -0
- varphi_devkit-1.0.0/PKG-INFO +200 -0
- varphi_devkit-1.0.0/README.md +178 -0
- varphi_devkit-1.0.0/pyproject.toml +110 -0
- varphi_devkit-1.0.0/src/varphi_devkit/__init__.py +33 -0
- varphi_devkit-1.0.0/src/varphi_devkit/compilation.py +119 -0
- varphi_devkit-1.0.0/src/varphi_devkit/model.py +53 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/Varphi.g4 +24 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/__init__.py +28 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/antlr/VarphiLexer.py +76 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/antlr/VarphiListener.py +30 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/antlr/VarphiParser.py +180 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/antlr/__init__.py +21 -0
- varphi_devkit-1.0.0/src/varphi_devkit/syntax/error_listener.py +79 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Hassan El-Sheikha
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: varphi-devkit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python framework for creating compilers that target the Varphi language
|
|
5
|
+
License: BSD-3-Clause
|
|
6
|
+
Keywords: compiler,turing-machine,dsl,antlr,parser
|
|
7
|
+
Author: Hassan El-Sheikha
|
|
8
|
+
Author-email: hmelsheikha@gmail.com
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Dist: antlr4-python3-runtime (>=4.13.2,<5.0.0)
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Varphi Development Kit
|
|
23
|
+
|
|
24
|
+
A Python framework for creating compilers that target the Varphi language - a domain-specific language for describing Turing machine transition rules.
|
|
25
|
+
|
|
26
|
+
## Overview
|
|
27
|
+
|
|
28
|
+
Varphi is a minimalist language designed to represent Turing machine programs using simple transition rules. The Varphi Development Kit provides a flexible compiler framework that allows you to build custom compilers to transform Varphi programs into any target format.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install varphi-devkit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Requirements:**
|
|
37
|
+
- Python ≥ 3.10
|
|
38
|
+
|
|
39
|
+
## Varphi Language Syntax
|
|
40
|
+
|
|
41
|
+
Varphi programs consist of transition rules with the following syntax:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
STATE TAPE_CHARACTER STATE TAPE_CHARACTER HEAD_DIRECTION
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Where:
|
|
48
|
+
- **STATE**: Current/target state (format: `q` followed by alphanumeric characters, e.g., `q0`, `q_start`, `q1_accept`)
|
|
49
|
+
- **TAPE_CHARACTER**: Tape symbol (`0` for blank, `1` for marked)
|
|
50
|
+
- **HEAD_DIRECTION**: Head movement (`L` for left, `R` for right)
|
|
51
|
+
|
|
52
|
+
### Example Varphi Program
|
|
53
|
+
|
|
54
|
+
```varphi
|
|
55
|
+
// Simple addition-by-one program
|
|
56
|
+
q0 1 q0 1 R
|
|
57
|
+
q0 0 qHalt 1 R
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Language Features
|
|
61
|
+
|
|
62
|
+
- **Comments**: Single-line (`//`) and multi-line (`/* */`) comments are supported
|
|
63
|
+
- **Whitespace**: Flexible whitespace handling (spaces, tabs, newlines)
|
|
64
|
+
- **States**: Flexible state naming with `q` prefix
|
|
65
|
+
|
|
66
|
+
## Core Architecture
|
|
67
|
+
|
|
68
|
+
The framework is built around these key components:
|
|
69
|
+
|
|
70
|
+
### Data Model
|
|
71
|
+
|
|
72
|
+
- **`VarphiTapeCharacter`**: Enum for tape symbols (`BLANK="0"`, `ONE="1"`)
|
|
73
|
+
- **`VarphiHeadDirection`**: Enum for head movement (`LEFT="L"`, `RIGHT="R"`)
|
|
74
|
+
- **`VarphiLine`**: Dataclass representing a transition rule with fields:
|
|
75
|
+
- `if_state`: Current state
|
|
76
|
+
- `if_condition`: Current tape character
|
|
77
|
+
- `then_state`: Next state
|
|
78
|
+
- `then_character`: Character to write
|
|
79
|
+
- `then_direction`: Direction to move
|
|
80
|
+
|
|
81
|
+
### Compiler Framework
|
|
82
|
+
|
|
83
|
+
- **`VarphiCompiler`**: Abstract base class for implementing custom compilers
|
|
84
|
+
- **`compile_varphi()`**: Function to parse and compile Varphi programs
|
|
85
|
+
- **`VarphiSyntaxError`**: Exception for syntax errors
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
### Creating a Custom Compiler
|
|
90
|
+
|
|
91
|
+
To create a Varphi compiler, subclass `VarphiCompiler` and implement three methods:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from varphi_devkit import VarphiCompiler, VarphiLine, compile_varphi
|
|
95
|
+
|
|
96
|
+
class MyCompiler(VarphiCompiler):
|
|
97
|
+
def __init__(self):
|
|
98
|
+
# Initialize your compiler's state
|
|
99
|
+
self.output = []
|
|
100
|
+
|
|
101
|
+
def handle_line(self, line: VarphiLine):
|
|
102
|
+
# Process each transition rule
|
|
103
|
+
self.output.append(f"Transition: {line.if_state} -> {line.then_state}")
|
|
104
|
+
|
|
105
|
+
def generate_compiled_program(self) -> str:
|
|
106
|
+
# Return the final compiled output
|
|
107
|
+
return "\n".join(self.output)
|
|
108
|
+
|
|
109
|
+
# Use your compiler
|
|
110
|
+
program = """
|
|
111
|
+
q0 0 q1 1 R
|
|
112
|
+
q1 1 q_halt 0 L
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
compiler = MyCompiler()
|
|
116
|
+
result = compile_varphi(program, compiler)
|
|
117
|
+
print(result)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Example Toy Compilers
|
|
121
|
+
|
|
122
|
+
The framework's test suite includes several [example compilers](/tests/toy_compilers) that demonstrate different use cases.
|
|
123
|
+
|
|
124
|
+
## Error Handling
|
|
125
|
+
|
|
126
|
+
The framework provides comprehensive syntax error reporting out of the box:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from varphi_devkit import VarphiSyntaxError, compile_varphi
|
|
130
|
+
from your_compiler import YourCompiler
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
result = compile_varphi("invalid syntax here", YourCompiler())
|
|
134
|
+
except VarphiSyntaxError as e:
|
|
135
|
+
print(f"Syntax error at line {e.line}, column {e.column}: {e.message}")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## API Reference
|
|
139
|
+
|
|
140
|
+
### Core Functions
|
|
141
|
+
|
|
142
|
+
#### `compile_varphi(program: str, compiler: VarphiCompiler) -> str`
|
|
143
|
+
|
|
144
|
+
Parses and compiles a Varphi program using the provided compiler.
|
|
145
|
+
|
|
146
|
+
- **Parameters:**
|
|
147
|
+
- `program`: Varphi source code as a string
|
|
148
|
+
- `compiler`: VarphiCompiler instance to process the program
|
|
149
|
+
- **Returns:** Compiled program output from the compiler
|
|
150
|
+
- **Raises:** `VarphiSyntaxError` for invalid syntax
|
|
151
|
+
|
|
152
|
+
### Abstract Base Class
|
|
153
|
+
|
|
154
|
+
#### `VarphiCompiler`
|
|
155
|
+
|
|
156
|
+
Abstract base class for implementing custom Varphi compilers.
|
|
157
|
+
|
|
158
|
+
**Abstract Methods:**
|
|
159
|
+
- `__init__(self) -> None`: Initialize compiler state
|
|
160
|
+
- `handle_line(self, line: VarphiLine) -> None`: Process a transition rule (line in the Varphi program)
|
|
161
|
+
- `generate_compiled_program(self) -> str`: Return final compiled output
|
|
162
|
+
|
|
163
|
+
### Data Classes
|
|
164
|
+
|
|
165
|
+
#### `VarphiLine`
|
|
166
|
+
|
|
167
|
+
Represents a single transition rule with attributes:
|
|
168
|
+
- `if_state: str` - Current state
|
|
169
|
+
- `if_condition: VarphiTapeCharacter` - Current tape character
|
|
170
|
+
- `then_state: str` - Next state
|
|
171
|
+
- `then_character: VarphiTapeCharacter` - Character to write
|
|
172
|
+
- `then_direction: VarphiHeadDirection` - Head movement direction
|
|
173
|
+
|
|
174
|
+
#### `VarphiTapeCharacter`
|
|
175
|
+
|
|
176
|
+
Enum for tape characters:
|
|
177
|
+
- `BLANK = "0"` - Empty tape cell
|
|
178
|
+
- `ONE = "1"` - Marked tape cell
|
|
179
|
+
|
|
180
|
+
#### `VarphiHeadDirection`
|
|
181
|
+
|
|
182
|
+
Enum for head movement:
|
|
183
|
+
- `LEFT = "L"` - Move head left
|
|
184
|
+
- `RIGHT = "R"` - Move head right
|
|
185
|
+
|
|
186
|
+
### Exceptions
|
|
187
|
+
|
|
188
|
+
#### `VarphiSyntaxError`
|
|
189
|
+
|
|
190
|
+
Exception raised for syntax errors in Varphi programs.
|
|
191
|
+
|
|
192
|
+
**Attributes:**
|
|
193
|
+
- `message: str` - Error description
|
|
194
|
+
- `line: int` - Line number where error occurred
|
|
195
|
+
- `column: int` - Column position of error
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
This project is available under the BSD-3-Clause License (see [LICENSE](LICENSE)).
|
|
200
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Varphi Development Kit
|
|
2
|
+
|
|
3
|
+
A Python framework for creating compilers that target the Varphi language - a domain-specific language for describing Turing machine transition rules.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Varphi is a minimalist language designed to represent Turing machine programs using simple transition rules. The Varphi Development Kit provides a flexible compiler framework that allows you to build custom compilers to transform Varphi programs into any target format.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install varphi-devkit
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Requirements:**
|
|
16
|
+
- Python ≥ 3.10
|
|
17
|
+
|
|
18
|
+
## Varphi Language Syntax
|
|
19
|
+
|
|
20
|
+
Varphi programs consist of transition rules with the following syntax:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
STATE TAPE_CHARACTER STATE TAPE_CHARACTER HEAD_DIRECTION
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Where:
|
|
27
|
+
- **STATE**: Current/target state (format: `q` followed by alphanumeric characters, e.g., `q0`, `q_start`, `q1_accept`)
|
|
28
|
+
- **TAPE_CHARACTER**: Tape symbol (`0` for blank, `1` for marked)
|
|
29
|
+
- **HEAD_DIRECTION**: Head movement (`L` for left, `R` for right)
|
|
30
|
+
|
|
31
|
+
### Example Varphi Program
|
|
32
|
+
|
|
33
|
+
```varphi
|
|
34
|
+
// Simple addition-by-one program
|
|
35
|
+
q0 1 q0 1 R
|
|
36
|
+
q0 0 qHalt 1 R
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Language Features
|
|
40
|
+
|
|
41
|
+
- **Comments**: Single-line (`//`) and multi-line (`/* */`) comments are supported
|
|
42
|
+
- **Whitespace**: Flexible whitespace handling (spaces, tabs, newlines)
|
|
43
|
+
- **States**: Flexible state naming with `q` prefix
|
|
44
|
+
|
|
45
|
+
## Core Architecture
|
|
46
|
+
|
|
47
|
+
The framework is built around these key components:
|
|
48
|
+
|
|
49
|
+
### Data Model
|
|
50
|
+
|
|
51
|
+
- **`VarphiTapeCharacter`**: Enum for tape symbols (`BLANK="0"`, `ONE="1"`)
|
|
52
|
+
- **`VarphiHeadDirection`**: Enum for head movement (`LEFT="L"`, `RIGHT="R"`)
|
|
53
|
+
- **`VarphiLine`**: Dataclass representing a transition rule with fields:
|
|
54
|
+
- `if_state`: Current state
|
|
55
|
+
- `if_condition`: Current tape character
|
|
56
|
+
- `then_state`: Next state
|
|
57
|
+
- `then_character`: Character to write
|
|
58
|
+
- `then_direction`: Direction to move
|
|
59
|
+
|
|
60
|
+
### Compiler Framework
|
|
61
|
+
|
|
62
|
+
- **`VarphiCompiler`**: Abstract base class for implementing custom compilers
|
|
63
|
+
- **`compile_varphi()`**: Function to parse and compile Varphi programs
|
|
64
|
+
- **`VarphiSyntaxError`**: Exception for syntax errors
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### Creating a Custom Compiler
|
|
69
|
+
|
|
70
|
+
To create a Varphi compiler, subclass `VarphiCompiler` and implement three methods:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from varphi_devkit import VarphiCompiler, VarphiLine, compile_varphi
|
|
74
|
+
|
|
75
|
+
class MyCompiler(VarphiCompiler):
|
|
76
|
+
def __init__(self):
|
|
77
|
+
# Initialize your compiler's state
|
|
78
|
+
self.output = []
|
|
79
|
+
|
|
80
|
+
def handle_line(self, line: VarphiLine):
|
|
81
|
+
# Process each transition rule
|
|
82
|
+
self.output.append(f"Transition: {line.if_state} -> {line.then_state}")
|
|
83
|
+
|
|
84
|
+
def generate_compiled_program(self) -> str:
|
|
85
|
+
# Return the final compiled output
|
|
86
|
+
return "\n".join(self.output)
|
|
87
|
+
|
|
88
|
+
# Use your compiler
|
|
89
|
+
program = """
|
|
90
|
+
q0 0 q1 1 R
|
|
91
|
+
q1 1 q_halt 0 L
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
compiler = MyCompiler()
|
|
95
|
+
result = compile_varphi(program, compiler)
|
|
96
|
+
print(result)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Example Toy Compilers
|
|
100
|
+
|
|
101
|
+
The framework's test suite includes several [example compilers](/tests/toy_compilers) that demonstrate different use cases.
|
|
102
|
+
|
|
103
|
+
## Error Handling
|
|
104
|
+
|
|
105
|
+
The framework provides comprehensive syntax error reporting out of the box:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from varphi_devkit import VarphiSyntaxError, compile_varphi
|
|
109
|
+
from your_compiler import YourCompiler
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
result = compile_varphi("invalid syntax here", YourCompiler())
|
|
113
|
+
except VarphiSyntaxError as e:
|
|
114
|
+
print(f"Syntax error at line {e.line}, column {e.column}: {e.message}")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## API Reference
|
|
118
|
+
|
|
119
|
+
### Core Functions
|
|
120
|
+
|
|
121
|
+
#### `compile_varphi(program: str, compiler: VarphiCompiler) -> str`
|
|
122
|
+
|
|
123
|
+
Parses and compiles a Varphi program using the provided compiler.
|
|
124
|
+
|
|
125
|
+
- **Parameters:**
|
|
126
|
+
- `program`: Varphi source code as a string
|
|
127
|
+
- `compiler`: VarphiCompiler instance to process the program
|
|
128
|
+
- **Returns:** Compiled program output from the compiler
|
|
129
|
+
- **Raises:** `VarphiSyntaxError` for invalid syntax
|
|
130
|
+
|
|
131
|
+
### Abstract Base Class
|
|
132
|
+
|
|
133
|
+
#### `VarphiCompiler`
|
|
134
|
+
|
|
135
|
+
Abstract base class for implementing custom Varphi compilers.
|
|
136
|
+
|
|
137
|
+
**Abstract Methods:**
|
|
138
|
+
- `__init__(self) -> None`: Initialize compiler state
|
|
139
|
+
- `handle_line(self, line: VarphiLine) -> None`: Process a transition rule (line in the Varphi program)
|
|
140
|
+
- `generate_compiled_program(self) -> str`: Return final compiled output
|
|
141
|
+
|
|
142
|
+
### Data Classes
|
|
143
|
+
|
|
144
|
+
#### `VarphiLine`
|
|
145
|
+
|
|
146
|
+
Represents a single transition rule with attributes:
|
|
147
|
+
- `if_state: str` - Current state
|
|
148
|
+
- `if_condition: VarphiTapeCharacter` - Current tape character
|
|
149
|
+
- `then_state: str` - Next state
|
|
150
|
+
- `then_character: VarphiTapeCharacter` - Character to write
|
|
151
|
+
- `then_direction: VarphiHeadDirection` - Head movement direction
|
|
152
|
+
|
|
153
|
+
#### `VarphiTapeCharacter`
|
|
154
|
+
|
|
155
|
+
Enum for tape characters:
|
|
156
|
+
- `BLANK = "0"` - Empty tape cell
|
|
157
|
+
- `ONE = "1"` - Marked tape cell
|
|
158
|
+
|
|
159
|
+
#### `VarphiHeadDirection`
|
|
160
|
+
|
|
161
|
+
Enum for head movement:
|
|
162
|
+
- `LEFT = "L"` - Move head left
|
|
163
|
+
- `RIGHT = "R"` - Move head right
|
|
164
|
+
|
|
165
|
+
### Exceptions
|
|
166
|
+
|
|
167
|
+
#### `VarphiSyntaxError`
|
|
168
|
+
|
|
169
|
+
Exception raised for syntax errors in Varphi programs.
|
|
170
|
+
|
|
171
|
+
**Attributes:**
|
|
172
|
+
- `message: str` - Error description
|
|
173
|
+
- `line: int` - Line number where error occurred
|
|
174
|
+
- `column: int` - Column position of error
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
This project is available under the BSD-3-Clause License (see [LICENSE](LICENSE)).
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "varphi-devkit"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A Python framework for creating compilers that target the Varphi language"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Hassan El-Sheikha",email = "hmelsheikha@gmail.com"}
|
|
7
|
+
]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
keywords = ["compiler", "turing-machine", "dsl", "antlr", "parser"]
|
|
11
|
+
license = {text = "BSD-3-Clause"}
|
|
12
|
+
homepage = "https://github.com/varphi-lang/varphi-devkit"
|
|
13
|
+
repository = "https://github.com/varphi-lang/varphi-devkit"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Software Development :: Compilers",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"antlr4-python3-runtime (>=4.13.2,<5.0.0)",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[tool.poetry]
|
|
30
|
+
packages = [{include = "varphi_devkit", from = "src"}]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
[tool.poetry.group.dev.dependencies]
|
|
34
|
+
pytest = "^8.4.1"
|
|
35
|
+
pylint = "^3.3.7"
|
|
36
|
+
antlr4-tools = "^0.2.2"
|
|
37
|
+
python-semantic-release = "^10.2.0"
|
|
38
|
+
build = "^1.3.0"
|
|
39
|
+
twine = "^6.1.0"
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
43
|
+
build-backend = "poetry.core.masonry.api"
|
|
44
|
+
|
|
45
|
+
[semantic_release]
|
|
46
|
+
assets = []
|
|
47
|
+
build_command_env = []
|
|
48
|
+
commit_message = "{version}\n\nAutomatically generated by python-semantic-release"
|
|
49
|
+
commit_parser = "conventional"
|
|
50
|
+
logging_use_named_masks = false
|
|
51
|
+
major_on_zero = true
|
|
52
|
+
allow_zero_version = false
|
|
53
|
+
repo_dir = "."
|
|
54
|
+
no_git_verify = false
|
|
55
|
+
tag_format = "v{version}"
|
|
56
|
+
version_toml = ["pyproject.toml:project.version"]
|
|
57
|
+
|
|
58
|
+
[semantic_release.branches.main]
|
|
59
|
+
match = "(main|master)"
|
|
60
|
+
prerelease_token = "rc"
|
|
61
|
+
prerelease = false
|
|
62
|
+
|
|
63
|
+
[semantic_release.changelog]
|
|
64
|
+
exclude_commit_patterns = []
|
|
65
|
+
mode = "update"
|
|
66
|
+
insertion_flag = "<!-- version list -->"
|
|
67
|
+
template_dir = "templates"
|
|
68
|
+
|
|
69
|
+
[semantic_release.changelog.default_templates]
|
|
70
|
+
changelog_file = "CHANGELOG.md"
|
|
71
|
+
output_format = "md"
|
|
72
|
+
mask_initial_release = true
|
|
73
|
+
|
|
74
|
+
[semantic_release.changelog.environment]
|
|
75
|
+
block_start_string = "{%"
|
|
76
|
+
block_end_string = "%}"
|
|
77
|
+
variable_start_string = "{{"
|
|
78
|
+
variable_end_string = "}}"
|
|
79
|
+
comment_start_string = "{#"
|
|
80
|
+
comment_end_string = "#}"
|
|
81
|
+
trim_blocks = false
|
|
82
|
+
lstrip_blocks = false
|
|
83
|
+
newline_sequence = "\n"
|
|
84
|
+
keep_trailing_newline = false
|
|
85
|
+
extensions = []
|
|
86
|
+
autoescape = false
|
|
87
|
+
|
|
88
|
+
[semantic_release.commit_author]
|
|
89
|
+
env = "GIT_COMMIT_AUTHOR"
|
|
90
|
+
default = "semantic-release <semantic-release>"
|
|
91
|
+
|
|
92
|
+
[semantic_release.commit_parser_options]
|
|
93
|
+
minor_tags = ["feat"]
|
|
94
|
+
patch_tags = ["fix", "perf"]
|
|
95
|
+
other_allowed_tags = ["build", "chore", "ci", "docs", "style", "refactor", "test"]
|
|
96
|
+
allowed_tags = ["feat", "fix", "perf", "build", "chore", "ci", "docs", "style", "refactor", "test"]
|
|
97
|
+
default_bump_level = 0
|
|
98
|
+
parse_squash_commits = true
|
|
99
|
+
ignore_merge_commits = true
|
|
100
|
+
|
|
101
|
+
[semantic_release.remote]
|
|
102
|
+
name = "origin"
|
|
103
|
+
type = "github"
|
|
104
|
+
ignore_token_for_push = false
|
|
105
|
+
insecure = false
|
|
106
|
+
|
|
107
|
+
[semantic_release.publish]
|
|
108
|
+
dist_glob_patterns = ["dist/*"]
|
|
109
|
+
upload_to_vcs_release = true
|
|
110
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Varphi Development Kit
|
|
3
|
+
|
|
4
|
+
A Python toolkit for working with the Varphi language - a domain-specific
|
|
5
|
+
language for describing Turing machine transition rules.
|
|
6
|
+
|
|
7
|
+
Main Components:
|
|
8
|
+
|
|
9
|
+
Model Classes:
|
|
10
|
+
- VarphiTapeCharacter: Represents tape characters (0 for blank, 1 for tally)
|
|
11
|
+
- VarphiHeadDirection: Represents head movement (L for left, R for right)
|
|
12
|
+
- VarphiLine: Represents a complete transition rule
|
|
13
|
+
|
|
14
|
+
Compilation:
|
|
15
|
+
- VarphiCompiler: Abstract base class for implementing Varphi compilers
|
|
16
|
+
- compile: Function to compile Varphi programs using a given compiler
|
|
17
|
+
|
|
18
|
+
Error Handling:
|
|
19
|
+
- VarphiSyntaxError: Exception raised for syntax errors in Varphi code
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from .model import VarphiTapeCharacter, VarphiHeadDirection, VarphiLine
|
|
23
|
+
from .compilation import VarphiCompiler, compile_varphi
|
|
24
|
+
from .syntax.error_listener import VarphiSyntaxError
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"VarphiTapeCharacter",
|
|
28
|
+
"VarphiHeadDirection",
|
|
29
|
+
"VarphiLine",
|
|
30
|
+
"VarphiCompiler",
|
|
31
|
+
"compile_varphi",
|
|
32
|
+
"VarphiSyntaxError",
|
|
33
|
+
]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Compilation infrastructure for Varphi language programs.
|
|
2
|
+
|
|
3
|
+
This module provides the compilation framework for translating Varphi programs
|
|
4
|
+
(Turing machine descriptions) into target languages. Users implement custom
|
|
5
|
+
compilers by subclassing VarphiCompiler and defining how individual transition
|
|
6
|
+
rules should be processed.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
1. Subclass VarphiCompiler and implement the abstract methods:
|
|
10
|
+
- __init__(): Set up your compiler's initial state
|
|
11
|
+
- handleLine(): Process each transition rule (VarphiLine)
|
|
12
|
+
- generate_compiled_program(): Return the final compiled output
|
|
13
|
+
|
|
14
|
+
2. Use the compile() function with your compiler instance:
|
|
15
|
+
compiled_output = compile(varphi_program_text, your_compiler_instance)
|
|
16
|
+
|
|
17
|
+
Classes:
|
|
18
|
+
VarphiCompiler: Abstract base class for implementing custom compilers.
|
|
19
|
+
|
|
20
|
+
Functions:
|
|
21
|
+
compile: Parses a Varphi program and compiles it using the provided compiler.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import logging
|
|
25
|
+
from abc import ABC, abstractmethod
|
|
26
|
+
|
|
27
|
+
from antlr4 import InputStream, CommonTokenStream, ParseTreeWalker
|
|
28
|
+
|
|
29
|
+
from .syntax.antlr.VarphiLexer import VarphiLexer
|
|
30
|
+
from .syntax.antlr.VarphiParser import VarphiParser
|
|
31
|
+
from .syntax.antlr.VarphiListener import VarphiListener
|
|
32
|
+
from .syntax.error_listener import VarphiSyntaxErrorListener
|
|
33
|
+
from .model import VarphiTapeCharacter, VarphiHeadDirection, VarphiLine
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class VarphiCompiler(VarphiListener, ABC):
|
|
41
|
+
"""Abstract base class for compiling Varphi programs into target languages.
|
|
42
|
+
|
|
43
|
+
Subclasses must implement the abstract methods to define compilation behavior.
|
|
44
|
+
Inherits from VarphiListener to receive ANTLR parse tree events.
|
|
45
|
+
|
|
46
|
+
Abstract Methods:
|
|
47
|
+
__init__: Initialize compiler state
|
|
48
|
+
handleLine: Process a single transition rule
|
|
49
|
+
generate_compiled_program: Return the final compiled output
|
|
50
|
+
"""
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def __init__(self) -> None:
|
|
53
|
+
"""Initialize the compiler's state and data structures."""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@abstractmethod
|
|
57
|
+
def handle_line(self, line: VarphiLine) -> None:
|
|
58
|
+
"""Process a single transition rule (line in the Varphi program).
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
line: The VarphiLine object representing a transition rule
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@abstractmethod
|
|
66
|
+
def generate_compiled_program(self) -> str:
|
|
67
|
+
"""Generate and return the final compiled program as a string.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The complete compiled program in the target language
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def enterLine(self, ctx: VarphiParser.LineContext) -> None:
|
|
75
|
+
"""Parse ANTLR line context and delegate to handleLine.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
ctx: The ANTLR parser context for the line rule
|
|
79
|
+
"""
|
|
80
|
+
logging.debug("Entering line %s", ctx.start.line)
|
|
81
|
+
if_state = str(ctx.STATE(0).getText())
|
|
82
|
+
logging.debug("If state: %s", if_state)
|
|
83
|
+
tape_character = VarphiTapeCharacter(ctx.TAPE_CHARACTER(0).getText())
|
|
84
|
+
logging.debug("Tape character: %s", tape_character)
|
|
85
|
+
then_state = str(ctx.STATE(1).getText())
|
|
86
|
+
logging.debug("Then state: %s", then_state)
|
|
87
|
+
then_character = VarphiTapeCharacter(ctx.TAPE_CHARACTER(1).getText())
|
|
88
|
+
logging.debug("Then character: %s", then_character)
|
|
89
|
+
then_direction = VarphiHeadDirection(ctx.HEAD_DIRECTION().getText())
|
|
90
|
+
logging.debug("Then direction: %s", then_direction)
|
|
91
|
+
line = VarphiLine(if_state, tape_character, then_state, then_character, then_direction)
|
|
92
|
+
logging.debug("Delegating to handleLine() helper method")
|
|
93
|
+
self.handle_line(line)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def compile_varphi(program: str, compiler: VarphiCompiler) -> str:
|
|
98
|
+
"""Parse and compile a Varphi program using the provided compiler.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
program: The Varphi program source code as a string
|
|
102
|
+
compiler: A VarphiCompiler instance to process the program
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
The compiled program output from the compiler
|
|
106
|
+
"""
|
|
107
|
+
input_stream = InputStream(program)
|
|
108
|
+
error_listener = VarphiSyntaxErrorListener(program)
|
|
109
|
+
lexer = VarphiLexer(input_stream)
|
|
110
|
+
lexer.removeErrorListeners()
|
|
111
|
+
lexer.addErrorListener(error_listener)
|
|
112
|
+
token_stream = CommonTokenStream(lexer)
|
|
113
|
+
parser = VarphiParser(token_stream)
|
|
114
|
+
parser.removeErrorListeners()
|
|
115
|
+
parser.addErrorListener(error_listener)
|
|
116
|
+
parse_tree = parser.program()
|
|
117
|
+
walker = ParseTreeWalker()
|
|
118
|
+
walker.walk(compiler, parse_tree)
|
|
119
|
+
return compiler.generate_compiled_program()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Data model for representing Varphi language programs.
|
|
2
|
+
|
|
3
|
+
This module provides the core data types for representing Varphi programs
|
|
4
|
+
(Turing machine descriptions) including tape characters, head directions,
|
|
5
|
+
and transition rules.
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
VarphiTapeCharacter: Enum for possible tape characters (0, 1).
|
|
9
|
+
VarphiHeadDirection: Enum for head movement directions (L, R).
|
|
10
|
+
VarphiLine: Dataclass representing a single transition rule.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
|
|
16
|
+
class VarphiTapeCharacter(Enum):
|
|
17
|
+
"""Represents the possible characters on a Turing machine tape.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
BLANK: Represents the blank/empty tape cell (character '0').
|
|
21
|
+
ONE: Represents the marked tape cell (character '1').
|
|
22
|
+
"""
|
|
23
|
+
BLANK = "0"
|
|
24
|
+
ONE = "1"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VarphiHeadDirection(Enum):
|
|
28
|
+
"""Represents the possible head movement directions for the Turing machine head.
|
|
29
|
+
|
|
30
|
+
Attributes:
|
|
31
|
+
LEFT: Move the head one position to the left (character 'L').
|
|
32
|
+
RIGHT: Move the head one position to the right (character 'R').
|
|
33
|
+
"""
|
|
34
|
+
LEFT = "L"
|
|
35
|
+
RIGHT = "R"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class VarphiLine:
|
|
40
|
+
"""Represents a single line (transition rule) in a Varphi program.
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
if_state: current state
|
|
44
|
+
if_condition: current tape character
|
|
45
|
+
then_state: next state
|
|
46
|
+
then_character: character to write
|
|
47
|
+
then_direction: direction to move the head
|
|
48
|
+
"""
|
|
49
|
+
if_state: str
|
|
50
|
+
if_condition: VarphiTapeCharacter
|
|
51
|
+
then_state: str
|
|
52
|
+
then_character: VarphiTapeCharacter
|
|
53
|
+
then_direction: VarphiHeadDirection
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
grammar Varphi;
|
|
2
|
+
|
|
3
|
+
// Parser rules
|
|
4
|
+
program : line* EOF;
|
|
5
|
+
line : STATE TAPE_CHARACTER STATE TAPE_CHARACTER HEAD_DIRECTION;
|
|
6
|
+
|
|
7
|
+
// Lexer rules
|
|
8
|
+
fragment LEFT : 'L';
|
|
9
|
+
fragment RIGHT : 'R';
|
|
10
|
+
fragment TALLY : '1';
|
|
11
|
+
fragment BLANK : '0';
|
|
12
|
+
|
|
13
|
+
STATE : 'q'[a-zA-Z0-9_]+;
|
|
14
|
+
TAPE_CHARACTER : TALLY | BLANK;
|
|
15
|
+
HEAD_DIRECTION : LEFT | RIGHT;
|
|
16
|
+
|
|
17
|
+
// Single-line comment (starts with // and ends at the end of the line)
|
|
18
|
+
COMMENT : '//' ~[\r\n]* -> skip;
|
|
19
|
+
|
|
20
|
+
// Multi-line comment (starts with /* and ends with */, can span multiple lines)
|
|
21
|
+
MULTI_COMMENT : '/*' .*? '*/' -> skip;
|
|
22
|
+
|
|
23
|
+
// Skip unnecessary whitespaces
|
|
24
|
+
WHITESPACE : [ \t\r\n]+ -> skip;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Varphi Syntax Module
|
|
3
|
+
|
|
4
|
+
This module provides syntax analysis components for the Varphi language.
|
|
5
|
+
|
|
6
|
+
Components:
|
|
7
|
+
- VarphiLexer: Tokenizes Varphi source code
|
|
8
|
+
- VarphiParser: Parses tokens into parse tree
|
|
9
|
+
- VarphiListener: Provides callback interface for parse tree traversal
|
|
10
|
+
- VarphiSyntaxError: Exception for syntax errors
|
|
11
|
+
- VarphiSyntaxErrorListener: Error handler for parsing
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# Error handling components
|
|
15
|
+
from .error_listener import VarphiSyntaxError, VarphiSyntaxErrorListener
|
|
16
|
+
|
|
17
|
+
# ANTLR generated components
|
|
18
|
+
from .antlr.VarphiLexer import VarphiLexer
|
|
19
|
+
from .antlr.VarphiParser import VarphiParser
|
|
20
|
+
from .antlr.VarphiListener import VarphiListener
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"VarphiSyntaxError",
|
|
24
|
+
"VarphiSyntaxErrorListener",
|
|
25
|
+
"VarphiLexer",
|
|
26
|
+
"VarphiParser",
|
|
27
|
+
"VarphiListener",
|
|
28
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Generated from src/varphi_devkit/syntax/Varphi.g4 by ANTLR 4.13.2
|
|
2
|
+
from antlr4 import *
|
|
3
|
+
from io import StringIO
|
|
4
|
+
import sys
|
|
5
|
+
if sys.version_info[1] > 5:
|
|
6
|
+
from typing import TextIO
|
|
7
|
+
else:
|
|
8
|
+
from typing.io import TextIO
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def serializedATN():
|
|
12
|
+
return [
|
|
13
|
+
4,0,6,75,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,
|
|
14
|
+
6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,1,0,1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,
|
|
15
|
+
4,1,4,4,4,32,8,4,11,4,12,4,33,1,5,1,5,3,5,38,8,5,1,6,1,6,3,6,42,
|
|
16
|
+
8,6,1,7,1,7,1,7,1,7,5,7,48,8,7,10,7,12,7,51,9,7,1,7,1,7,1,8,1,8,
|
|
17
|
+
1,8,1,8,5,8,59,8,8,10,8,12,8,62,9,8,1,8,1,8,1,8,1,8,1,8,1,9,4,9,
|
|
18
|
+
70,8,9,11,9,12,9,71,1,9,1,9,1,60,0,10,1,0,3,0,5,0,7,0,9,1,11,2,13,
|
|
19
|
+
3,15,4,17,5,19,6,1,0,3,4,0,48,57,65,90,95,95,97,122,2,0,10,10,13,
|
|
20
|
+
13,3,0,9,10,13,13,32,32,76,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,
|
|
21
|
+
0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,1,21,1,0,0,0,3,23,1,0,0,0,
|
|
22
|
+
5,25,1,0,0,0,7,27,1,0,0,0,9,29,1,0,0,0,11,37,1,0,0,0,13,41,1,0,0,
|
|
23
|
+
0,15,43,1,0,0,0,17,54,1,0,0,0,19,69,1,0,0,0,21,22,5,76,0,0,22,2,
|
|
24
|
+
1,0,0,0,23,24,5,82,0,0,24,4,1,0,0,0,25,26,5,49,0,0,26,6,1,0,0,0,
|
|
25
|
+
27,28,5,48,0,0,28,8,1,0,0,0,29,31,5,113,0,0,30,32,7,0,0,0,31,30,
|
|
26
|
+
1,0,0,0,32,33,1,0,0,0,33,31,1,0,0,0,33,34,1,0,0,0,34,10,1,0,0,0,
|
|
27
|
+
35,38,3,5,2,0,36,38,3,7,3,0,37,35,1,0,0,0,37,36,1,0,0,0,38,12,1,
|
|
28
|
+
0,0,0,39,42,3,1,0,0,40,42,3,3,1,0,41,39,1,0,0,0,41,40,1,0,0,0,42,
|
|
29
|
+
14,1,0,0,0,43,44,5,47,0,0,44,45,5,47,0,0,45,49,1,0,0,0,46,48,8,1,
|
|
30
|
+
0,0,47,46,1,0,0,0,48,51,1,0,0,0,49,47,1,0,0,0,49,50,1,0,0,0,50,52,
|
|
31
|
+
1,0,0,0,51,49,1,0,0,0,52,53,6,7,0,0,53,16,1,0,0,0,54,55,5,47,0,0,
|
|
32
|
+
55,56,5,42,0,0,56,60,1,0,0,0,57,59,9,0,0,0,58,57,1,0,0,0,59,62,1,
|
|
33
|
+
0,0,0,60,61,1,0,0,0,60,58,1,0,0,0,61,63,1,0,0,0,62,60,1,0,0,0,63,
|
|
34
|
+
64,5,42,0,0,64,65,5,47,0,0,65,66,1,0,0,0,66,67,6,8,0,0,67,18,1,0,
|
|
35
|
+
0,0,68,70,7,2,0,0,69,68,1,0,0,0,70,71,1,0,0,0,71,69,1,0,0,0,71,72,
|
|
36
|
+
1,0,0,0,72,73,1,0,0,0,73,74,6,9,0,0,74,20,1,0,0,0,7,0,33,37,41,49,
|
|
37
|
+
60,71,1,6,0,0
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
class VarphiLexer(Lexer):
|
|
41
|
+
|
|
42
|
+
atn = ATNDeserializer().deserialize(serializedATN())
|
|
43
|
+
|
|
44
|
+
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
|
45
|
+
|
|
46
|
+
STATE = 1
|
|
47
|
+
TAPE_CHARACTER = 2
|
|
48
|
+
HEAD_DIRECTION = 3
|
|
49
|
+
COMMENT = 4
|
|
50
|
+
MULTI_COMMENT = 5
|
|
51
|
+
WHITESPACE = 6
|
|
52
|
+
|
|
53
|
+
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
|
54
|
+
|
|
55
|
+
modeNames = [ "DEFAULT_MODE" ]
|
|
56
|
+
|
|
57
|
+
literalNames = [ "<INVALID>",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
symbolicNames = [ "<INVALID>",
|
|
61
|
+
"STATE", "TAPE_CHARACTER", "HEAD_DIRECTION", "COMMENT", "MULTI_COMMENT",
|
|
62
|
+
"WHITESPACE" ]
|
|
63
|
+
|
|
64
|
+
ruleNames = [ "LEFT", "RIGHT", "TALLY", "BLANK", "STATE", "TAPE_CHARACTER",
|
|
65
|
+
"HEAD_DIRECTION", "COMMENT", "MULTI_COMMENT", "WHITESPACE" ]
|
|
66
|
+
|
|
67
|
+
grammarFileName = "Varphi.g4"
|
|
68
|
+
|
|
69
|
+
def __init__(self, input=None, output:TextIO = sys.stdout):
|
|
70
|
+
super().__init__(input, output)
|
|
71
|
+
self.checkVersion("4.13.2")
|
|
72
|
+
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
|
73
|
+
self._actions = None
|
|
74
|
+
self._predicates = None
|
|
75
|
+
|
|
76
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Generated from src/varphi_devkit/syntax/Varphi.g4 by ANTLR 4.13.2
|
|
2
|
+
from antlr4 import *
|
|
3
|
+
if "." in __name__:
|
|
4
|
+
from .VarphiParser import VarphiParser
|
|
5
|
+
else:
|
|
6
|
+
from VarphiParser import VarphiParser
|
|
7
|
+
|
|
8
|
+
# This class defines a complete listener for a parse tree produced by VarphiParser.
|
|
9
|
+
class VarphiListener(ParseTreeListener):
|
|
10
|
+
|
|
11
|
+
# Enter a parse tree produced by VarphiParser#program.
|
|
12
|
+
def enterProgram(self, ctx:VarphiParser.ProgramContext):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
# Exit a parse tree produced by VarphiParser#program.
|
|
16
|
+
def exitProgram(self, ctx:VarphiParser.ProgramContext):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Enter a parse tree produced by VarphiParser#line.
|
|
21
|
+
def enterLine(self, ctx:VarphiParser.LineContext):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
# Exit a parse tree produced by VarphiParser#line.
|
|
25
|
+
def exitLine(self, ctx:VarphiParser.LineContext):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
del VarphiParser
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Generated from src/varphi_devkit/syntax/Varphi.g4 by ANTLR 4.13.2
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
from antlr4 import *
|
|
4
|
+
from io import StringIO
|
|
5
|
+
import sys
|
|
6
|
+
if sys.version_info[1] > 5:
|
|
7
|
+
from typing import TextIO
|
|
8
|
+
else:
|
|
9
|
+
from typing.io import TextIO
|
|
10
|
+
|
|
11
|
+
def serializedATN():
|
|
12
|
+
return [
|
|
13
|
+
4,1,6,19,2,0,7,0,2,1,7,1,1,0,5,0,6,8,0,10,0,12,0,9,9,0,1,0,1,0,1,
|
|
14
|
+
1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,2,0,2,0,0,17,0,7,1,0,0,0,2,12,1,0,
|
|
15
|
+
0,0,4,6,3,2,1,0,5,4,1,0,0,0,6,9,1,0,0,0,7,5,1,0,0,0,7,8,1,0,0,0,
|
|
16
|
+
8,10,1,0,0,0,9,7,1,0,0,0,10,11,5,0,0,1,11,1,1,0,0,0,12,13,5,1,0,
|
|
17
|
+
0,13,14,5,2,0,0,14,15,5,1,0,0,15,16,5,2,0,0,16,17,5,3,0,0,17,3,1,
|
|
18
|
+
0,0,0,1,7
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
class VarphiParser ( Parser ):
|
|
22
|
+
|
|
23
|
+
grammarFileName = "Varphi.g4"
|
|
24
|
+
|
|
25
|
+
atn = ATNDeserializer().deserialize(serializedATN())
|
|
26
|
+
|
|
27
|
+
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
|
28
|
+
|
|
29
|
+
sharedContextCache = PredictionContextCache()
|
|
30
|
+
|
|
31
|
+
literalNames = [ ]
|
|
32
|
+
|
|
33
|
+
symbolicNames = [ "<INVALID>", "STATE", "TAPE_CHARACTER", "HEAD_DIRECTION",
|
|
34
|
+
"COMMENT", "MULTI_COMMENT", "WHITESPACE" ]
|
|
35
|
+
|
|
36
|
+
RULE_program = 0
|
|
37
|
+
RULE_line = 1
|
|
38
|
+
|
|
39
|
+
ruleNames = [ "program", "line" ]
|
|
40
|
+
|
|
41
|
+
EOF = Token.EOF
|
|
42
|
+
STATE=1
|
|
43
|
+
TAPE_CHARACTER=2
|
|
44
|
+
HEAD_DIRECTION=3
|
|
45
|
+
COMMENT=4
|
|
46
|
+
MULTI_COMMENT=5
|
|
47
|
+
WHITESPACE=6
|
|
48
|
+
|
|
49
|
+
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
|
50
|
+
super().__init__(input, output)
|
|
51
|
+
self.checkVersion("4.13.2")
|
|
52
|
+
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
|
|
53
|
+
self._predicates = None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ProgramContext(ParserRuleContext):
|
|
59
|
+
__slots__ = 'parser'
|
|
60
|
+
|
|
61
|
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
|
62
|
+
super().__init__(parent, invokingState)
|
|
63
|
+
self.parser = parser
|
|
64
|
+
|
|
65
|
+
def EOF(self):
|
|
66
|
+
return self.getToken(VarphiParser.EOF, 0)
|
|
67
|
+
|
|
68
|
+
def line(self, i:int=None):
|
|
69
|
+
if i is None:
|
|
70
|
+
return self.getTypedRuleContexts(VarphiParser.LineContext)
|
|
71
|
+
else:
|
|
72
|
+
return self.getTypedRuleContext(VarphiParser.LineContext,i)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def getRuleIndex(self):
|
|
76
|
+
return VarphiParser.RULE_program
|
|
77
|
+
|
|
78
|
+
def enterRule(self, listener:ParseTreeListener):
|
|
79
|
+
if hasattr( listener, "enterProgram" ):
|
|
80
|
+
listener.enterProgram(self)
|
|
81
|
+
|
|
82
|
+
def exitRule(self, listener:ParseTreeListener):
|
|
83
|
+
if hasattr( listener, "exitProgram" ):
|
|
84
|
+
listener.exitProgram(self)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def program(self):
|
|
90
|
+
|
|
91
|
+
localctx = VarphiParser.ProgramContext(self, self._ctx, self.state)
|
|
92
|
+
self.enterRule(localctx, 0, self.RULE_program)
|
|
93
|
+
self._la = 0 # Token type
|
|
94
|
+
try:
|
|
95
|
+
self.enterOuterAlt(localctx, 1)
|
|
96
|
+
self.state = 7
|
|
97
|
+
self._errHandler.sync(self)
|
|
98
|
+
_la = self._input.LA(1)
|
|
99
|
+
while _la==1:
|
|
100
|
+
self.state = 4
|
|
101
|
+
self.line()
|
|
102
|
+
self.state = 9
|
|
103
|
+
self._errHandler.sync(self)
|
|
104
|
+
_la = self._input.LA(1)
|
|
105
|
+
|
|
106
|
+
self.state = 10
|
|
107
|
+
self.match(VarphiParser.EOF)
|
|
108
|
+
except RecognitionException as re:
|
|
109
|
+
localctx.exception = re
|
|
110
|
+
self._errHandler.reportError(self, re)
|
|
111
|
+
self._errHandler.recover(self, re)
|
|
112
|
+
finally:
|
|
113
|
+
self.exitRule()
|
|
114
|
+
return localctx
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class LineContext(ParserRuleContext):
|
|
118
|
+
__slots__ = 'parser'
|
|
119
|
+
|
|
120
|
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
|
121
|
+
super().__init__(parent, invokingState)
|
|
122
|
+
self.parser = parser
|
|
123
|
+
|
|
124
|
+
def STATE(self, i:int=None):
|
|
125
|
+
if i is None:
|
|
126
|
+
return self.getTokens(VarphiParser.STATE)
|
|
127
|
+
else:
|
|
128
|
+
return self.getToken(VarphiParser.STATE, i)
|
|
129
|
+
|
|
130
|
+
def TAPE_CHARACTER(self, i:int=None):
|
|
131
|
+
if i is None:
|
|
132
|
+
return self.getTokens(VarphiParser.TAPE_CHARACTER)
|
|
133
|
+
else:
|
|
134
|
+
return self.getToken(VarphiParser.TAPE_CHARACTER, i)
|
|
135
|
+
|
|
136
|
+
def HEAD_DIRECTION(self):
|
|
137
|
+
return self.getToken(VarphiParser.HEAD_DIRECTION, 0)
|
|
138
|
+
|
|
139
|
+
def getRuleIndex(self):
|
|
140
|
+
return VarphiParser.RULE_line
|
|
141
|
+
|
|
142
|
+
def enterRule(self, listener:ParseTreeListener):
|
|
143
|
+
if hasattr( listener, "enterLine" ):
|
|
144
|
+
listener.enterLine(self)
|
|
145
|
+
|
|
146
|
+
def exitRule(self, listener:ParseTreeListener):
|
|
147
|
+
if hasattr( listener, "exitLine" ):
|
|
148
|
+
listener.exitLine(self)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def line(self):
|
|
154
|
+
|
|
155
|
+
localctx = VarphiParser.LineContext(self, self._ctx, self.state)
|
|
156
|
+
self.enterRule(localctx, 2, self.RULE_line)
|
|
157
|
+
try:
|
|
158
|
+
self.enterOuterAlt(localctx, 1)
|
|
159
|
+
self.state = 12
|
|
160
|
+
self.match(VarphiParser.STATE)
|
|
161
|
+
self.state = 13
|
|
162
|
+
self.match(VarphiParser.TAPE_CHARACTER)
|
|
163
|
+
self.state = 14
|
|
164
|
+
self.match(VarphiParser.STATE)
|
|
165
|
+
self.state = 15
|
|
166
|
+
self.match(VarphiParser.TAPE_CHARACTER)
|
|
167
|
+
self.state = 16
|
|
168
|
+
self.match(VarphiParser.HEAD_DIRECTION)
|
|
169
|
+
except RecognitionException as re:
|
|
170
|
+
localctx.exception = re
|
|
171
|
+
self._errHandler.reportError(self, re)
|
|
172
|
+
self._errHandler.recover(self, re)
|
|
173
|
+
finally:
|
|
174
|
+
self.exitRule()
|
|
175
|
+
return localctx
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ANTLR Generated Components for Varphi Language
|
|
3
|
+
|
|
4
|
+
This module contains the ANTLR-generated lexer, parser, and listener components
|
|
5
|
+
for the Varphi language.
|
|
6
|
+
|
|
7
|
+
Components:
|
|
8
|
+
- VarphiLexer: Generated lexer for tokenizing Varphi source code
|
|
9
|
+
- VarphiParser: Generated parser for creating parse trees
|
|
10
|
+
- VarphiListener: Generated base listener for parse tree traversal
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .VarphiLexer import VarphiLexer
|
|
14
|
+
from .VarphiParser import VarphiParser
|
|
15
|
+
from .VarphiListener import VarphiListener
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"VarphiLexer",
|
|
19
|
+
"VarphiParser",
|
|
20
|
+
"VarphiListener",
|
|
21
|
+
]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Custom error handling for Varphi language syntax errors.
|
|
2
|
+
|
|
3
|
+
This module provides error handling components for the Varphi language parser.
|
|
4
|
+
|
|
5
|
+
Classes:
|
|
6
|
+
VarphiSyntaxError: Custom exception for Varphi syntax errors with line/column info.
|
|
7
|
+
VarphiSyntaxErrorListener: ANTLR4 error listener that formats and raises syntax errors.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from antlr4.error.ErrorListener import ErrorListener
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class VarphiSyntaxError(Exception):
|
|
14
|
+
"""Exception raised for general syntax errors."""
|
|
15
|
+
|
|
16
|
+
line: int
|
|
17
|
+
column: int
|
|
18
|
+
|
|
19
|
+
def __init__(self, message: str, line: int, column: int) -> None:
|
|
20
|
+
"""Initializes a VarphiSyntaxError with a message, line, and column.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
message (str): The error message.
|
|
24
|
+
line (int): The line where the error occurred.
|
|
25
|
+
column (int): The column where the error occurred.
|
|
26
|
+
"""
|
|
27
|
+
super().__init__(message)
|
|
28
|
+
self.line = line
|
|
29
|
+
self.column = column
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class VarphiSyntaxErrorListener(ErrorListener):
|
|
33
|
+
"""Custom error listener for Varphi syntax errors.
|
|
34
|
+
|
|
35
|
+
This listener processes syntax errors and raises an exception with a detailed
|
|
36
|
+
error message, including the specific line and column where the error occurred.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
input_text: list[str]
|
|
40
|
+
|
|
41
|
+
def __init__(self, input_text: str) -> None:
|
|
42
|
+
"""Initializes the VarphiSyntaxErrorListener with the input text.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
input_text (str): The input text to be processed.
|
|
46
|
+
"""
|
|
47
|
+
super().__init__()
|
|
48
|
+
self.input_text = input_text.splitlines()
|
|
49
|
+
|
|
50
|
+
def syntaxError(self, # pylint: disable=too-many-arguments, too-many-positional-arguments
|
|
51
|
+
recognizer,
|
|
52
|
+
offendingSymbol,
|
|
53
|
+
line,
|
|
54
|
+
column,
|
|
55
|
+
msg,
|
|
56
|
+
e
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Handles syntax errors encountered by the parser.
|
|
59
|
+
|
|
60
|
+
Raises a VarphiSyntaxError with detailed information about the error.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
recognizer: The recognizer that encountered the error.
|
|
64
|
+
offending_symbol: The symbol that caused the error.
|
|
65
|
+
line (int): The line number where the error occurred.
|
|
66
|
+
column (int): The column number where the error occurred.
|
|
67
|
+
msg (str): The error message.
|
|
68
|
+
e: The exception that caused the error.
|
|
69
|
+
"""
|
|
70
|
+
error_line = self.input_text[line - 1]
|
|
71
|
+
# Create a line with ^ pointing to the offending symbol
|
|
72
|
+
pointer_line = " " * column + "^"
|
|
73
|
+
|
|
74
|
+
# Format the error message
|
|
75
|
+
error = f"Syntax error at line {line}:{column} - {msg}\n"
|
|
76
|
+
error += f" {error_line}\n"
|
|
77
|
+
error += f" {pointer_line}\n"
|
|
78
|
+
|
|
79
|
+
raise VarphiSyntaxError(error, line, column)
|