compilerlab5 0.1.1__py3-none-any.whl

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.
@@ -0,0 +1,374 @@
1
+ Metadata-Version: 2.4
2
+ Name: compilerlab5
3
+ Version: 0.1.1
4
+ Summary: Five Compiler Design laboratory programs from Experiments 6-10
5
+ Author: Compiler Lab Package
6
+ License: MIT
7
+ Keywords: compiler-design,lalr,slr,three-address-code,shift-reduce,lexical-analyzer
8
+ Requires-Python: >=3.9
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Dynamic: license-file
12
+
13
+ \# compilerlab5
14
+
15
+
16
+
17
+ A pip-installable package containing five Compiler Design laboratory programs based on \*\*Experiment 6-10.pdf\*\*:
18
+
19
+
20
+
21
+ 1\. LALR bottom-up parser demo
22
+
23
+ 2\. SLR(1) parsing demo
24
+
25
+ 3\. Three-address code generator
26
+
27
+ 4\. Lexical analyzer for operators
28
+
29
+ 5\. Shift-reduce parser
30
+
31
+
32
+
33
+ \## Installation
34
+
35
+
36
+
37
+ Install the package from PyPI:
38
+
39
+
40
+
41
+ ```bash
42
+
43
+ python -m pip install compilerlab5
44
+
45
+ ```
46
+
47
+
48
+
49
+ After installation, the package can be used from any supported Python environment.
50
+
51
+
52
+
53
+ \## Usage
54
+
55
+
56
+
57
+ \### 1. LALR Bottom-Up Parser
58
+
59
+
60
+
61
+ ```bash
62
+
63
+ compilerlab5 lalr
64
+
65
+ ```
66
+
67
+
68
+
69
+ Example input:
70
+
71
+
72
+
73
+ ```text
74
+
75
+ i+i\*i
76
+
77
+ ```
78
+
79
+
80
+
81
+ \### 2. SLR(1) Parser
82
+
83
+
84
+
85
+ ```bash
86
+
87
+ compilerlab5 slr
88
+
89
+ ```
90
+
91
+
92
+
93
+ Example input:
94
+
95
+
96
+
97
+ ```text
98
+
99
+ dd
100
+
101
+ ```
102
+
103
+
104
+
105
+ \### 3. Three-Address Code Generator
106
+
107
+
108
+
109
+ ```bash
110
+
111
+ compilerlab5 tac
112
+
113
+ ```
114
+
115
+
116
+
117
+ Example input:
118
+
119
+
120
+
121
+ ```text
122
+
123
+ a+b\*c
124
+
125
+ ```
126
+
127
+
128
+
129
+ \### 4. Lexical Analyzer for Operators
130
+
131
+
132
+
133
+ ```bash
134
+
135
+ compilerlab5 operator
136
+
137
+ ```
138
+
139
+
140
+
141
+ Example input:
142
+
143
+
144
+
145
+ ```text
146
+
147
+ \+
148
+
149
+ ```
150
+
151
+
152
+
153
+ \### 5. Shift-Reduce Parser
154
+
155
+
156
+
157
+ ```bash
158
+
159
+ compilerlab5 shift-reduce
160
+
161
+ ```
162
+
163
+
164
+
165
+ Example input:
166
+
167
+
168
+
169
+ ```text
170
+
171
+ id+id\*id
172
+
173
+ ```
174
+
175
+
176
+
177
+ \## Individual Commands
178
+
179
+
180
+
181
+ The individual console commands are also available:
182
+
183
+
184
+
185
+ ```bash
186
+
187
+ lalr-parser
188
+
189
+ slr-parser
190
+
191
+ tac-generator
192
+
193
+ operator-validator
194
+
195
+ shift-reduce-parser
196
+
197
+ ```
198
+
199
+
200
+
201
+ \## Python Module Usage
202
+
203
+
204
+
205
+ The package can also be executed through Python:
206
+
207
+
208
+
209
+ ```bash
210
+
211
+ python -m cpp lalr
212
+
213
+ python -m cpp slr
214
+
215
+ python -m cpp tac
216
+
217
+ python -m cpp operator
218
+
219
+ python -m cpp shift-reduce
220
+
221
+ ```
222
+
223
+
224
+
225
+ Here, `cpp` is the internal Python package name, while `compilerlab5` is the public PyPI distribution name.
226
+
227
+
228
+
229
+ \## Local Testing
230
+
231
+
232
+
233
+ From the project directory:
234
+
235
+
236
+
237
+ ```bash
238
+
239
+ python -m pip install --upgrade build
240
+
241
+ python -m build
242
+
243
+ ```
244
+
245
+
246
+
247
+ Install the generated wheel:
248
+
249
+
250
+
251
+ ```bash
252
+
253
+ python -m pip install dist/compilerlab5-0.1.1-py3-none-any.whl
254
+
255
+ ```
256
+
257
+
258
+
259
+ \## PyPI Publishing
260
+
261
+
262
+
263
+ Build the package:
264
+
265
+
266
+
267
+ ```bash
268
+
269
+ python -m build
270
+
271
+ ```
272
+
273
+
274
+
275
+ Check the generated distributions:
276
+
277
+
278
+
279
+ ```bash
280
+
281
+ dir dist
282
+
283
+ ```
284
+
285
+
286
+
287
+ Upload the distributions using Twine:
288
+
289
+
290
+
291
+ ```bash
292
+
293
+ python -m twine upload dist/\*
294
+
295
+ ```
296
+
297
+
298
+
299
+ For PyPI authentication, use the username:
300
+
301
+
302
+
303
+ ```text
304
+
305
+ \_\_token\_\_
306
+
307
+ ```
308
+
309
+
310
+
311
+ and a valid PyPI API token as the password.
312
+
313
+
314
+
315
+ \## Portability
316
+
317
+
318
+
319
+ The Python package does \*\*not\*\* require GCC or Clang to run the Python implementations.
320
+
321
+
322
+
323
+ Python is required on the target system.
324
+
325
+
326
+
327
+ The original C source files from the supplied \*\*Experiment 6-10.pdf\*\* are also included under:
328
+
329
+
330
+
331
+ ```text
332
+
333
+ src/cpp/c\_sources/
334
+
335
+ ```
336
+
337
+
338
+
339
+ These source files are included for laboratory/reference purposes.
340
+
341
+
342
+
343
+ \## Package Information
344
+
345
+
346
+
347
+ \*\*Distribution name:\*\* `compilerlab5`
348
+
349
+
350
+
351
+ \*\*Python package/module:\*\* `cpp`
352
+
353
+
354
+
355
+ \*\*Current version:\*\* `0.1.1`
356
+
357
+
358
+
359
+ \*\*License:\*\* MIT
360
+
361
+
362
+
363
+ \## Educational Purpose
364
+
365
+
366
+
367
+ This is a teaching/laboratory package containing examples for Compiler Design experiments 6-10.
368
+
369
+
370
+
371
+ The parser examples intentionally follow the structure and terminology of the supplied laboratory material and are intended for educational use rather than as a production compiler toolkit.
372
+
373
+
374
+
@@ -0,0 +1,19 @@
1
+ compilerlab5-0.1.1.dist-info/licenses/LICENSE,sha256=FZMl_KxZ3I8Ajtguk5x4g3NhIXqG-L49BIUpHP5GpX0,659
2
+ cpp/__init__.py,sha256=8EOxaXdnube-I32_fswktrTi6m7XzRy7b33uoC3i1xc,88
3
+ cpp/__main__.py,sha256=EClCwCzb6h6YBpt0hrnG4h0mlNhNePyg_xBNNSVm1os,65
4
+ cpp/cli.py,sha256=sA0xHsvyf8jqxQiDbaH7k8h3VT44p6rJVrh13ruprXI,513
5
+ cpp/lalr.py,sha256=eHsbHIT8AfJxwaL6081iSxwrKHHmQWF_NdvjPT4JZqg,1049
6
+ cpp/operator.py,sha256=BFrpeZt9f3RxNks7OgdqDglF5Oi63enMgB4utyMsymU,1361
7
+ cpp/shift_reduce.py,sha256=DJ6Ab8qflBLtKGFEksOK14sryUoz-yVB10wgujQK-nw,1998
8
+ cpp/slr.py,sha256=nGNTleNHCO70oES3sGHRkZjD8ykGO_IOG2LERC6R17M,724
9
+ cpp/tac.py,sha256=MCs-aYek40GbZgwoehOIjvnKHW2g1-WGoIXh0xlZH4k,1303
10
+ cpp/c_sources/01_lalr_bottom_up.c,sha256=c4NhvcdjpIk48izCpqaZrH-k1ViN2ZWTy_gDD_4WgWw,813
11
+ cpp/c_sources/02_slr1_parser.c,sha256=7KAvuaWvUHYQISWDYwh9Ia3QTs7Ynn1Ybg2WW33Zuf0,1497
12
+ cpp/c_sources/03_three_address_code.c,sha256=ytSSUdpDwtLkAOo9wGSiSazQYjAp7TNTpKHF2mMnFOc,1462
13
+ cpp/c_sources/04_operator_lexical_analyzer.c,sha256=sBkSLiLLkvoSJokqYnGrKIe3qOsLq3shrGCw2Oq7P68,1805
14
+ cpp/c_sources/05_shift_reduce_parser.c,sha256=oORINMK1GUXpLUWnAZr_G_MQEw-lIHAkDV5h2f8KDpQ,1406
15
+ compilerlab5-0.1.1.dist-info/METADATA,sha256=IXf682qJRfKF-zsOdiXcLfDJ03VkSgnfvacViyiltVc,3738
16
+ compilerlab5-0.1.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
17
+ compilerlab5-0.1.1.dist-info/entry_points.txt,sha256=UETMSrtoZk72OdIBMaD-RT2t7n4YzH7nQ93T52Jrm2Y,212
18
+ compilerlab5-0.1.1.dist-info/top_level.txt,sha256=st3_n7dR9Y75QOgD4nJcJed-luRnmOMrSoGkUl0VO1I,4
19
+ compilerlab5-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,7 @@
1
+ [console_scripts]
2
+ compilerlab5 = cpp.cli:main
3
+ lalr-parser = cpp.lalr:main
4
+ operator-validator = cpp.operator:main
5
+ shift-reduce-parser = cpp.shift_reduce:main
6
+ slr-parser = cpp.slr:main
7
+ tac-generator = cpp.tac:main
@@ -0,0 +1,15 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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.
@@ -0,0 +1 @@
1
+ cpp
cpp/__init__.py ADDED
@@ -0,0 +1,2 @@
1
+ """Five Compiler Design laboratory programs, packaged for pip."""
2
+ __version__ = "0.1.0"
cpp/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,23 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ char stack[50]; int top = -1;
4
+ void push(char c) { stack[++top] = c; }
5
+ void pop(int n) { top -= n; }
6
+ int main() {
7
+ char input[50]; int i = 0;
8
+ printf("Enter string (e.g., i+i*i): "); scanf("%49s", input);
9
+ push('$');
10
+ while (input[i] != '\0') {
11
+ if (input[i] == 'i') {
12
+ push('F'); printf("Shift i, Reduce F->i\n");
13
+ stack[top] = 'T'; printf("Reduce T->F\n");
14
+ stack[top] = 'E'; printf("Reduce E->T\n");
15
+ } else if (input[i] == '+' || input[i] == '*') {
16
+ push(input[i]); printf("Shift %c\n", input[i]);
17
+ } else { printf("Rejected\n"); return 0; }
18
+ i++;
19
+ }
20
+ if (top >= 2 && stack[top] == 'E') printf("Accepted by LALR Bottom-Up Parser\n");
21
+ else printf("Rejected\n");
22
+ return 0;
23
+ }
@@ -0,0 +1,37 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <stdlib.h>
4
+ char input[20]; int ip = 0;
5
+ int main() {
6
+ int stateStack[20], top = 0; stateStack[top] = 0;
7
+ printf("Enter input string: "); scanf("%19s", input); strcat(input, "$");
8
+ while (1) {
9
+ int state = stateStack[top]; char symbol = input[ip];
10
+ switch (state) {
11
+ case 0:
12
+ if (symbol == 'c') { stateStack[++top] = 3; ip++; }
13
+ else if (symbol == 'd') { stateStack[++top] = 4; ip++; }
14
+ else { printf("Rejected\n"); return 0; }
15
+ break;
16
+ case 1:
17
+ if (symbol == '$') { printf("Accepted\n"); return 0; }
18
+ printf("Rejected\n"); return 0;
19
+ case 2:
20
+ if (symbol == 'c') { stateStack[++top] = 3; ip++; }
21
+ else if (symbol == 'd') { stateStack[++top] = 4; ip++; }
22
+ else { printf("Rejected\n"); return 0; }
23
+ break;
24
+ case 3:
25
+ /* The supplied experiment omits the full state-3 transition table. */
26
+ printf("Rejected\n"); return 0;
27
+ case 4:
28
+ top--; state = stateStack[top];
29
+ if (state == 0) stateStack[++top] = 2;
30
+ else if (state == 2) stateStack[++top] = 5;
31
+ else { printf("Rejected\n"); return 0; }
32
+ break;
33
+ case 5: printf("Accepted\n"); return 0;
34
+ default: printf("Rejected\n"); return 0;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,33 @@
1
+ #include <stdio.h>
2
+ #include <ctype.h>
3
+ #include <string.h>
4
+ char input[50]; int tempCount = 1;
5
+ void printTAC(char op, char a, char b) { printf("t%d = %c %c %c\n", tempCount, a, op, b); tempCount++; }
6
+ int precedence(char c) { if (c=='+'||c=='-') return 1; if(c=='*'||c=='/') return 2; return 0; }
7
+ int main() {
8
+ char opStack[50], valStack[50]; int topOp=-1, topVal=-1;
9
+ printf("Enter expression: "); scanf("%49s", input);
10
+ for (int i=0; input[i]!='\0'; i++) {
11
+ char ch=input[i];
12
+ if (isalnum((unsigned char)ch)) valStack[++topVal]=ch;
13
+ else if (ch=='(') opStack[++topOp]=ch;
14
+ else if (ch==')') {
15
+ while(topOp!=-1 && opStack[topOp]!='(') {
16
+ char op=opStack[topOp--], b=valStack[topVal--], a=valStack[topVal--];
17
+ printTAC(op,a,b); valStack[++topVal]='t'+tempCount-1;
18
+ }
19
+ if(topOp!=-1) topOp--;
20
+ } else {
21
+ while(topOp!=-1 && opStack[topOp]!='(' && precedence(opStack[topOp])>=precedence(ch)) {
22
+ char op=opStack[topOp--], b=valStack[topVal--], a=valStack[topVal--];
23
+ printTAC(op,a,b); valStack[++topVal]='t'+tempCount-1;
24
+ }
25
+ opStack[++topOp]=ch;
26
+ }
27
+ }
28
+ while(topOp!=-1) {
29
+ char op=opStack[topOp--], b=valStack[topVal--], a=valStack[topVal--];
30
+ printTAC(op,a,b); valStack[++topVal]='t'+tempCount-1;
31
+ }
32
+ printf("Final result stored in t%d\n", tempCount-1); return 0;
33
+ }
@@ -0,0 +1,24 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ void validateOperator(const char *op) {
4
+ if(strlen(op)==1) {
5
+ switch(op[0]) {
6
+ case '+': case '-': case '*': case '/': case '%': printf("'%s' is a Valid Arithmetic Operator.\n",op); return;
7
+ case '<': case '>': printf("'%s' is a Valid Relational Operator.\n",op); return;
8
+ case '=': printf("'%s' is a Valid Assignment Operator.\n",op); return;
9
+ case '!': printf("'%s' is a Valid Logical NOT Operator.\n",op); return;
10
+ case '&': case '|': case '^': case '~': printf("'%s' is a Valid Bitwise Operator.\n",op); return;
11
+ case '?': case ':': printf("'%s' is a Valid Conditional/Ternary Operator.\n",op); return;
12
+ }
13
+ }
14
+ if(strlen(op)==2) {
15
+ if(!strcmp(op,"++")||!strcmp(op,"--")) { printf("'%s' is a Valid Increment/Decrement Operator.\n",op); return; }
16
+ if(!strcmp(op,"==")||!strcmp(op,"!=")||!strcmp(op,"<=")||!strcmp(op,">=")) { printf("'%s' is a Valid Relational Operator.\n",op); return; }
17
+ if(!strcmp(op,"&&")||!strcmp(op,"||")) { printf("'%s' is a Valid Logical Operator.\n",op); return; }
18
+ if(!strcmp(op,"+=")||!strcmp(op,"-=")||!strcmp(op,"*=")||!strcmp(op,"/=")||!strcmp(op,"%=")) { printf("'%s' is a Valid Compound Assignment Operator.\n",op); return; }
19
+ if(!strcmp(op,"<<")||!strcmp(op,">>")) { printf("'%s' is a Valid Bitwise Shift Operator.\n",op); return; }
20
+ }
21
+ if(strlen(op)==3 && (!strcmp(op,"<<=")||!strcmp(op,">>="))) { printf("'%s' is a Valid Compound Bitwise Shift Operator.\n",op); return; }
22
+ printf("'%s' is an INVALID Operator.\n",op);
23
+ }
24
+ int main(){ char input[10]; printf("--- Lexical Analyzer: Operator Validator ---\nEnter a symbol to validate: "); if(scanf("%9s",input)==1) validateOperator(input); return 0; }
@@ -0,0 +1,21 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ char stack[100], input[100]; int top=-1, ip=0;
4
+ void displayStack(){ for(int i=0;i<=top;i++) printf("%c",stack[i]); }
5
+ void reduce() {
6
+ if(top>=1 && stack[top-1]=='i' && stack[top]=='d'){ stack[top-1]='E'; top--; printf("Reduce: E -> id\n"); return; }
7
+ if(top>=2 && stack[top-2]=='(' && stack[top-1]=='E' && stack[top]==')'){ top-=2; stack[top]='E'; printf("Reduce: E -> (E)\n"); return; }
8
+ if(top>=2 && stack[top-2]=='E' && stack[top-1]=='+' && stack[top]=='E'){ top-=2; stack[top]='E'; printf("Reduce: E -> E+E\n"); return; }
9
+ if(top>=2 && stack[top-2]=='E' && stack[top-1]=='*' && stack[top]=='E'){ top-=2; stack[top]='E'; printf("Reduce: E -> E*E\n"); return; }
10
+ }
11
+ int main(){
12
+ printf("SHIFT-REDUCE PARSER\n--------------------\nGrammar:\nE -> E+E\nE -> E*E\nE -> (E)\nE -> id\n\nEnter input string (use id for identifier): ");
13
+ scanf("%99s",input);
14
+ printf("\n%-15s %-15s %-20s\n","Stack","Input","Action");
15
+ printf("-----------------------------------------------\n");
16
+ while(input[ip]!='\0'){ stack[++top]=input[ip++]; printf("%-15s %-15s Shift %c\n",stack,input+ip,stack[top]); reduce(); }
17
+ while(1){ int oldTop=top; reduce(); if(oldTop==top) break; }
18
+ printf("\nFinal Stack: "); displayStack();
19
+ if(top==0 && stack[0]=='E') printf("\n\nInput string ACCEPTED.\n"); else printf("\n\nInput string REJECTED.\n");
20
+ return 0;
21
+ }
cpp/cli.py ADDED
@@ -0,0 +1,19 @@
1
+ import argparse
2
+ from . import lalr, slr, tac, operator, shift_reduce
3
+
4
+ COMMANDS = {
5
+ "lalr": lalr.main,
6
+ "slr": slr.main,
7
+ "tac": tac.main,
8
+ "operator": operator.main,
9
+ "shift-reduce": shift_reduce.main,
10
+ }
11
+
12
+ def main():
13
+ p=argparse.ArgumentParser(prog="cpp", description="Five Compiler Design lab programs")
14
+ p.add_argument("program", nargs="?", choices=COMMANDS, help="Program to run")
15
+ a=p.parse_args()
16
+ if not a.program:
17
+ p.print_help()
18
+ return
19
+ COMMANDS[a.program]()
cpp/lalr.py ADDED
@@ -0,0 +1,34 @@
1
+ """LALR-style bottom-up parser demo based on the supplied Experiment 6-10 PDF.
2
+
3
+ Grammar demonstrated:
4
+ E -> E+T | T
5
+ T -> T*F | F
6
+ F -> i
7
+
8
+ This is a teaching/demo parser, matching the reduction trace style of the source.
9
+ """
10
+ def parse(text: str) -> list[str]:
11
+ text = text.strip()
12
+ if not text:
13
+ return ["Rejected"]
14
+ if any(c not in "i+*" for c in text) or text[0] != "i" or text[-1] != "i":
15
+ return ["Rejected"]
16
+ if "++" in text or "**" in text or "+*" in text or "*+" in text:
17
+ return ["Rejected"]
18
+ out=[]
19
+ expect_operand=True
20
+ for c in text:
21
+ if expect_operand:
22
+ if c!="i": return ["Rejected"]
23
+ out += ["Shift i, Reduce F->i", "Reduce T->F", "Reduce E->T"]
24
+ expect_operand=False
25
+ else:
26
+ if c not in "+*": return ["Rejected"]
27
+ out.append(f"Shift {c}")
28
+ expect_operand=True
29
+ out.append("Accepted by LALR Bottom-Up Parser")
30
+ return out
31
+
32
+ def main():
33
+ s=input("Enter string (e.g., i+i*i): ")
34
+ print("\n".join(parse(s)))
cpp/operator.py ADDED
@@ -0,0 +1,27 @@
1
+ """Lexical analyzer for operators, based on the supplied PDF."""
2
+ def validate_operator(op: str) -> str:
3
+ arithmetic={"+","-","*","/","%"}
4
+ relational={"<",">","==","!=","<=",">="}
5
+ assignment={"="}
6
+ logical={"!","&&","||"}
7
+ bitwise={"&","|","^","~"}
8
+ conditional={"?",":"}
9
+ incdec={"++","--"}
10
+ compound={"+=","-=","*=","/=","%="}
11
+ shifts={"<<",">>"}
12
+ compound_shifts={"<<=",">>="}
13
+ if op in arithmetic: return f"'{op}' is a Valid Arithmetic Operator."
14
+ if op in relational: return f"'{op}' is a Valid Relational Operator."
15
+ if op in assignment: return f"'{op}' is a Valid Assignment Operator."
16
+ if op in logical: return f"'{op}' is a Valid Logical Operator."
17
+ if op in bitwise: return f"'{op}' is a Valid Bitwise Operator."
18
+ if op in conditional: return f"'{op}' is a Valid Conditional/Ternary Operator."
19
+ if op in incdec: return f"'{op}' is a Valid Increment/Decrement Operator."
20
+ if op in compound: return f"'{op}' is a Valid Compound Assignment Operator."
21
+ if op in shifts: return f"'{op}' is a Valid Bitwise Shift Operator."
22
+ if op in compound_shifts: return f"'{op}' is a Valid Compound Bitwise Shift Operator."
23
+ return f"'{op}' is an INVALID Operator."
24
+
25
+ def main():
26
+ print("--- Lexical Analyzer: Operator Validator ---")
27
+ print(validate_operator(input("Enter a symbol to validate: ")))
cpp/shift_reduce.py ADDED
@@ -0,0 +1,56 @@
1
+ """Shift-reduce parser based on the supplied PDF.
2
+
3
+ Grammar:
4
+ E -> E+E
5
+ E -> E*E
6
+ E -> (E)
7
+ E -> id
8
+ """
9
+ def parse(text: str) -> list[tuple[str,str,str]]:
10
+ s=text.strip()
11
+ if not s: return [("", "", "Rejected")]
12
+ tokens=[]
13
+ i=0
14
+ while i<len(s):
15
+ if s.startswith("id",i):
16
+ tokens.append("id"); i+=2
17
+ elif s[i] in "+*()":
18
+ tokens.append(s[i]); i+=1
19
+ else:
20
+ return [("", s[i:], "Rejected")]
21
+ stack=[]; rows=[]
22
+ def reduce_once():
23
+ if len(stack)>=1 and stack[-1]=="id":
24
+ stack[-1]="E"; return "Reduce: E -> id"
25
+ if len(stack)>=3 and stack[-3:] == ["(","E",")"]:
26
+ del stack[-3:]; stack.append("E"); return "Reduce: E -> (E)"
27
+ if len(stack)>=3 and stack[-3:] == ["E","*","E"]:
28
+ del stack[-3:]; stack.append("E"); return "Reduce: E -> E*E"
29
+ if len(stack)>=3 and stack[-3:] == ["E","+","E"]:
30
+ del stack[-3:]; stack.append("E"); return "Reduce: E -> E+E"
31
+ return None
32
+ for idx,tok in enumerate(tokens):
33
+ stack.append(tok)
34
+ rows.append((" ".join(stack)," ".join(tokens[idx+1:]),f"Shift {tok}"))
35
+ # Prefer id/parenthesis reductions immediately, then repeatedly reduce.
36
+ while True:
37
+ act=reduce_once()
38
+ if not act: break
39
+ rows.append((" ".join(stack)," ".join(tokens[idx+1:]),act))
40
+ while True:
41
+ act=reduce_once()
42
+ if not act: break
43
+ rows.append((" ".join(stack),"",act))
44
+ rows.append((" ".join(stack),"","Input string ACCEPTED." if stack==["E"] else "Input string REJECTED."))
45
+ return rows
46
+
47
+ def main():
48
+ print("SHIFT-REDUCE PARSER")
49
+ print("--------------------")
50
+ print("Grammar:")
51
+ print("E -> E+E\nE -> E*E\nE -> (E)\nE -> id\n")
52
+ s=input("Enter input string (use id for identifier): ")
53
+ print("\n{:<15} {:<15} {:<30}".format("Stack","Input","Action"))
54
+ print("-"*65)
55
+ for a,b,c in parse(s):
56
+ print("{:<15} {:<15} {}".format(a,b,c))
cpp/slr.py ADDED
@@ -0,0 +1,29 @@
1
+ """SLR(1) parsing demo based on the supplied PDF.
2
+
3
+ Grammar:
4
+ S -> CC
5
+ C -> cC | d
6
+
7
+ The implementation mirrors the small state-machine example in the source.
8
+ """
9
+ def parse(text: str) -> list[str]:
10
+ s=text.strip()
11
+ if not s:
12
+ return ["Rejected"]
13
+ # For S -> CC, C -> cC | d, valid strings are two C strings.
14
+ def consume_c(i):
15
+ while i < len(s) and s[i] == "c":
16
+ i += 1
17
+ if i < len(s) and s[i] == "d":
18
+ return i+1
19
+ return None
20
+ j=consume_c(0)
21
+ if j is not None and j < len(s):
22
+ k=consume_c(j)
23
+ if k == len(s):
24
+ return ["Accepted"]
25
+ return ["Rejected"]
26
+
27
+ def main():
28
+ s=input("Enter input string: ")
29
+ print("\n".join(parse(s)))
cpp/tac.py ADDED
@@ -0,0 +1,38 @@
1
+ """Three-address code generator based on the supplied PDF."""
2
+ import re
3
+
4
+ def generate(expr: str) -> list[str]:
5
+ expr=expr.strip()
6
+ if not expr:
7
+ raise ValueError("Expression cannot be empty")
8
+ if not re.fullmatch(r"[A-Za-z0-9()+*/-]+", expr):
9
+ raise ValueError("Only identifiers/numbers, + - * / and parentheses are supported")
10
+ precedence={"+":1,"-":1,"*":2,"/":2}
11
+ ops=[]; vals=[]; out=[]; n=1
12
+ def emit():
13
+ nonlocal n
14
+ op=ops.pop()
15
+ b=vals.pop(); a=vals.pop()
16
+ t=f"t{n}"
17
+ out.append(f"{t} = {a} {op} {b}")
18
+ vals.append(t); n+=1
19
+ for ch in expr:
20
+ if ch.isalnum(): vals.append(ch)
21
+ elif ch=="(": ops.append(ch)
22
+ elif ch==")":
23
+ while ops and ops[-1]!="(": emit()
24
+ if not ops: raise ValueError("Mismatched parentheses")
25
+ ops.pop()
26
+ else:
27
+ while ops and ops[-1]!="(" and precedence[ops[-1]]>=precedence[ch]:
28
+ emit()
29
+ ops.append(ch)
30
+ while ops:
31
+ if ops[-1]=="(": raise ValueError("Mismatched parentheses")
32
+ emit()
33
+ if len(vals)!=1: raise ValueError("Invalid expression")
34
+ out.append(f"Final result stored in {vals[0]}")
35
+ return out
36
+
37
+ def main():
38
+ print("\n".join(generate(input("Enter expression: "))))