├── README.md ├── ast ├── for.py ├── st.py └── tester │ ├── LICENSE │ ├── README.md │ ├── parse_python_to_json.py │ ├── pythonparser │ ├── __init__.py │ ├── __init__.pyc │ ├── __main__.py │ ├── algorithm.py │ ├── ast.py │ ├── ast.pyc │ ├── diagnostic.py │ ├── diagnostic.pyc │ ├── lexer.py │ ├── lexer.pyc │ ├── parser.py │ ├── parser.pyc │ ├── source.py │ └── source.pyc │ └── test.py ├── lexer ├── code ├── for.py ├── lex.py ├── st.py ├── symbol_table ├── symbol_table.csv ├── temp.py └── test.py ├── optimization ├── o.txt ├── optimize.py └── output_file.txt └── parser and icg ├── bin ├── 2lex_cleaner.py ├── 2lex_cleaner.pyc ├── __pycache__ │ ├── lex.cpython-36.pyc │ ├── parsetab.cpython-36.pyc │ └── yacc.cpython-36.pyc ├── a.txt ├── code.py ├── code.pyc ├── converter.py ├── converter.pyc ├── dump ├── irgen ├── irgen~ ├── lex.py ├── lex.pyc ├── lexer.py ├── lexer.pyc ├── op ├── op.py ├── op.pyc ├── out.txt ├── parser.out ├── parser.pyc ├── parsetab.py ├── parsetab.pyc ├── pcom.py ├── pcom.pyc ├── pyac.py ├── pyac.pyc ├── st ├── symbolTable.py ├── symbolTable.pyc ├── symbol_table.csv ├── tac.py ├── tac.pyc ├── temp.py ├── temp.pyc ├── test2.out ├── yacc.py └── yacc.pyc ├── dump ├── makefile ├── op.py ├── parsetab.pyc ├── pyac.py ├── pyac.py~ ├── readme.md ├── src ├── converter.py ├── lex.py ├── lexer.py ├── parser.py ├── symbolTable.py ├── tac.py └── yacc.py ├── st ├── symbol_table.csv ├── test.py ├── test.py~ └── test ├── assignment.py ├── conti.py ├── dead.py ├── dead.py.save ├── expr.py ├── extra.py ├── for.py ├── func.py ├── if.py ├── op.py ├── ot.txt ├── out.txt ├── temp.py ├── test.py ├── test1.out ├── test1.py ├── testfor.py ├── tf.py └── while.py /README.md: -------------------------------------------------------------------------------- 1 | # MyPythonCompiler 2 | 3 | As a part of my Compiler Design Project, I have created a python compiler from scratch using the same Grammar Rules for Python. This Compiler is designed only for python code structures with loops and uses PLY tools and is written in Python itself. 4 | 5 | There are 4 stages of this project 6 | 1) THE LEXER (inclusive of ignoring singluar and multiple comments) 7 | 2) PARSER (inclusive of identation handling) 8 | 3) INTERMEDIATE CODE GENERATION AND BUILDING AN ABSTRACT SYNTAX TREE 9 | 4) CODE OPTIMIZATION 10 | 11 | THE MAIN CHALLENGE WAS TO DEAL WITH INDENTATION AS FAR THE LANGUAGE PYTHON IS CONCERNED 12 | -------------------------------------------------------------------------------- /ast/for.py: -------------------------------------------------------------------------------- 1 | #Code to implement for loop 2 | a = [1, 2, 3, 9, 7, 3] 3 | b=1 4 | #2 variales 5 | for i in a: 6 | c = i * i + 3 / 2 7 | for var in [1,3,6,7]: 8 | print(var*var) 9 | -------------------------------------------------------------------------------- /ast/st.py: -------------------------------------------------------------------------------- 1 | import json 2 | from ast import parse 3 | from ast2json import ast2json 4 | 5 | ast = ast2json(parse(open('for.py').read())) 6 | print (json.dumps(ast, indent=4)) 7 | -------------------------------------------------------------------------------- /ast/tester/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Philip Guo 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 | -------------------------------------------------------------------------------- /ast/tester/README.md: -------------------------------------------------------------------------------- 1 | # python-parse-to-json 2 | 3 | Parse Python code to an AST in JSON format, based upon https://github.com/m-labs/pythonparser/ 4 | 5 | Created on 2017-01-20 by Philip Guo 6 | 7 | 15-minute tutorial video: https://www.youtube.com/watch?v=wK_VVajpolI 8 | 9 | --- 10 | 11 | Forked the HEAD of https://github.com/m-labs/pythonparser/ on 2017-01-20 into here and simplified it. 12 | 13 | hello! 14 | 15 | Example usage: 16 | 17 | ``` 18 | $ python parse_python_to_json.py --pp ' 19 | > def foo(a, b, *c): 20 | > y = a + (b - c) 21 | > return y 22 | > ' 23 | { 24 | "body": [ 25 | { 26 | "body": [ 27 | { 28 | "loc": { 29 | "start": { 30 | "column": 2, 31 | "line": 3 32 | }, 33 | "end": { 34 | "column": 16, 35 | "line": 3 36 | } 37 | }, 38 | "_fields": [ 39 | "targets", 40 | "value" 41 | ], 42 | "type": "Assign", 43 | "targets": [ 44 | { 45 | "ctx": null, 46 | "loc": { 47 | "start": { 48 | "column": 2, 49 | "line": 3 50 | }, 51 | "end": { 52 | "column": 3, 53 | "line": 3 54 | } 55 | }, 56 | "_fields": [ 57 | "id", 58 | "ctx" 59 | ], 60 | "type": "Name", 61 | "id": "y" 62 | } 63 | ], 64 | "value": { 65 | "loc": { 66 | "start": { 67 | "column": 6, 68 | "line": 3 69 | }, 70 | "end": { 71 | "column": 16, 72 | "line": 3 73 | } 74 | }, 75 | "right": { 76 | "loc": { 77 | "start": { 78 | "column": 11, 79 | "line": 3 80 | }, 81 | "end": { 82 | "column": 16, 83 | "line": 3 84 | } 85 | }, 86 | "right": { 87 | "ctx": null, 88 | "loc": { 89 | "start": { 90 | "column": 15, 91 | "line": 3 92 | }, 93 | "end": { 94 | "column": 16, 95 | "line": 3 96 | } 97 | }, 98 | "_fields": [ 99 | "id", 100 | "ctx" 101 | ], 102 | "type": "Name", 103 | "id": "c" 104 | }, 105 | "left": { 106 | "ctx": null, 107 | "loc": { 108 | "start": { 109 | "column": 11, 110 | "line": 3 111 | }, 112 | "end": { 113 | "column": 12, 114 | "line": 3 115 | } 116 | }, 117 | "_fields": [ 118 | "id", 119 | "ctx" 120 | ], 121 | "type": "Name", 122 | "id": "b" 123 | }, 124 | "_fields": [ 125 | "left", 126 | "op", 127 | "right" 128 | ], 129 | "type": "BinOp", 130 | "op": { 131 | "loc": { 132 | "start": { 133 | "column": 13, 134 | "line": 3 135 | }, 136 | "end": { 137 | "column": 14, 138 | "line": 3 139 | } 140 | }, 141 | "_fields": [], 142 | "type": "Sub" 143 | } 144 | }, 145 | "left": { 146 | "ctx": null, 147 | "loc": { 148 | "start": { 149 | "column": 6, 150 | "line": 3 151 | }, 152 | "end": { 153 | "column": 7, 154 | "line": 3 155 | } 156 | }, 157 | "_fields": [ 158 | "id", 159 | "ctx" 160 | ], 161 | "type": "Name", 162 | "id": "a" 163 | }, 164 | "_fields": [ 165 | "left", 166 | "op", 167 | "right" 168 | ], 169 | "type": "BinOp", 170 | "op": { 171 | "loc": { 172 | "start": { 173 | "column": 8, 174 | "line": 3 175 | }, 176 | "end": { 177 | "column": 9, 178 | "line": 3 179 | } 180 | }, 181 | "_fields": [], 182 | "type": "Add" 183 | } 184 | } 185 | }, 186 | { 187 | "loc": { 188 | "start": { 189 | "column": 2, 190 | "line": 4 191 | }, 192 | "end": { 193 | "column": 10, 194 | "line": 4 195 | } 196 | }, 197 | "_fields": [ 198 | "value" 199 | ], 200 | "type": "Return", 201 | "value": { 202 | "ctx": null, 203 | "loc": { 204 | "start": { 205 | "column": 9, 206 | "line": 4 207 | }, 208 | "end": { 209 | "column": 10, 210 | "line": 4 211 | } 212 | }, 213 | "_fields": [ 214 | "id", 215 | "ctx" 216 | ], 217 | "type": "Name", 218 | "id": "y" 219 | } 220 | } 221 | ], 222 | "loc": { 223 | "start": { 224 | "column": 0, 225 | "line": 2 226 | }, 227 | "end": { 228 | "column": 10, 229 | "line": 4 230 | } 231 | }, 232 | "name": "foo", 233 | "args": { 234 | "loc": { 235 | "start": { 236 | "column": 8, 237 | "line": 2 238 | }, 239 | "end": { 240 | "column": 16, 241 | "line": 2 242 | } 243 | }, 244 | "vararg": { 245 | "loc": { 246 | "start": { 247 | "column": 15, 248 | "line": 2 249 | }, 250 | "end": { 251 | "column": 16, 252 | "line": 2 253 | } 254 | }, 255 | "_fields": [ 256 | "arg", 257 | "annotation" 258 | ], 259 | "type": "arg", 260 | "annotation": null, 261 | "arg": "c" 262 | }, 263 | "args": [ 264 | { 265 | "loc": { 266 | "start": { 267 | "column": 8, 268 | "line": 2 269 | }, 270 | "end": { 271 | "column": 9, 272 | "line": 2 273 | } 274 | }, 275 | "_fields": [ 276 | "arg", 277 | "annotation" 278 | ], 279 | "type": "arg", 280 | "annotation": null, 281 | "arg": "a" 282 | }, 283 | { 284 | "loc": { 285 | "start": { 286 | "column": 11, 287 | "line": 2 288 | }, 289 | "end": { 290 | "column": 12, 291 | "line": 2 292 | } 293 | }, 294 | "_fields": [ 295 | "arg", 296 | "annotation" 297 | ], 298 | "type": "arg", 299 | "annotation": null, 300 | "arg": "b" 301 | } 302 | ], 303 | "kwarg": null, 304 | "defaults": [], 305 | "kw_defaults": [], 306 | "kwonlyargs": [], 307 | "_fields": [ 308 | "args", 309 | "vararg", 310 | "kwonlyargs", 311 | "kwarg", 312 | "defaults", 313 | "kw_defaults" 314 | ], 315 | "type": "arguments" 316 | }, 317 | "returns": null, 318 | "_fields": [ 319 | "name", 320 | "args", 321 | "returns", 322 | "body", 323 | "decorator_list" 324 | ], 325 | "type": "FunctionDef", 326 | "decorator_list": [] 327 | } 328 | ], 329 | "loc": { 330 | "start": { 331 | "column": 0, 332 | "line": 2 333 | }, 334 | "end": { 335 | "column": 10, 336 | "line": 4 337 | } 338 | }, 339 | "_fields": [ 340 | "body" 341 | ], 342 | "type": "Module" 343 | } 344 | ``` 345 | -------------------------------------------------------------------------------- /ast/tester/parse_python_to_json.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | Parses a Python source file into an AST in JSON format. can be viewed 4 | online in a viewer like: http://jsonviewer.stack.hu/ 5 | 6 | Usage: 7 | 8 | python parse_python_to_json.py --pyfile=test.py # pass in code within a file 9 | python parse_python_to_json.py 'print "Hello world"' # pass in code as a string 10 | 11 | Try running on its own source code; whoa very META! 12 | 13 | python parse_python_to_json.py --pyfile=parse_python_to_json.py 14 | 15 | 16 | Output: prints JSON to stdout 17 | 18 | Created on 2017-01-20 by Philip Guo 19 | ''' 20 | 21 | import ast 22 | import json 23 | import optparse 24 | #import pprint 25 | import pythonparser # based on https://github.com/m-labs/pythonparser 26 | import os 27 | import sys 28 | 29 | #pp = pprint.PrettyPrinter() 30 | 31 | class Visitor: 32 | def visit(self, obj, level=0): 33 | """Visit a node or a list of nodes. Other values are ignored""" 34 | if isinstance(obj, list): 35 | return [self.visit(elt, level) for elt in obj] 36 | 37 | elif isinstance(obj, pythonparser.ast.AST): 38 | typ = obj.__class__.__name__ 39 | #print >> sys.stderr, obj 40 | loc = None 41 | if hasattr(obj, 'loc'): 42 | loc = { 43 | 'start': {'line': obj.loc.begin().line(), 'column': obj.loc.begin().column()}, 44 | 'end': {'line': obj.loc.end().line(), 'column': obj.loc.end().column()} 45 | } 46 | # TODO: check out obj._locs for more details later if needed 47 | 48 | d = {} 49 | d['type'] = typ 50 | d['loc'] = loc 51 | d['_fields'] = obj._fields 52 | for field_name in obj._fields: 53 | val = self.visit(getattr(obj, field_name), level+1) 54 | d[field_name] = val 55 | return d 56 | 57 | else: 58 | # let's hope this is a primitive type that's JSON-encodable! 59 | return obj 60 | 61 | 62 | if __name__ == "__main__": 63 | parser = optparse.OptionParser() 64 | parser.add_option("--pyfile", action="store", dest="pyfile", 65 | help="Take input from a Python source file") 66 | parser.add_option("--pp", action="store_true", 67 | help="Pretty-print JSON for human viewing") 68 | (options, args) = parser.parse_args() 69 | 70 | if options.pyfile: 71 | code = open(options.pyfile).read() 72 | else: 73 | code = args[0] 74 | # make sure it ends with a newline to get parse() to work: 75 | if code[-1] != '\n': 76 | code += '\n' 77 | 78 | indent_level = None 79 | if options.pp: 80 | indent_level = 2 81 | 82 | try: 83 | p = pythonparser.parse(code) 84 | 85 | v = Visitor() 86 | res = v.visit(p) 87 | print json.dumps(res, indent=indent_level) 88 | except pythonparser.diagnostic.Error as e: 89 | error_obj = {'type': 'parse_error'} 90 | diag = e.diagnostic 91 | loc = diag.location 92 | 93 | error_obj['loc'] = { 94 | 'start': {'line': loc.begin().line(), 'column': loc.begin().column()}, 95 | 'end': {'line': loc.end().line(), 'column': loc.end().column()} 96 | } 97 | 98 | error_obj['message'] = diag.message() 99 | print json.dumps(error_obj, indent=indent_level) 100 | sys.exit(1) 101 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, unicode_literals 2 | import sys, pythonparser.source, pythonparser.lexer, pythonparser.parser, pythonparser.diagnostic 3 | 4 | def parse_buffer(buffer, mode="exec", flags=[], version=None, engine=None): 5 | """ 6 | Like :meth:`parse`, but accepts a :class:`source.Buffer` instead of 7 | source and filename, and returns comments as well. 8 | 9 | :see: :meth:`parse` 10 | :return: (:class:`ast.AST`, list of :class:`source.Comment`) 11 | Abstract syntax tree and comments 12 | """ 13 | 14 | if version is None: 15 | version = sys.version_info[0:2] 16 | 17 | if engine is None: 18 | engine = pythonparser.diagnostic.Engine() 19 | 20 | lexer = pythonparser.lexer.Lexer(buffer, version, engine) 21 | if mode in ("single", "eval"): 22 | lexer.interactive = True 23 | 24 | parser = pythonparser.parser.Parser(lexer, version, engine) 25 | parser.add_flags(flags) 26 | 27 | if mode == "exec": 28 | return parser.file_input(), lexer.comments 29 | elif mode == "single": 30 | return parser.single_input(), lexer.comments 31 | elif mode == "eval": 32 | return parser.eval_input(), lexer.comments 33 | 34 | def parse(source, filename="", mode="exec", 35 | flags=[], version=None, engine=None): 36 | """ 37 | Parse a string into an abstract syntax tree. 38 | This is the replacement for the built-in :meth:`..ast.parse`. 39 | 40 | :param source: (string) Source code in the correct encoding 41 | :param filename: (string) Filename of the source (used in diagnostics) 42 | :param mode: (string) Execution mode. Pass ``"exec"`` to parse a module, 43 | ``"single"`` to parse a single (interactive) statement, 44 | and ``"eval"`` to parse an expression. In the last two cases, 45 | ``source`` must be terminated with an empty line 46 | (i.e. end with ``"\\n\\n"``). 47 | :param flags: (list of string) Future flags. 48 | Equivalent to ``from __future__ import ``. 49 | :param version: (2-tuple of int) Major and minor version of Python 50 | syntax to recognize, ``sys.version_info[0:2]`` by default. 51 | :param engine: (:class:`diagnostic.Engine`) Diagnostic engine, 52 | a fresh one is created by default 53 | :return: (:class:`ast.AST`) Abstract syntax tree 54 | :raise: :class:`diagnostic.Error` 55 | if the source code is not well-formed 56 | """ 57 | ast, comments = parse_buffer(pythonparser.source.Buffer(source, filename), 58 | mode, flags, version, engine) 59 | return ast 60 | 61 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/__init__.pyc -------------------------------------------------------------------------------- /ast/tester/pythonparser/__main__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, unicode_literals 2 | from . import parse, diagnostic 3 | import sys, time, codecs 4 | 5 | for filename in sys.argv[1:]: 6 | with codecs.open(filename, encoding="utf-8") as f: 7 | input = f.read() 8 | try: 9 | start = time.time() 10 | root = parse(input, filename) 11 | interval = time.time() - start 12 | 13 | print(root) 14 | print("elapsed: %.2f (%.2f kb/s)" % (interval, len(input)/interval/1000), 15 | file=sys.stderr) 16 | except diagnostic.Error as e: 17 | print("\n".join(e.diagnostic.render()), 18 | file=sys.stderr) 19 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/algorithm.py: -------------------------------------------------------------------------------- 1 | """ 2 | The :mod:`Diagnostic` module provides several commonly useful 3 | algorithms that operate on abstract syntax trees. 4 | """ 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | from . import ast 8 | 9 | class Visitor: 10 | """ 11 | A node visitor base class that does a traversal 12 | of the abstract syntax tree. 13 | 14 | This class is meant to be subclassed, with the subclass adding 15 | visitor methods. The visitor method should call ``self.generic_visit(node)`` 16 | to continue the traversal; this allows to perform arbitrary 17 | actions both before and after traversing the children of a node. 18 | 19 | The visitor methods for the nodes are ``'visit_'`` + 20 | class name of the node. So a `Try` node visit function would 21 | be `visit_Try`. 22 | """ 23 | 24 | def generic_visit(self, node): 25 | """Called if no explicit visitor function exists for a node.""" 26 | for field_name in node._fields: 27 | self.visit(getattr(node, field_name)) 28 | 29 | def _visit_one(self, node): 30 | visit_attr = "visit_" + type(node).__name__ 31 | if hasattr(self, visit_attr): 32 | return getattr(self, visit_attr)(node) 33 | else: 34 | return self.generic_visit(node) 35 | 36 | def visit(self, obj): 37 | """Visit a node or a list of nodes. Other values are ignored""" 38 | if isinstance(obj, list): 39 | return [self.visit(elt) for elt in obj] 40 | elif isinstance(obj, ast.AST): 41 | return self._visit_one(obj) 42 | 43 | class Transformer: 44 | """ 45 | A node transformer base class that does a post-order traversal 46 | of the abstract syntax tree while allowing to replace or remove 47 | the nodes being traversed. 48 | 49 | The return value of the visitor methods is used to replace or remove 50 | the old node. If the return value of the visitor method is ``None``, 51 | the node will be removed from its location, otherwise it is replaced 52 | with the return value. The return value may be the original node 53 | in which case no replacement takes place. 54 | 55 | This class is meant to be subclassed, with the subclass adding 56 | visitor methods. The visitor method should call ``self.generic_visit(node)`` 57 | to continue the traversal; this allows to perform arbitrary 58 | actions both before and after traversing the children of a node. 59 | 60 | The visitor methods for the nodes are ``'visit_'`` + 61 | class name of the node. So a `Try` node visit function would 62 | be `visit_Try`. 63 | """ 64 | 65 | def generic_visit(self, node): 66 | """Called if no explicit visitor function exists for a node.""" 67 | for field_name in node._fields: 68 | setattr(node, field_name, self.visit(getattr(node, field_name))) 69 | return node 70 | 71 | def _visit_one(self, node): 72 | visit_attr = "visit_" + type(node).__name__ 73 | if hasattr(self, visit_attr): 74 | return getattr(self, visit_attr)(node) 75 | else: 76 | return self.generic_visit(node) 77 | 78 | def visit(self, obj): 79 | """Visit a node or a list of nodes. Other values are ignored""" 80 | if isinstance(obj, list): 81 | return list(filter(lambda x: x is not None, map(self.visit, obj))) 82 | elif isinstance(obj, ast.AST): 83 | return self._visit_one(obj) 84 | else: 85 | return obj 86 | 87 | def compare(left, right, compare_locs=False): 88 | """ 89 | An AST comparison function. Returns ``True`` if all fields in 90 | ``left`` are equal to fields in ``right``; if ``compare_locs`` is 91 | true, all locations should match as well. 92 | """ 93 | if type(left) != type(right): 94 | return False 95 | 96 | if isinstance(left, ast.AST): 97 | for field in left._fields: 98 | if not compare(getattr(left, field), getattr(right, field)): 99 | return False 100 | 101 | if compare_locs: 102 | for loc in left._locs: 103 | if getattr(left, loc) != getattr(right, loc): 104 | return False 105 | 106 | return True 107 | elif isinstance(left, list): 108 | if len(left) != len(right): 109 | return False 110 | 111 | for left_elt, right_elt in zip(left, right): 112 | if not compare(left_elt, right_elt): 113 | return False 114 | 115 | return True 116 | else: 117 | return left == right 118 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/ast.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/ast.pyc -------------------------------------------------------------------------------- /ast/tester/pythonparser/diagnostic.py: -------------------------------------------------------------------------------- 1 | """ 2 | The :mod:`Diagnostic` module concerns itself with processing 3 | and presentation of diagnostic messages. 4 | """ 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | from functools import reduce 8 | from contextlib import contextmanager 9 | import sys, re 10 | 11 | class Diagnostic: 12 | """ 13 | A diagnostic message highlighting one or more locations 14 | in a single source buffer. 15 | 16 | :ivar level: (one of ``LEVELS``) severity level 17 | :ivar reason: (format string) diagnostic message 18 | :ivar arguments: (dictionary) substitutions for ``reason`` 19 | :ivar location: (:class:`pythonparser.source.Range`) most specific 20 | location of the problem 21 | :ivar highlights: (list of :class:`pythonparser.source.Range`) 22 | secondary locations related to the problem that are 23 | likely to be on the same line 24 | :ivar notes: (list of :class:`Diagnostic`) 25 | secondary diagnostics highlighting relevant source 26 | locations that are unlikely to be on the same line 27 | """ 28 | 29 | LEVELS = ["note", "warning", "error", "fatal"] 30 | """ 31 | Available diagnostic levels: 32 | * ``fatal`` indicates an unrecoverable error. 33 | * ``error`` indicates an error that leaves a possibility of 34 | processing more code, e.g. a recoverable parsing error. 35 | * ``warning`` indicates a potential problem. 36 | * ``note`` level diagnostics do not appear by itself, 37 | but are attached to other diagnostics to refer to 38 | and describe secondary source locations. 39 | """ 40 | 41 | def __init__(self, level, reason, arguments, location, 42 | highlights=None, notes=None): 43 | if level not in self.LEVELS: 44 | raise ValueError("level must be one of Diagnostic.LEVELS") 45 | 46 | if highlights is None: 47 | highlights = [] 48 | if notes is None: 49 | notes = [] 50 | 51 | if len(set(map(lambda x: x.source_buffer, 52 | [location] + highlights))) > 1: 53 | raise ValueError("location and highlights must refer to the same source buffer") 54 | 55 | self.level, self.reason, self.arguments = \ 56 | level, reason, arguments 57 | self.location, self.highlights, self.notes = \ 58 | location, highlights, notes 59 | 60 | def message(self): 61 | """ 62 | Returns the formatted message. 63 | """ 64 | return self.reason.format(**self.arguments) 65 | 66 | def render(self, only_line=False, colored=False): 67 | """ 68 | Returns the human-readable location of the diagnostic in the source, 69 | the formatted message, the source line corresponding 70 | to ``location`` and a line emphasizing the problematic 71 | locations in the source line using ASCII art, as a list of lines. 72 | Appends the result of calling :meth:`render` on ``notes``, if any. 73 | 74 | For example: :: 75 | 76 | :1:8-9: error: cannot add integer and string 77 | x + (1 + "a") 78 | ~ ^ ~~~ 79 | 80 | :param only_line: (bool) If true, only print line number, not line and column range 81 | """ 82 | source_line = self.location.source_line().rstrip("\n") 83 | highlight_line = bytearray(re.sub(r"[^\t]", " ", source_line), "utf-8") 84 | 85 | for hilight in self.highlights: 86 | if hilight.line() == self.location.line(): 87 | lft, rgt = hilight.column_range() 88 | highlight_line[lft:rgt] = bytearray("~", "utf-8") * (rgt - lft) 89 | 90 | lft, rgt = self.location.column_range() 91 | if rgt == lft: # Expand zero-length ranges to one ^ 92 | rgt = lft + 1 93 | highlight_line[lft:rgt] = bytearray("^", "utf-8") * (rgt - lft) 94 | 95 | if only_line: 96 | location = "%s:%s" % (self.location.source_buffer.name, self.location.line()) 97 | else: 98 | location = str(self.location) 99 | 100 | notes = list(self.notes) 101 | if self.level != "note": 102 | expanded_location = self.location.expanded_from 103 | while expanded_location is not None: 104 | notes.insert(0, Diagnostic("note", 105 | "expanded from here", {}, 106 | self.location.expanded_from)) 107 | expanded_location = expanded_location.expanded_from 108 | 109 | rendered_notes = reduce(list.__add__, [note.render(only_line, colored) 110 | for note in notes], []) 111 | if colored: 112 | if self.level in ("error", "fatal"): 113 | level_color = 31 # red 114 | elif self.level == "warning": 115 | level_color = 35 # magenta 116 | else: # level == "note" 117 | level_color = 30 # gray 118 | return [ 119 | "\x1b[1;37m{}: \x1b[{}m{}:\x1b[37m {}\x1b[0m". 120 | format(location, level_color, self.level, self.message()), 121 | source_line, 122 | "\x1b[1;32m{}\x1b[0m".format(highlight_line.decode("utf-8")) 123 | ] + rendered_notes 124 | else: 125 | return [ 126 | "{}: {}: {}".format(location, self.level, self.message()), 127 | source_line, 128 | highlight_line.decode("utf-8") 129 | ] + rendered_notes 130 | 131 | 132 | class Error(Exception): 133 | """ 134 | :class:`Error` is an exception which carries a :class:`Diagnostic`. 135 | 136 | :ivar diagnostic: (:class:`Diagnostic`) the diagnostic 137 | """ 138 | def __init__(self, diagnostic): 139 | self.diagnostic = diagnostic 140 | 141 | def __str__(self): 142 | return "\n".join(self.diagnostic.render()) 143 | 144 | class Engine: 145 | """ 146 | :class:`Engine` is a single point through which diagnostics from 147 | lexer, parser and any AST consumer are dispatched. 148 | 149 | :ivar all_errors_are_fatal: if true, an exception is raised not only 150 | for ``fatal`` diagnostic level, but also ``error`` 151 | """ 152 | def __init__(self, all_errors_are_fatal=False): 153 | self.all_errors_are_fatal = all_errors_are_fatal 154 | self._appended_notes = [] 155 | 156 | def process(self, diagnostic): 157 | """ 158 | The default implementation of :meth:`process` renders non-fatal 159 | diagnostics to ``sys.stderr``, and raises fatal ones as a :class:`Error`. 160 | """ 161 | diagnostic.notes += self._appended_notes 162 | self.render_diagnostic(diagnostic) 163 | if diagnostic.level == "fatal" or \ 164 | (self.all_errors_are_fatal and diagnostic.level == "error"): 165 | raise Error(diagnostic) 166 | 167 | @contextmanager 168 | def context(self, *notes): 169 | """ 170 | A context manager that appends ``note`` to every diagnostic processed by 171 | this engine. 172 | """ 173 | self._appended_notes += notes 174 | yield 175 | del self._appended_notes[-len(notes):] 176 | 177 | def render_diagnostic(self, diagnostic): 178 | sys.stderr.write("\n".join(diagnostic.render()) + "\n") 179 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/diagnostic.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/diagnostic.pyc -------------------------------------------------------------------------------- /ast/tester/pythonparser/lexer.py: -------------------------------------------------------------------------------- 1 | """ 2 | The :mod:`lexer` module concerns itself with tokenizing Python source. 3 | """ 4 | 5 | from __future__ import absolute_import, division, print_function, unicode_literals 6 | from . import source, diagnostic 7 | #import regex as re # <-- original code; requires an external regex module 8 | import re # <-- modified by pgbovine to use built-in standard library re 9 | import unicodedata 10 | import sys 11 | 12 | if sys.version_info[0] == 3: 13 | unichr = chr 14 | 15 | class Token: 16 | """ 17 | The :class:`Token` encapsulates a single lexer token and its location 18 | in the source code. 19 | 20 | :ivar loc: (:class:`pythonparser.source.Range`) token location 21 | :ivar kind: (string) token kind 22 | :ivar value: token value; None or a kind-specific class 23 | """ 24 | def __init__(self, loc, kind, value=None): 25 | self.loc, self.kind, self.value = loc, kind, value 26 | 27 | def __repr__(self): 28 | return "Token(%s, \"%s\", %s)" % (repr(self.loc), self.kind, repr(self.value)) 29 | 30 | class Lexer: 31 | """ 32 | The :class:`Lexer` class extracts tokens and comments from 33 | a :class:`pythonparser.source.Buffer`. 34 | 35 | :class:`Lexer` is an iterable. 36 | 37 | :ivar version: (tuple of (*major*, *minor*)) 38 | the version of Python, determining the grammar used 39 | :ivar source_buffer: (:class:`pythonparser.source.Buffer`) 40 | the source buffer 41 | :ivar diagnostic_engine: (:class:`pythonparser.diagnostic.Engine`) 42 | the diagnostic engine 43 | :ivar offset: (integer) character offset into ``source_buffer`` 44 | indicating where the next token will be recognized 45 | :ivar interactive: (boolean) whether a completely empty line 46 | should generate a NEWLINE token, for use in REPLs 47 | """ 48 | 49 | _reserved_2_6 = frozenset([ 50 | "!=", "%", "%=", "&", "&=", "(", ")", "*", "**", "**=", "*=", "+", "+=", 51 | ",", "-", "-=", ".", "/", "//", "//=", "/=", ":", ";", "<", "<<", "<<=", 52 | "<=", "<>", "=", "==", ">", ">=", ">>", ">>=", "@", "[", "]", "^", "^=", "`", 53 | "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", 54 | "else", "except", "exec", "finally", "for", "from", "global", "if", "import", 55 | "in", "is", "lambda", "not", "or", "pass", "print", "raise", "return", "try", 56 | "while", "with", "yield", "{", "|", "|=", "}", "~" 57 | ]) 58 | 59 | _reserved_3_0 = _reserved_2_6 \ 60 | - set(["<>", "`", "exec", "print"]) \ 61 | | set(["->", "...", "False", "None", "nonlocal", "True"]) 62 | 63 | _reserved_3_1 = _reserved_3_0 \ 64 | | set(["<>"]) 65 | 66 | _reserved_3_5 = _reserved_3_1 \ 67 | | set(["@", "@="]) 68 | 69 | _reserved = { 70 | (2, 6): _reserved_2_6, 71 | (2, 7): _reserved_2_6, 72 | (3, 0): _reserved_3_0, 73 | (3, 1): _reserved_3_1, 74 | (3, 2): _reserved_3_1, 75 | (3, 3): _reserved_3_1, 76 | (3, 4): _reserved_3_1, 77 | (3, 5): _reserved_3_5, 78 | } 79 | """ 80 | A map from a tuple (*major*, *minor*) corresponding to Python version to 81 | :class:`frozenset`\s of keywords. 82 | """ 83 | 84 | _string_prefixes_3_1 = frozenset(["", "r", "b", "br"]) 85 | _string_prefixes_3_3 = frozenset(["", "r", "u", "b", "br", "rb"]) 86 | 87 | # holy mother of god why 88 | _string_prefixes = { 89 | (2, 6): frozenset(["", "r", "u", "ur"]), 90 | (2, 7): frozenset(["", "r", "u", "ur", "b", "br"]), 91 | (3, 0): frozenset(["", "r", "b"]), 92 | (3, 1): _string_prefixes_3_1, 93 | (3, 2): _string_prefixes_3_1, 94 | (3, 3): _string_prefixes_3_3, 95 | (3, 4): _string_prefixes_3_3, 96 | (3, 5): _string_prefixes_3_3, 97 | } 98 | """ 99 | A map from a tuple (*major*, *minor*) corresponding to Python version to 100 | :class:`frozenset`\s of string prefixes. 101 | """ 102 | 103 | def __init__(self, source_buffer, version, diagnostic_engine, interactive=False): 104 | self.source_buffer = source_buffer 105 | self.version = version 106 | self.diagnostic_engine = diagnostic_engine 107 | self.interactive = interactive 108 | self.print_function = False 109 | 110 | self.offset = 0 111 | self.new_line = True 112 | self.indent = [(0, source.Range(source_buffer, 0, 0), "")] 113 | self.comments = [] 114 | self.queue = [] 115 | self.parentheses = [] 116 | self.curly_braces = [] 117 | self.square_braces = [] 118 | 119 | try: 120 | reserved = self._reserved[version] 121 | except KeyError: 122 | raise NotImplementedError("pythonparser.lexer.Lexer cannot lex Python %s" % str(version)) 123 | 124 | # Sort for the regexp to obey longest-match rule. 125 | re_reserved = sorted(reserved, reverse=True, key=len) 126 | re_keywords = "|".join([kw for kw in re_reserved if kw.isalnum()]) 127 | re_operators = "|".join([re.escape(op) for op in re_reserved if not op.isalnum()]) 128 | 129 | # Python 3.0 uses ID_Start, >3.0 uses XID_Start 130 | if self.version == (3, 0): 131 | id_xid = "" 132 | else: 133 | id_xid = "X" 134 | 135 | # To speed things up on CPython, we use the re module to generate a DFA 136 | # from our token set and execute it in C. Every result yielded by 137 | # iterating this regular expression has exactly one non-empty group 138 | # that would correspond to a e.g. lex scanner branch. 139 | # The only thing left to Python code is then to select one from this 140 | # small set of groups, which is much faster than dissecting the strings. 141 | # 142 | # A lexer has to obey longest-match rule, but a regular expression does not. 143 | # Therefore, the cases in it are carefully sorted so that the longest 144 | # ones come up first. The exception is the identifier case, which would 145 | # otherwise grab all keywords; it is made to work by making it impossible 146 | # for the keyword case to match a word prefix, and ordering it before 147 | # the identifier case. 148 | self._lex_token_re = re.compile(r""" 149 | [ \t\f]* # initial whitespace 150 | ( # 1 151 | (\\)? # ?2 line continuation 152 | ([\n]|[\r][\n]|[\r]) # 3 newline 153 | | (\#.*) # 4 comment 154 | | ( # 5 floating point or complex literal 155 | (?: [0-9]* \. [0-9]+ 156 | | [0-9]+ \.? 157 | ) [eE] [+-]? [0-9]+ 158 | | [0-9]* \. [0-9]+ 159 | | [0-9]+ \. 160 | ) ([jJ])? # ?6 complex suffix 161 | | ([0-9]+) [jJ] # 7 complex literal 162 | | (?: # integer literal 163 | ( [1-9] [0-9]* ) # 8 dec 164 | | 0[oO] ( [0-7]+ ) # 9 oct 165 | | 0[xX] ( [0-9A-Fa-f]+ ) # 10 hex 166 | | 0[bB] ( [01]+ ) # 11 bin 167 | | ( [0-9] [0-9]* ) # 12 bare oct 168 | ) 169 | [Ll]? 170 | | ([BbUu]?[Rr]?) # ?13 string literal options 171 | (?: # string literal start 172 | # 14, 15, 16 long string 173 | (""\"|''') ((?: \\?[\n] | \\. | . )*?) (\14) 174 | # 17, 18, 19 short string 175 | | (" |' ) ((?: \\ [\n] | \\. | . )*?) (\17) 176 | # 20 unterminated 177 | | (""\"|'''|"|') 178 | ) 179 | | ((?:{keywords})\b|{operators}) # 21 keywords and operators 180 | | ([A-Za-z_][A-Za-z0-9_]*\b) # 22 identifier 181 | | (\p{{{id_xid}ID_Start}}\p{{{id_xid}ID_Continue}}*) # 23 Unicode identifier 182 | | ($) # 24 end-of-file 183 | ) 184 | """.format(keywords=re_keywords, operators=re_operators, 185 | id_xid=id_xid), re.VERBOSE|re.UNICODE) 186 | 187 | # These are identical for all lexer instances. 188 | _lex_escape_re = re.compile(r""" 189 | \\(?: 190 | ([\n\\'"abfnrtv]) # 1 single-char 191 | | ([0-7]{3}) # 2 oct 192 | | x([0-9A-Fa-f]{2}) # 3 hex 193 | ) 194 | """, re.VERBOSE) 195 | 196 | _lex_escape_unicode_re = re.compile(_lex_escape_re.pattern + r""" 197 | | \\(?: 198 | u([0-9A-Fa-f]{4}) # 4 unicode-16 199 | | U([0-9A-Fa-f]{8}) # 5 unicode-32 200 | | N\{(.+?)\} # 6 unicode-name 201 | ) 202 | """, re.VERBOSE) 203 | 204 | _lex_check_byte_re = re.compile("[^\x00-\x7f]") 205 | 206 | def next(self, eof_token=False): 207 | """ 208 | Returns token at ``offset`` as a :class:`Token` and advances ``offset`` 209 | to point past the end of the token, where the token has: 210 | 211 | - *range* which is a :class:`pythonparser.source.Range` that includes 212 | the token but not surrounding whitespace, 213 | - *kind* which is a string containing one of Python keywords or operators, 214 | ``newline``, ``float``, ``int``, ``complex``, ``strbegin``, 215 | ``strdata``, ``strend``, ``ident``, ``indent``, ``dedent`` or ``eof`` 216 | (if ``eof_token`` is True). 217 | - *value* which is the flags as lowercase string if *kind* is ``strbegin``, 218 | the string contents if *kind* is ``strdata``, 219 | the numeric value if *kind* is ``float``, ``int`` or ``complex``, 220 | the identifier if *kind* is ``ident`` and ``None`` in any other case. 221 | 222 | :param eof_token: if true, will return a token with kind ``eof`` 223 | when the input is exhausted; if false, will raise ``StopIteration``. 224 | """ 225 | if len(self.queue) == 0: 226 | self._refill(eof_token) 227 | 228 | return self.queue.pop(0) 229 | 230 | def peek(self, eof_token=False): 231 | """Same as :meth:`next`, except the token is not dequeued.""" 232 | if len(self.queue) == 0: 233 | self._refill(eof_token) 234 | 235 | return self.queue[-1] 236 | 237 | # We need separate next and _refill because lexing can sometimes 238 | # generate several tokens, e.g. INDENT 239 | def _refill(self, eof_token): 240 | if self.offset == len(self.source_buffer.source): 241 | range = source.Range(self.source_buffer, self.offset, self.offset) 242 | 243 | for i in self.indent[1:]: 244 | self.indent.pop(-1) 245 | self.queue.append(Token(range, "dedent")) 246 | 247 | if eof_token: 248 | self.queue.append(Token(range, "eof")) 249 | elif len(self.queue) == 0: 250 | raise StopIteration 251 | 252 | return 253 | 254 | match = self._lex_token_re.match(self.source_buffer.source, self.offset) 255 | if match is None: 256 | diag = diagnostic.Diagnostic( 257 | "fatal", "unexpected {character}", 258 | {"character": repr(self.source_buffer.source[self.offset]).lstrip("u")}, 259 | source.Range(self.source_buffer, self.offset, self.offset + 1)) 260 | self.diagnostic_engine.process(diag) 261 | 262 | # Should we emit indent/dedent? 263 | if self.new_line and \ 264 | match.group(3) is None and \ 265 | match.group(4) is None: # not a blank line 266 | whitespace = match.string[match.start(0):match.start(1)] 267 | level = len(whitespace.expandtabs()) 268 | range = source.Range(self.source_buffer, match.start(1), match.start(1)) 269 | if level > self.indent[-1][0]: 270 | self.indent.append((level, range, whitespace)) 271 | self.queue.append(Token(range, "indent")) 272 | elif level < self.indent[-1][0]: 273 | exact = False 274 | while level <= self.indent[-1][0]: 275 | if level == self.indent[-1][0] or self.indent[-1][0] == 0: 276 | exact = True 277 | break 278 | self.indent.pop(-1) 279 | self.queue.append(Token(range, "dedent")) 280 | if not exact: 281 | note = diagnostic.Diagnostic( 282 | "note", "expected to match level here", {}, 283 | self.indent[-1][1]) 284 | error = diagnostic.Diagnostic( 285 | "fatal", "inconsistent indentation", {}, 286 | range, notes=[note]) 287 | self.diagnostic_engine.process(error) 288 | elif whitespace != self.indent[-1][2] and self.version >= (3, 0): 289 | error = diagnostic.Diagnostic( 290 | "error", "inconsistent use of tabs and spaces in indentation", {}, 291 | range) 292 | self.diagnostic_engine.process(error) 293 | 294 | # Prepare for next token. 295 | self.offset = match.end(0) 296 | 297 | tok_range = source.Range(self.source_buffer, *match.span(1)) 298 | if match.group(3) is not None: # newline 299 | if len(self.parentheses) + len(self.square_braces) + len(self.curly_braces) > 0: 300 | # 2.1.6 Implicit line joining 301 | return self._refill(eof_token) 302 | if match.group(2) is not None: 303 | # 2.1.5. Explicit line joining 304 | return self._refill(eof_token) 305 | if self.new_line and not \ 306 | (self.interactive and match.group(0) == match.group(3)): # REPL terminator 307 | # 2.1.7. Blank lines 308 | return self._refill(eof_token) 309 | 310 | self.new_line = True 311 | self.queue.append(Token(tok_range, "newline")) 312 | return 313 | 314 | if match.group(4) is not None: # comment 315 | self.comments.append(source.Comment(tok_range, match.group(4))) 316 | return self._refill(eof_token) 317 | 318 | # Lexing non-whitespace now. 319 | self.new_line = False 320 | 321 | if match.group(5) is not None: # floating point or complex literal 322 | if match.group(6) is None: 323 | self.queue.append(Token(tok_range, "float", float(match.group(5)))) 324 | else: 325 | self.queue.append(Token(tok_range, "complex", float(match.group(5)) * 1j)) 326 | 327 | elif match.group(7) is not None: # complex literal 328 | self.queue.append(Token(tok_range, "complex", int(match.group(7)) * 1j)) 329 | 330 | elif match.group(8) is not None: # integer literal, dec 331 | literal = match.group(8) 332 | self._check_long_literal(tok_range, match.group(1)) 333 | self.queue.append(Token(tok_range, "int", int(literal))) 334 | 335 | elif match.group(9) is not None: # integer literal, oct 336 | literal = match.group(9) 337 | self._check_long_literal(tok_range, match.group(1)) 338 | self.queue.append(Token(tok_range, "int", int(literal, 8))) 339 | 340 | elif match.group(10) is not None: # integer literal, hex 341 | literal = match.group(10) 342 | self._check_long_literal(tok_range, match.group(1)) 343 | self.queue.append(Token(tok_range, "int", int(literal, 16))) 344 | 345 | elif match.group(11) is not None: # integer literal, bin 346 | literal = match.group(11) 347 | self._check_long_literal(tok_range, match.group(1)) 348 | self.queue.append(Token(tok_range, "int", int(literal, 2))) 349 | 350 | elif match.group(12) is not None: # integer literal, bare oct 351 | literal = match.group(12) 352 | if len(literal) > 1 and self.version >= (3, 0): 353 | error = diagnostic.Diagnostic( 354 | "error", "in Python 3, decimal literals must not start with a zero", {}, 355 | source.Range(self.source_buffer, tok_range.begin_pos, tok_range.begin_pos + 1)) 356 | self.diagnostic_engine.process(error) 357 | self.queue.append(Token(tok_range, "int", int(literal, 8))) 358 | 359 | elif match.group(14) is not None: # long string literal 360 | self._string_literal( 361 | options=match.group(13), begin_span=(match.start(13), match.end(14)), 362 | data=match.group(15), data_span=match.span(15), 363 | end_span=match.span(16)) 364 | 365 | elif match.group(17) is not None: # short string literal 366 | self._string_literal( 367 | options=match.group(13), begin_span=(match.start(13), match.end(17)), 368 | data=match.group(18), data_span=match.span(18), 369 | end_span=match.span(19)) 370 | 371 | elif match.group(20) is not None: # unterminated string 372 | error = diagnostic.Diagnostic( 373 | "fatal", "unterminated string", {}, 374 | tok_range) 375 | self.diagnostic_engine.process(error) 376 | 377 | elif match.group(21) is not None: # keywords and operators 378 | kwop = match.group(21) 379 | self._match_pair_delim(tok_range, kwop) 380 | if kwop == "print" and self.print_function: 381 | self.queue.append(Token(tok_range, "ident", "print")) 382 | else: 383 | self.queue.append(Token(tok_range, kwop)) 384 | 385 | elif match.group(22) is not None: # identifier 386 | self.queue.append(Token(tok_range, "ident", match.group(22))) 387 | 388 | elif match.group(23) is not None: # Unicode identifier 389 | if self.version < (3, 0): 390 | error = diagnostic.Diagnostic( 391 | "error", "in Python 2, Unicode identifiers are not allowed", {}, 392 | tok_range) 393 | self.diagnostic_engine.process(error) 394 | self.queue.append(Token(tok_range, "ident", match.group(23))) 395 | 396 | elif match.group(24) is not None: # end-of-file 397 | # Reuse the EOF logic 398 | return self._refill(eof_token) 399 | 400 | else: 401 | assert False 402 | 403 | def _string_literal(self, options, begin_span, data, data_span, end_span): 404 | options = options.lower() 405 | begin_range = source.Range(self.source_buffer, *begin_span) 406 | data_range = source.Range(self.source_buffer, *data_span) 407 | 408 | if options not in self._string_prefixes[self.version]: 409 | error = diagnostic.Diagnostic( 410 | "error", "string prefix '{prefix}' is not available in Python {major}.{minor}", 411 | {"prefix": options, "major": self.version[0], "minor": self.version[1]}, 412 | begin_range) 413 | self.diagnostic_engine.process(error) 414 | 415 | self.queue.append(Token(begin_range, "strbegin", options)) 416 | self.queue.append(Token(data_range, 417 | "strdata", self._replace_escape(data_range, options, data))) 418 | self.queue.append(Token(source.Range(self.source_buffer, *end_span), 419 | "strend")) 420 | 421 | def _replace_escape(self, range, mode, value): 422 | is_raw = ("r" in mode) 423 | is_byte = ("b" in mode) 424 | is_unicode = ("u" in mode) 425 | 426 | if is_raw: 427 | return value 428 | 429 | if is_byte and self._lex_check_byte_re.match(value): 430 | error = diagnostic.Diagnostic( 431 | "error", "non-7-bit character in a byte literal", {}, 432 | tok_range) 433 | self.diagnostic_engine.process(error) 434 | 435 | if is_unicode or self.version >= (3, 0): 436 | re = self._lex_escape_unicode_re 437 | else: 438 | re = self._lex_escape_re 439 | 440 | chunks = [] 441 | offset = 0 442 | while offset < len(value): 443 | match = re.search(value, offset) 444 | if match is None: 445 | # Append the remaining of the string 446 | chunks.append(value[offset:]) 447 | break 448 | 449 | # Append the part of string before match 450 | chunks.append(value[offset:match.start()]) 451 | offset = match.end() 452 | 453 | # Process the escape 454 | if match.group(1) is not None: # single-char 455 | chr = match.group(1) 456 | if chr == "\n": 457 | pass 458 | elif chr == "\\" or chr == "'" or chr == "\"": 459 | chunks.append(chr) 460 | elif chr == "a": 461 | chunks.append("\a") 462 | elif chr == "b": 463 | chunks.append("\b") 464 | elif chr == "f": 465 | chunks.append("\f") 466 | elif chr == "n": 467 | chunks.append("\n") 468 | elif chr == "r": 469 | chunks.append("\r") 470 | elif chr == "t": 471 | chunks.append("\t") 472 | elif chr == "v": 473 | chunks.append("\v") 474 | elif match.group(2) is not None: # oct 475 | chunks.append(unichr(int(match.group(2), 8))) 476 | elif match.group(3) is not None: # hex 477 | chunks.append(unichr(int(match.group(3), 16))) 478 | elif match.group(4) is not None: # unicode-16 479 | chunks.append(unichr(int(match.group(4), 16))) 480 | elif match.group(5) is not None: # unicode-32 481 | try: 482 | chunks.append(unichr(int(match.group(5), 16))) 483 | except ValueError: 484 | error = diagnostic.Diagnostic( 485 | "error", "unicode character out of range", {}, 486 | source.Range(self.source_buffer, 487 | range.begin_pos + match.start(0), 488 | range.begin_pos + match.end(0))) 489 | self.diagnostic_engine.process(error) 490 | elif match.group(6) is not None: # unicode-name 491 | try: 492 | chunks.append(unicodedata.lookup(match.group(6))) 493 | except KeyError: 494 | error = diagnostic.Diagnostic( 495 | "error", "unknown unicode character name", {}, 496 | source.Range(self.source_buffer, 497 | range.begin_pos + match.start(0), 498 | range.begin_pos + match.end(0))) 499 | self.diagnostic_engine.process(error) 500 | 501 | return "".join(chunks) 502 | 503 | def _check_long_literal(self, range, literal): 504 | if literal[-1] in "lL" and self.version >= (3, 0): 505 | error = diagnostic.Diagnostic( 506 | "error", "in Python 3, long integer literals were removed", {}, 507 | source.Range(self.source_buffer, range.end_pos - 1, range.end_pos)) 508 | self.diagnostic_engine.process(error) 509 | 510 | def _match_pair_delim(self, range, kwop): 511 | if kwop == "(": 512 | self.parentheses.append(range) 513 | elif kwop == "[": 514 | self.square_braces.append(range) 515 | elif kwop == "{": 516 | self.curly_braces.append(range) 517 | elif kwop == ")": 518 | self._check_innermost_pair_delim(range, "(") 519 | self.parentheses.pop() 520 | elif kwop == "]": 521 | self._check_innermost_pair_delim(range, "[") 522 | self.square_braces.pop() 523 | elif kwop == "}": 524 | self._check_innermost_pair_delim(range, "{") 525 | self.curly_braces.pop() 526 | 527 | def _check_innermost_pair_delim(self, range, expected): 528 | ranges = [] 529 | if len(self.parentheses) > 0: 530 | ranges.append(("(", self.parentheses[-1])) 531 | if len(self.square_braces) > 0: 532 | ranges.append(("[", self.square_braces[-1])) 533 | if len(self.curly_braces) > 0: 534 | ranges.append(("{", self.curly_braces[-1])) 535 | 536 | ranges.sort(key=lambda k: k[1].begin_pos) 537 | if any(ranges): 538 | compl_kind, compl_range = ranges[-1] 539 | if compl_kind != expected: 540 | note = diagnostic.Diagnostic( 541 | "note", "'{delimiter}' opened here", 542 | {"delimiter": compl_kind}, 543 | compl_range) 544 | error = diagnostic.Diagnostic( 545 | "fatal", "mismatched '{delimiter}'", 546 | {"delimiter": range.source()}, 547 | range, notes=[note]) 548 | self.diagnostic_engine.process(error) 549 | else: 550 | error = diagnostic.Diagnostic( 551 | "fatal", "mismatched '{delimiter}'", 552 | {"delimiter": range.source()}, 553 | range) 554 | self.diagnostic_engine.process(error) 555 | 556 | def __iter__(self): 557 | return self 558 | 559 | def __next__(self): 560 | return self.next() 561 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/lexer.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/lexer.pyc -------------------------------------------------------------------------------- /ast/tester/pythonparser/parser.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/parser.pyc -------------------------------------------------------------------------------- /ast/tester/pythonparser/source.py: -------------------------------------------------------------------------------- 1 | """ 2 | The :mod:`source` module concerns itself with manipulating 3 | buffers of source code: creating ranges of characters corresponding 4 | to a token, combining these ranges, extracting human-readable 5 | location information and original source from a range. 6 | """ 7 | 8 | from __future__ import absolute_import, division, print_function, unicode_literals 9 | import bisect 10 | 11 | class Buffer: 12 | """ 13 | A buffer containing source code and location information. 14 | 15 | :ivar source: (string) source code 16 | :ivar name: (string) input filename or another description 17 | of the input (e.g. ````). 18 | :ivar line: (integer) first line of the input 19 | """ 20 | def __init__(self, source, name="", first_line=1): 21 | self.source = source 22 | self.name = name 23 | self.first_line = first_line 24 | self._line_begins = None 25 | 26 | def __repr__(self): 27 | return "Buffer(\"%s\")" % self.name 28 | 29 | def source_line(self, lineno): 30 | """ 31 | Returns line ``lineno`` from source, taking ``first_line`` into account, 32 | or raises :exc:`IndexError` if ``lineno`` is out of range. 33 | """ 34 | line_begins = self._extract_line_begins() 35 | lineno = lineno - self.first_line 36 | if lineno >= 0 and lineno + 1 < len(line_begins): 37 | first, last = line_begins[lineno:lineno + 2] 38 | return self.source[first:last] 39 | elif lineno >= 0 and lineno < len(line_begins): 40 | return self.source[line_begins[-1]:] 41 | else: 42 | raise IndexError 43 | 44 | def decompose_position(self, offset): 45 | """ 46 | Returns a ``line, column`` tuple for a character offset into the source, 47 | orraises :exc:`IndexError` if ``lineno`` is out of range. 48 | """ 49 | line_begins = self._extract_line_begins() 50 | lineno = bisect.bisect_right(line_begins, offset) - 1 51 | if offset >= 0 and offset <= len(self.source): 52 | return lineno + self.first_line, offset - line_begins[lineno] 53 | else: 54 | raise IndexError 55 | 56 | def _extract_line_begins(self): 57 | if self._line_begins: 58 | return self._line_begins 59 | 60 | self._line_begins = [0] 61 | index = None 62 | while True: 63 | index = self.source.find("\n", index) + 1 64 | if index == 0: 65 | return self._line_begins 66 | self._line_begins.append(index) 67 | 68 | class Range: 69 | """ 70 | Location of an exclusive range of characters [*begin_pos*, *end_pos*) 71 | in a :class:`Buffer`. 72 | 73 | :ivar begin_pos: (integer) offset of the first character 74 | :ivar end_pos: (integer) offset of the character before the last 75 | :ivar expanded_from: (Range or None) the range from which this range was expanded 76 | """ 77 | def __init__(self, source_buffer, begin_pos, end_pos, expanded_from=None): 78 | self.source_buffer = source_buffer 79 | self.begin_pos = begin_pos 80 | self.end_pos = end_pos 81 | self.expanded_from = expanded_from 82 | 83 | def __repr__(self): 84 | """ 85 | Returns a human-readable representation of this range. 86 | """ 87 | return "Range(\"%s\", %d, %d, %s)" % \ 88 | (self.source_buffer.name, self.begin_pos, self.end_pos, repr(self.expanded_from)) 89 | 90 | def chain(self, expanded_from): 91 | """ 92 | Returns a range identical to this one, but indicating that 93 | it was expanded from the range `expanded_from`. 94 | """ 95 | return Range(self.source_buffer, self.begin_pos, self.begin_pos, 96 | expanded_from=expanded_from) 97 | 98 | def begin(self): 99 | """ 100 | Returns a zero-length range located just before the beginning of this range. 101 | """ 102 | return Range(self.source_buffer, self.begin_pos, self.begin_pos, 103 | expanded_from=self.expanded_from) 104 | 105 | def end(self): 106 | """ 107 | Returns a zero-length range located just after the end of this range. 108 | """ 109 | return Range(self.source_buffer, self.end_pos, self.end_pos, 110 | expanded_from=self.expanded_from) 111 | 112 | def size(self): 113 | """ 114 | Returns the amount of characters spanned by the range. 115 | """ 116 | return self.end_pos - self.begin_pos 117 | 118 | def column(self): 119 | """ 120 | Returns a zero-based column number of the beginning of this range. 121 | """ 122 | line, column = self.source_buffer.decompose_position(self.begin_pos) 123 | return column 124 | 125 | def column_range(self): 126 | """ 127 | Returns a [*begin*, *end*) tuple describing the range of columns spanned 128 | by this range. If range spans more than one line, returned *end* is 129 | the last column of the line. 130 | """ 131 | if self.begin().line() == self.end().line(): 132 | return self.begin().column(), self.end().column() 133 | else: 134 | return self.begin().column(), len(self.begin().source_line()) - 1 135 | 136 | def line(self): 137 | """ 138 | Returns the line number of the beginning of this range. 139 | """ 140 | line, column = self.source_buffer.decompose_position(self.begin_pos) 141 | return line 142 | 143 | def join(self, other): 144 | """ 145 | Returns the smallest possible range spanning both this range and other. 146 | Raises :exc:`ValueError` if the ranges do not belong to the same 147 | :class:`Buffer`. 148 | """ 149 | if self.source_buffer != other.source_buffer: 150 | raise ValueError 151 | if self.expanded_from == other.expanded_from: 152 | expanded_from = self.expanded_from 153 | else: 154 | expanded_from = None 155 | return Range(self.source_buffer, 156 | min(self.begin_pos, other.begin_pos), 157 | max(self.end_pos, other.end_pos), 158 | expanded_from=expanded_from) 159 | 160 | def source(self): 161 | """ 162 | Returns the source code covered by this range. 163 | """ 164 | return self.source_buffer.source[self.begin_pos:self.end_pos] 165 | 166 | def source_line(self): 167 | """ 168 | Returns the line of source code containing the beginning of this range. 169 | """ 170 | return self.source_buffer.source_line(self.line()) 171 | 172 | def source_lines(self): 173 | """ 174 | Returns the lines of source code containing the entirety of this range. 175 | """ 176 | return [self.source_buffer.source_line(line) 177 | for line in range(self.line(), self.end().line() + 1)] 178 | 179 | def __str__(self): 180 | """ 181 | Returns a Clang-style string representation of the beginning of this range. 182 | """ 183 | if self.begin_pos != self.end_pos: 184 | return "%s:%d:%d-%d:%d" % (self.source_buffer.name, 185 | self.line(), self.column() + 1, 186 | self.end().line(), self.end().column() + 1) 187 | else: 188 | return "%s:%d:%d" % (self.source_buffer.name, 189 | self.line(), self.column() + 1) 190 | 191 | def __eq__(self, other): 192 | """ 193 | Returns true if the ranges have the same source buffer, start and end position. 194 | """ 195 | return (type(self) == type(other) and 196 | self.source_buffer == other.source_buffer and 197 | self.begin_pos == other.begin_pos and 198 | self.end_pos == other.end_pos and 199 | self.expanded_from == other.expanded_from) 200 | 201 | def __ne__(self, other): 202 | """ 203 | Inverse of :meth:`__eq__`. 204 | """ 205 | return not (self == other) 206 | 207 | def __hash__(self): 208 | return hash((self.source_buffer, self.begin_pos, self.end_pos, self.expanded_from)) 209 | 210 | class Comment: 211 | """ 212 | A comment in the source code. 213 | 214 | :ivar loc: (:class:`Range`) source location 215 | :ivar text: (string) comment text 216 | """ 217 | 218 | def __init__(self, loc, text): 219 | self.loc, self.text = loc, text 220 | 221 | class RewriterConflict(Exception): 222 | """ 223 | An exception that is raised when two ranges supplied to a rewriter overlap. 224 | 225 | :ivar first: (:class:`Range`) first overlapping range 226 | :ivar second: (:class:`Range`) second overlapping range 227 | """ 228 | 229 | def __init__(self, first, second): 230 | self.first, self.second = first, second 231 | exception.__init__(self, "Ranges %s and %s overlap" % (repr(first), repr(second))) 232 | 233 | class Rewriter: 234 | """ 235 | The :class:`Rewriter` class rewrites source code: performs bulk modification 236 | guided by a list of ranges and code fragments replacing their original 237 | content. 238 | 239 | :ivar buffer: (:class:`Buffer`) buffer 240 | """ 241 | 242 | def __init__(self, buffer): 243 | self.buffer = buffer 244 | self.ranges = [] 245 | 246 | def replace(self, range, replacement): 247 | """Remove `range` and replace it with string `replacement`.""" 248 | self.ranges.append((range, replacement)) 249 | 250 | def remove(self, range): 251 | """Remove `range`.""" 252 | self.replace(range, "") 253 | 254 | def insert_before(self, range, text): 255 | """Insert `text` before `range`.""" 256 | self.replace(range.begin(), text) 257 | 258 | def insert_after(self, range, text): 259 | """Insert `text` after `range`.""" 260 | self.replace(range.end(), text) 261 | 262 | def rewrite(self): 263 | """Return the rewritten source. May raise :class:`RewriterConflict`.""" 264 | self._sort() 265 | self._check() 266 | 267 | rewritten, pos = [], 0 268 | for range, replacement in self.ranges: 269 | rewritten.append(self.buffer.source[pos:range.begin_pos]) 270 | rewritten.append(replacement) 271 | pos = range.end_pos 272 | rewritten.append(self.buffer.source[pos:]) 273 | 274 | return Buffer("".join(rewritten), self.buffer.name, self.buffer.first_line) 275 | 276 | def _sort(self): 277 | self.ranges.sort(key=lambda x: x[0].begin_pos) 278 | 279 | def _check(self): 280 | for (fst, _), (snd, _) in zip(self.ranges, self.ranges[1:]): 281 | if snd.begin_pos < fst.end_pos: 282 | raise RewriterConflict(fst, snd) 283 | -------------------------------------------------------------------------------- /ast/tester/pythonparser/source.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/ast/tester/pythonparser/source.pyc -------------------------------------------------------------------------------- /ast/tester/test.py: -------------------------------------------------------------------------------- 1 | ''' 2 | LAB_NAME = "First doctest lab" 3 | 4 | LAB_DESCRIPTION = 5 | This is my first **lab** in [markdown](https://daringfireball.net/projects/markdown/syntax) format 6 | 7 | - shawn 8 | - is 9 | - cool 10 | 11 | woohoo! 12 | ''' 13 | 14 | # helper function written by student, not part of the lab 15 | def add(x, y): 16 | return x + y 17 | 18 | def slow_multiply(a, b): 19 | """ 20 | Lab part 2 21 | Return the product of 'a' and 'b' 22 | ------ 23 | >>> print slow_multiply(3, 5) 24 | 15 25 | """ 26 | i = 0 27 | prod = 0 28 | for i in range(b): 29 | prod = add(prod, a) 30 | return prod 31 | -------------------------------------------------------------------------------- /lexer/code: -------------------------------------------------------------------------------- 1 | 2 | a = [1 2 3 9 7 3] 3 | b=1 4 | 5 | adasfsafasa 6 | for i in a 7 | c = i * i + 3 / 2 8 | for var in [1367] 9 | print var*var 10 | -------------------------------------------------------------------------------- /lexer/for.py: -------------------------------------------------------------------------------- 1 | #Code to implement for loop 2 | a = [1, 2, 3, 9, 7, 3] 3 | b=1 4 | #2 variales 5 | '''adasfsafasa''' 6 | for i in a: 7 | c = i * i + 3 / 2 8 | for var in [1,3,6,7]: 9 | print var*var 10 | -------------------------------------------------------------------------------- /lexer/lex.py: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'for' : 'FOR', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | 'in' : 'IN', 15 | 'range': 'RANGE', 16 | 'not in' : 'NOTIN' 17 | } 18 | 19 | rl = [] 20 | for k in reserved: 21 | rl.append(reserved[k]) 22 | 23 | tokens=['LBRACE','RBRACE','RSBRACE','LSBRACE','LPAREN','RPAREN','ID','FUNC','PLUS','MINUS','TIMES','DIVIDE','EQUALS','NEWLINE','WHITE','NUMBER','COMMENT','ERROR','COL' ,'INTEGER','FLOAT','DOUBLE','STRING','MSTR', 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 24 | 25 | literals = [ '{', '}','[',']' , '(' , ')'] 26 | 27 | t_PLUS = r'\+' 28 | t_MINUS = r'-' 29 | t_TIMES = r'\*' 30 | t_DIVIDE = r'/' 31 | t_EQUALS = r'\=' 32 | t_GRT = r'>' 33 | t_LSR = r'<' 34 | t_GRTEQ = r'>=' 35 | t_LSREQ = r'<=' 36 | t_EQ = r'==' 37 | t_COL = r':' 38 | t_MSTR = r'\"\"\"[\n**\n*]*\"\"\"' 39 | t_STRING = r'\".*?\"' 40 | t_INTEGER = r'\d+' 41 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 42 | t_LPAREN = r'\(' 43 | t_RBRACE = r'\}' 44 | t_RPAREN = r'\)' 45 | t_LBRACE = r'\{' 46 | t_LSBRACE = r'\[' 47 | t_RSBRACE = r'\]' 48 | 49 | indent = [False,0] 50 | 51 | def t_lbrace(t): 52 | r'\{' 53 | t.type = '{' 54 | return t 55 | 56 | def t_rbrace(t): 57 | r'\}' 58 | t.type = '}' 59 | return t 60 | 61 | def t_lparen(t): 62 | r'\(' 63 | t.type = '(' 64 | return t 65 | 66 | def t_rparen(t): 67 | r'\)' 68 | t.type = ')' 69 | return t 70 | 71 | def t_rsbrace(t): 72 | r'\]' 73 | t.type = ']' 74 | return t 75 | def t_lsbrace(t): 76 | r'\[' 77 | t.type = '[' 78 | return t 79 | 80 | status = 0 #to keep track of indentation 81 | def t_tab(t): 82 | r'\t+' 83 | global status 84 | status = len(str(t.value)) - len(str(t.value).strip('\t')) 85 | 86 | def t_FUNC(t): 87 | '[d][e][f][\s]'r'[a-zA-Z_]*[a-zA-Z_0-9]*[(]*' 88 | t.value = str(t.value)[4:len(str(t.value))-2] 89 | return t 90 | 91 | def t_ID(t): 92 | r'[a-zA-Z_][a-zA-Z_0-9]*' 93 | t.type = reserved.get(t.value,'ID') 94 | return t 95 | 96 | def t_NUMBER(t): 97 | r'\d+' 98 | t.value = int(t.value) 99 | return t 100 | 101 | def t_indent(t): 102 | r'[:]\n' 103 | global indent 104 | indent=[True, len(str(t.value)) - len( str(t.value).strip() ) ] 105 | t.lexer.lineno += len(t.value) 106 | op.write('\n\t') 107 | 108 | 109 | def t_newline(t): 110 | r'\t+' 111 | t.lexer.lineno += len(t.value) 112 | op.write('\n') 113 | c = 0 114 | for i in str(t.value): 115 | if i in [' ',' ','\n','\t','\s']: 116 | c=c+1 117 | else: 118 | break 119 | global indent 120 | if c>0: 121 | indent = [True, c] 122 | else: 123 | indent = [False, 0] 124 | 125 | 126 | 127 | def t_error(t): 128 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 129 | t.lexer.skip(1) 130 | 131 | def t_COMMENT(t): 132 | r'\#.*' 133 | t.lexer.lineno += len(t.value) 134 | pass 135 | 136 | def t_WHITE(t): 137 | r'\s+' 138 | op.write(str(t.value)) 139 | pass 140 | 141 | 142 | lex.lex() 143 | 144 | 145 | data = open('/home/vamsi/Desktop/lexer/for.py','r') 146 | lex.input(data.read()) 147 | data.close() 148 | 149 | 150 | op = open('/home/vamsi/Desktop/lexer/code','w') 151 | 152 | st = open('/home/vamsi/Desktop/lexer/symbol_table','w') 153 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 154 | 155 | l=[] 156 | 157 | while True: 158 | tok = lex.token() 159 | if not tok: 160 | break 161 | print(tok,'\t\t\t',indent) 162 | op.write(str(tok.value)) 163 | 164 | if(tok.type in rl or str(tok.type) in ['ID','NUMBER','INTEGER','FLOAT','DOUBLE','STRING']): 165 | if tok.value not in [x[1] for x in l]: 166 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 167 | st.write(line) 168 | 169 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 170 | 171 | 172 | print('\n\n') 173 | #[print(x) for x in l] 174 | 175 | myFile = open('symbol_table.csv', 'w') 176 | with myFile: 177 | writer = csv.writer(myFile) 178 | writer.writerows(l) 179 | -------------------------------------------------------------------------------- /lexer/st.py: -------------------------------------------------------------------------------- 1 | '''import json 2 | from ast import parse 3 | import ast2json 4 | 5 | ast = ast2json(parse(open('for.py').read())) 6 | print (json.dumps(ast, indent=4)) 7 | ''' 8 | import ast 9 | fn=open("/home/vamsi/Desktop/CDnew/for.py","r") 10 | op=ast.parse(fn) 11 | ast.dump(tree) 12 | -------------------------------------------------------------------------------- /lexer/symbol_table: -------------------------------------------------------------------------------- 1 | TYPE VALUE LINE_NO LEXPOS 2 | 3 | ID a 28 28 4 | NUMBER 1 28 33 5 | NUMBER 2 28 36 6 | NUMBER 3 28 39 7 | NUMBER 9 28 42 8 | NUMBER 7 28 45 9 | ID b 28 51 10 | ID adasfsafasa 39 70 11 | FOR for 39 85 12 | ID i 39 89 13 | IN in 39 91 14 | ID c 41 98 15 | ID var 41 120 16 | NUMBER 6 41 132 17 | PRINT print 43 139 18 | -------------------------------------------------------------------------------- /lexer/symbol_table.csv: -------------------------------------------------------------------------------- 1 | ID,a,28,28 2 | NUMBER,1,28,33 3 | NUMBER,2,28,36 4 | NUMBER,3,28,39 5 | NUMBER,9,28,42 6 | NUMBER,7,28,45 7 | ID,b,28,51 8 | ID,adasfsafasa,39,70 9 | FOR,for,39,85 10 | ID,i,39,89 11 | IN,in,39,91 12 | ID,c,41,98 13 | ID,var,41,120 14 | NUMBER,6,41,132 15 | PRINT,print,43,139 16 | -------------------------------------------------------------------------------- /lexer/temp.py: -------------------------------------------------------------------------------- 1 | # Python program to find the factorial of a number provided by the user. 2 | 3 | # change the value for a different result 4 | num = 7 5 | 6 | # uncomment to take input from the user 7 | #num = int(input("Enter a number: ")) 8 | 9 | factorial = 1 10 | 11 | # check if the number is negative, positive or zero 12 | if num < 0: 13 | print("undefined") 14 | elif num == 0: 15 | print("fact=1") 16 | else: 17 | for i in range(1,num + 1): 18 | for j in range(0,1): 19 | factorial = factorial*i 20 | print("fact=",factorial) 21 | -------------------------------------------------------------------------------- /lexer/test.py: -------------------------------------------------------------------------------- 1 | digits = [0, 1, 5] 2 | for i in range(9): 3 | print(i) 4 | else: 5 | print("No items left.") 6 | -------------------------------------------------------------------------------- /optimization/o.txt: -------------------------------------------------------------------------------- 1 | var1=[1,2,3,9,7,3] 2 | var2=var1 3 | var3=1 4 | var5=0 5 | var6=var2 6 | var7=4 7 | if var5==var7 goto L1 8 | var9=var5*4 9 | var10=var9+100 10 | var11=var4*var4 11 | var12=3+3 12 | var13=var11+var12 13 | var14=var13 14 | var5=var5+1 15 | L1: 16 | var17=0 17 | var18=[1,3,6,7] 18 | var19=4 19 | var17=var17+1 20 | goto L1 21 | -------------------------------------------------------------------------------- /optimization/optimize.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | icg_file = "output_file.txt" 4 | istemp = lambda s : bool(re.match(r"^t[0-9]*$", s)) 5 | isid = lambda s : bool(re.match(r"^[A-Za-z][A-Za-z0-9_]*$", s)) #can be temp also 6 | binary_operators = {"+", "-", "*", "/", "*", "&", "|", "^", ">>", "<<", "==", ">=", "<=", "!=", ">", "<"} 7 | def printicg(list_of_lines, message = "") : 8 | print(message.upper()) 9 | for line in list_of_lines : 10 | print(line.strip()) 11 | 12 | 13 | def eval_wrap(line) : 14 | tokens = line.split() 15 | if len(tokens) != 5 : 16 | return line 17 | if tokens[1] != "=" or tokens[3] not in binary_operators: 18 | return line 19 | #tokens = tokens[2:] 20 | if tokens[2].isdigit() and tokens[4].isdigit() : 21 | result = eval(str(tokens[2] + tokens[3] + tokens[4])) 22 | return " ".join([tokens[0], tokens[1], str(result)]) 23 | if tokens[2].isdigit() or tokens[4].isdigit() : #Replace the identifier with a number and evaluate 24 | op1 = "5" if isid(tokens[2]) else tokens[2] 25 | op2 = "5" if isid(tokens[4]) else tokens[4] 26 | op = tokens[3] 27 | try : 28 | result = int(eval(op1+op+op2)) 29 | if result == 0 : #multiplication with 0 30 | return " ".join([tokens[0],tokens[1], "0"]) 31 | elif result == 5 : #add zero, subtract 0, multiply 1, divide 1 32 | if isid(tokens[2]) and tokens[4].isdigit() : 33 | return " ".join([tokens[0], tokens[1], tokens[2]]) 34 | elif isid(tokens[4]) and tokens[2].isdigit(): 35 | return " ".join([tokens[0], tokens[1], tokens[4]]) 36 | elif result == -5 and tokens[2] == "0" : # 0 - id 37 | return " ".join([tokens[0], tokens[1], "-"+tokens[4]]) 38 | return " ".join(tokens) 39 | 40 | except NameError : 41 | return line 42 | except ZeroDivisionError : 43 | print("Division By Zero is undefined") 44 | quit() 45 | return line 46 | 47 | 48 | def fold_constants(list_of_lines) : 49 | """ 50 | Some expressions that can have a definite answer need not be waste run time resources : 51 | e.g. 52 | 1. number + number, number - number etc. 53 | 2. identifier + 0, identfier / 0, identifer - 0, identifier*0 and their commutatives 54 | 3. identifier * 1, identifier / 1 55 | """ 56 | 57 | new_list_of_lines = [] 58 | for line in list_of_lines : 59 | new_list_of_lines.append(eval_wrap(line)) 60 | return new_list_of_lines 61 | 62 | def remove_dead_code(list_of_lines) : 63 | """ 64 | Temporaries that are never assigned to any variable nor used in any expression are deleted. Done recursively. 65 | """ 66 | num_lines = len(list_of_lines) 67 | temps_on_lhs = set() 68 | for line in list_of_lines : 69 | tokens = line.split() 70 | if istemp(tokens[0]) : 71 | temps_on_lhs.add(tokens[0]) 72 | 73 | useful_temps = set() 74 | for line in list_of_lines : 75 | tokens = line.split() 76 | if len(tokens) >= 2 : 77 | if istemp(tokens[1]) : 78 | useful_temps.add(tokens[1]) 79 | if len(tokens) >= 3 : 80 | if istemp(tokens[2]) : 81 | useful_temps.add(tokens[2]) 82 | 83 | temps_to_remove = temps_on_lhs - useful_temps 84 | new_list_of_lines = [] 85 | for line in list_of_lines : 86 | tokens = line.split() 87 | if tokens[0] not in temps_to_remove : 88 | new_list_of_lines.append(line) 89 | if num_lines == len(new_list_of_lines) : 90 | return new_list_of_lines 91 | return remove_dead_code(new_list_of_lines) 92 | 93 | if __name__ == "__main__" : 94 | if len(sys.argv) == 2 : 95 | icg_file = str(sys.argv[1]) 96 | 97 | list_of_lines = [] 98 | f = open(icg_file, "r") 99 | for line in f : 100 | list_of_lines.append(line) 101 | f.close() 102 | 103 | printicg(list_of_lines, "ICG") 104 | without_deadcode = remove_dead_code(list_of_lines) 105 | printicg(without_deadcode, "Optimized ICG after removing dead code") 106 | print("Eliminated", len(list_of_lines)-len(without_deadcode), "lines of code") 107 | 108 | printicg(list_of_lines, "ICG") 109 | folded_constants = fold_constants(list_of_lines) 110 | printicg(folded_constants, "Optimized ICG after constant folding") 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /optimization/output_file.txt: -------------------------------------------------------------------------------- 1 | i = 0 2 | L1 : 3 | t0 = i < 7 4 | ifFalse t0 goto L4 5 | goto L2 6 | L3 : 7 | t1 = i + 1 8 | i = t1 9 | goto L1 10 | L2 : 11 | t2 = 9 * 4 12 | t3 = t2 * 1 13 | t4 = t3 * 4 14 | t5 = x > 5 15 | ifFalse t5 goto L5 16 | t6 = 32 17 | goto L6 18 | L5 : 19 | t7 = 123 * 3 20 | t6 = t7 21 | goto L6 22 | L6 : 23 | goto L3 24 | L4: 25 | -------------------------------------------------------------------------------- /parser and icg/bin/2lex_cleaner.py: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'while' : 'WHILE', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | } 15 | 16 | rl = [] #reserved word list 17 | for k in reserved: 18 | rl.append(reserved[k]) 19 | 20 | # List of token names. This is always required 21 | tokens = ['LBRACE','RBRACE', 22 | 'LPAREN','RPAREN', 23 | 'ID','FUNC', 24 | 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 25 | 'NEWLINE','WHITE','NUMBER','INDENT', 26 | 'COMMENT',#'MULTCOM', 27 | 'ERROR','COL', 28 | 'INTEGER','FLOAT','STRING', 29 | 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 30 | 31 | literals = [ '{', '}' , '(' , ')'] 32 | 33 | t_PLUS = r'\+' 34 | t_MINUS = r'-' 35 | t_TIMES = r'\*' 36 | t_DIVIDE = r'/' 37 | t_EQUALS = r'\=' 38 | t_GRT = r'>' 39 | t_LSR = r'<' 40 | t_GRTEQ = r'>=' 41 | t_LSREQ = r'<=' 42 | t_EQ = r'==' 43 | t_COL = r':' 44 | t_INTEGER = r'\d+' 45 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 46 | t_STRING = r'\".*?\"' 47 | t_LPAREN = r'\(' 48 | t_RBRACE = r'\}' 49 | t_RPAREN = r'\)' 50 | t_LBRACE = r'\{' 51 | 52 | #def t_lbrace(t): 53 | # r'\{' 54 | # t.type = '{' # Set token type to the expected literal 55 | # return t 56 | 57 | #def t_rbrace(t): 58 | # r'\}' 59 | # t.type = '}' # Set token type to the expected literal 60 | # return t 61 | 62 | #def t_lparen(t): 63 | # r'\(' 64 | # t.type = '(' # Set token type to the expected literal 65 | # return t 66 | 67 | #def t_rparen(t): 68 | # r'\)' 69 | # t.type = ')' # Set token type to the expected literal 70 | # return t 71 | 72 | #def t_FUNC(t): 73 | # r'[d][e][f][\s][a-zA-Z_]*[a-zA-Z_0-9]*[(]*' 74 | # t.value = str(t.value)[4:len(str(t.value))-2] 75 | # return t 76 | 77 | def t_ID(t): 78 | r'[a-zA-Z_][a-zA-Z_0-9]*' 79 | t.type = reserved.get(t.value,'ID') # Check for reserved words 80 | return t 81 | 82 | def t_NUMBER(t): 83 | r'\d+' 84 | t.value = int(t.value) 85 | return t 86 | 87 | #def t_indent(t): 88 | # c = 0 89 | # for i in str(t.value): 90 | # if i in ['\s']: 91 | # c=c+1 92 | # else: 93 | # break 94 | 95 | # global indent 96 | # if c>0: 97 | # indent = [True, c] 98 | # else: 99 | # indent = [False, 0] 100 | 101 | 102 | # Define a rule so we can track line numbers 103 | def t_NEWLINE(t): 104 | r'\n+' 105 | t.lexer.lineno += len(t.value) 106 | # op.write('\n') 107 | return t 108 | 109 | # Error handling rule 110 | def t_error(t): 111 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 112 | t.lexer.skip(1) 113 | 114 | def t_COMMENT(t): 115 | r'\#.*' 116 | pass 117 | # No return value. Token discarded 118 | 119 | def t_WHITE(t): 120 | r'\s+' 121 | op.write(str(t.value)) 122 | return t 123 | 124 | 125 | #def t_MULTCOM(t): 126 | # r'\""".*.\"""' 127 | # pass 128 | 129 | # Build the lexer 130 | lex.lex() 131 | 132 | 133 | # Give the lexer some input 134 | data = open('temp.py','r') 135 | lex.input(data.read()) 136 | data.close() 137 | 138 | #modified code file 139 | op = open('op.py','w') 140 | 141 | #symbol table file 142 | st = open('st','w') 143 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 144 | 145 | l=[] #tokens list of lists 146 | al =[] #all tokens 147 | 148 | newl = [0 , 0] # [ lineno , lexpos ] 149 | 150 | ti = 0 #token index 151 | # Tokenize 152 | while True: 153 | tok = lex.token() 154 | 155 | if not tok: 156 | break # No more input 157 | # print(tok) 158 | al.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 159 | op.write(str(tok.value)) #modified code 160 | 161 | #symbol table file 162 | if(tok.type in rl or str(tok.type) in ['NUMBER','INTEGER','FLOAT','STRING']): 163 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 164 | st.write(line) 165 | 166 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 167 | ti += 1 168 | 169 | if (str(tok.type) == 'ID'): 170 | # print([x[1] for x in l]) 171 | if tok.value not in [x[1] for x in l] : 172 | tok.type = 'GLOBAL_ID' 173 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 174 | st.write(line) 175 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 176 | else: 177 | ln = tok.lineno - 1 178 | temp_l = [ x[0] for x in al if int(x[2])==ln ] 179 | while len(temp_l)>0 and temp_l[0] == 'WHITE' and str(tok.value) not in temp_l and 'DEF' not in temp_l : 180 | ln -= 1 181 | temp_l = [ x[0] for x in al if int(x[2])==ln ] 182 | 183 | temp_l = [x[0] for x in al if int(x[2]==ln)] 184 | 185 | if len(temp_l)>0 and temp_l[0] == 'DEF' and str(tok.value) not in temp_l: 186 | tok.type = 'LOCAL_ID' 187 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 188 | st.write(line) 189 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 190 | 191 | total = tok.lineno 192 | 193 | #[print(x) for x in l] 194 | 195 | 196 | #writing to csv file 197 | myFile = open('symbol_table.csv', 'w') 198 | with myFile: 199 | writer = csv.writer(myFile) 200 | writer.writerows(l) 201 | 202 | #yacc 203 | 204 | # Precedence rules for the arithmetic operators 205 | precedence = ( 206 | ('left','PLUS','MINUS'), 207 | ('left','TIMES','DIVIDE'), 208 | ('right','UMINUS'), 209 | ) 210 | 211 | # dictionary of names (for storing variables) 212 | names = { } 213 | 214 | def p_while(p): 215 | 'statement : WHILE LPAREN expression RPAREN COL statement' 216 | if p[3] > 0 : print(p[6]) 217 | 218 | def p_check_if(p): 219 | '''statement : IF LPAREN expression RPAREN COL statement ELIF LPAREN expression RPAREN statement 220 | | IF LPAREN expression RPAREN COL statement ELSE COL statement 221 | | IF LPAREN expression RPAREN COL statement''' 222 | 223 | if p[3] > 0: print(p[6]) 224 | elif p[3]<0 and p[9]>0: print(p[9]) 225 | elif p[3]<0 : print(p[8]) 226 | 227 | def p_statement_assign(p): 228 | 'statement : NAME EQUALS expression' 229 | names[p[1]] = p[3] 230 | 231 | def p_statement_expr(p): 232 | 'statement : expression' 233 | print(p[1]) 234 | 235 | def p_expression_binop(p): 236 | '''expression : expression PLUS expression 237 | | expression MINUS expression 238 | | expression TIMES expression 239 | | expression DIVIDE expression''' 240 | if p[2] == '+' : p[0] = p[1] + p[3] 241 | elif p[2] == '-': p[0] = p[1] - p[3] 242 | elif p[2] == '*': p[0] = p[1] * p[3] 243 | elif p[2] == '/': p[0] = p[1] / p[3] 244 | 245 | def p_expression_uminus(p): 246 | 'expression : MINUS expression %prec UMINUS' 247 | p[0] = -p[2] 248 | 249 | def p_expression_group(p): 250 | 'expression : LPAREN expression RPAREN' 251 | p[0] = p[2] 252 | 253 | def p_expression_number(p): 254 | 'expression : NUMBER' 255 | p[0] = p[1] 256 | 257 | def p_expression_name(p): 258 | 'expression : NAME' 259 | try: 260 | p[0] = names[p[1]] 261 | except LookupError: 262 | print("Undefined name '%s'" % p[1]) 263 | p[0] = 0 264 | 265 | def p_error(p): 266 | print("Syntax error at '%s'" % p.value) 267 | 268 | import ply.yacc as yacc 269 | yacc.yacc() 270 | 271 | o=open('op','r') 272 | for line in o: 273 | try: 274 | yacc.parse(line) 275 | except EOFError: 276 | break 277 | -------------------------------------------------------------------------------- /parser and icg/bin/2lex_cleaner.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/2lex_cleaner.pyc -------------------------------------------------------------------------------- /parser and icg/bin/__pycache__/lex.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/__pycache__/lex.cpython-36.pyc -------------------------------------------------------------------------------- /parser and icg/bin/__pycache__/parsetab.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/__pycache__/parsetab.cpython-36.pyc -------------------------------------------------------------------------------- /parser and icg/bin/__pycache__/yacc.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/__pycache__/yacc.cpython-36.pyc -------------------------------------------------------------------------------- /parser and icg/bin/a.txt: -------------------------------------------------------------------------------- 1 | fun : 2 | 0: ['var4', 10, '', '='] 3 | 1: ['', '', '', 'JUMP_RETURN'] 4 | program : 5 | 0: ['var1', 8, '', '='] 6 | 1: ['var2', 10, '', '='] 7 | 2: ['"hi HEllo"', '', 'STRING', 'PRINT'] 8 | 3: ['"\n"', '', 'STRING', 'PRINT'] 9 | 4: ['', '', -1, 'HALT'] 10 | 11 | 12 | SYMBOL TABLE 13 | -------------- 14 | 15 | SCOPE: fun 16 | ----------------------- 17 | {'j': {'fun': 'var4', 'offset': 0, 'type': 'NUMBER', 'width': 4}, 18 | 'numParam': 0, 19 | 'parentName': 'program', 20 | 'returnType': 'UNDEFINED', 21 | 'scopeName': 'fun', 22 | 'type': 'FUNCTION', 23 | 'width': 4} 24 | ----------------------- 25 | 26 | 27 | SCOPE: program 28 | ----------------------- 29 | {'False': {'fun': 0, 30 | 'offset': 15, 31 | 'program': 0, 32 | 'type': 'BOOLEAN', 33 | 'width': 1}, 34 | 'True': {'fun': 1, 'offset': 14, 'program': 1, 'type': 'BOOLEAN', 'width': 1}, 35 | 'a': {'offset': 2, 'program': 'var1', 'type': 'NUMBER', 'width': 4}, 36 | 'fun': {'j': {'fun': 'var4', 'offset': 0, 'type': 'NUMBER', 'width': 4}, 37 | 'numParam': 0, 38 | 'parentName': 'program', 39 | 'returnType': 'UNDEFINED', 40 | 'scopeName': 'fun', 41 | 'type': 'FUNCTION', 42 | 'width': 4}, 43 | 'i': {'offset': 6, 'program': 'var2', 'type': 'NUMBER', 'width': 4}, 44 | 'numParam': 0, 45 | 'returnType': 'UNDEFINED', 46 | 'scopeName': 'program', 47 | 'type': 'FUNCTION', 48 | 'width': 16} 49 | ----------------------- 50 | 51 | -------------------------------------------------------------------------------- /parser and icg/bin/code.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | i=10 6 | 7 | 8 | 9 | if(i<10): 10 | 11 | 12 | 13 | print(i) 14 | 15 | 16 | 17 | def fun(): 18 | 19 | 20 | 21 | i=20 22 | 23 | 24 | 25 | print(i) 26 | 27 | 28 | 29 | j=34+2 30 | 31 | 32 | 33 | print(j) 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /parser and icg/bin/code.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/code.pyc -------------------------------------------------------------------------------- /parser and icg/bin/converter.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def isAction(x): 4 | first = x[:x.find(":")] 5 | if first=="Action ": 6 | return True 7 | 8 | def isReduce(x): 9 | third = x[x.find(":")+2:x.find(":")+3] 10 | if third == "R": 11 | return True 12 | else: 13 | return False 14 | 15 | def getRule(x): 16 | rule = x[x.find("[")+1:x.find("]")] 17 | return rule 18 | 19 | def left(x): 20 | return x[:x.find(" ")] 21 | 22 | def right(x): 23 | children = x[x.find("->")+3:] 24 | children = children.split() 25 | return children 26 | 27 | def getValue(x): 28 | value = x[x.find("with [")+6:x.find("] and")] 29 | value = value.replace("\\","\\\\") 30 | value = value.replace('"','\\\"') 31 | ans = [] 32 | i = 0 33 | while i < len(value): 34 | if(value[i]==','): 35 | i+=1 36 | S = "" 37 | count = 0 38 | if value[i]!="'": 39 | while i"): 75 | continue 76 | nodeId+=1 77 | stack.append((child,nodeId,item[2])) 78 | if(value[i]!="None"): 79 | print "\tnode"+str(nodeId)+" [label= \""+child+"\\n"+value[i]+"\"];" 80 | else: 81 | print "\tnode"+str(nodeId)+" [label= \""+child+"\"];" 82 | 83 | print "\tnode"+str(item[1])+" -> node"+str(nodeId)+";" 84 | i+=1 85 | else: 86 | stack.pop() 87 | pass 88 | print "}" 89 | assert(len(stack)==0) -------------------------------------------------------------------------------- /parser and icg/bin/converter.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/converter.pyc -------------------------------------------------------------------------------- /parser and icg/bin/lex.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/lex.pyc -------------------------------------------------------------------------------- /parser and icg/bin/lexer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import lex 3 | from lex import TOKEN 4 | import tokenize 5 | 6 | NO_INDENT = 0 7 | MAY_INDENT = 1 8 | MUST_INDENT = 2 9 | errorList=[] 10 | tokens=[] 11 | keywordlist = [ 12 | 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 13 | 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 14 | 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 15 | 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 16 | 'with', 'yield' 17 | ] 18 | 19 | RESERVED = {} 20 | for keyword in keywordlist: 21 | name = keyword.upper() 22 | RESERVED[keyword] = name 23 | tokens.append(name) 24 | 25 | tokens = tuple(tokens) + ( 26 | 'EQEQUAL','NOTEQUAL','LESSEQUAL','LEFTSHIFT','GREATEREQUAL', 27 | 'RIGHTSHIFT','PLUSEQUAL','MINEQUAL','STAREQUAL','SLASHEQUAL','PERCENTEQUAL', 28 | 'STARSTAR','SLASHSLASH','STARSTAREQUAL','SLASHSLASHEQUAL', 29 | 'COLON','COMMA','SEMI','PLUS','MINUS','STAR','SLASH','VBAR','AMPER','LESS', 30 | 'GREATER','EQUAL','DOT','PERCENT','BACKQUOTE','CIRCUMFLEX','TILDE', 'AT', 31 | 32 | 'LPAREN', 'RPAREN', 33 | 'LBRACE', 'RBRACE', 34 | 'LSQB', 'RSQB', 35 | 'NEWLINE', 36 | 'INUMBER','FNUMBER', 37 | 'BINARYNUMBER','OCTALNUMBER','HEXADECIMALNUMBER', 38 | 'NUMBER', 39 | 'INDENT', 'DEDENT', 40 | 'TRIPLESTRING', 'STRING', 41 | 'RAWSTRING','UNICODESTRING', 42 | 'NAME','WS', 43 | 'ENDMARKER' 44 | ) 45 | 46 | # Regular expression rules for simple tokens 47 | t_EQEQUAL = r'==' 48 | t_NOTEQUAL = r'!=' 49 | t_LESSEQUAL = r'<=' 50 | t_LEFTSHIFT = r'<<' 51 | t_GREATEREQUAL = r'>=' 52 | t_RIGHTSHIFT = r'>>' 53 | t_PLUSEQUAL = r'\+=' 54 | t_MINEQUAL = r'-=' 55 | t_STAREQUAL = r'\*=' 56 | t_SLASHEQUAL = r'/=' 57 | t_PERCENTEQUAL = r'%=' 58 | t_STARSTAR = r'\*\*' 59 | t_SLASHSLASH = r'//' 60 | t_STARSTAREQUAL = r'\*\*=' 61 | t_SLASHSLASHEQUAL = r'//=' 62 | 63 | t_COLON = r':' 64 | t_COMMA = r',' 65 | t_SEMI = r';' 66 | t_PLUS = r'\+' 67 | t_MINUS = r'-' 68 | t_STAR = r'\*' 69 | t_SLASH = r'/' 70 | t_VBAR = r'\|' 71 | t_AMPER = r'&' 72 | t_LESS = r'<' 73 | t_GREATER = r'>' 74 | t_EQUAL = r'=' 75 | t_DOT = r'\.' 76 | t_PERCENT = r'%' 77 | t_BACKQUOTE = r'`' 78 | t_CIRCUMFLEX = r'\^' 79 | t_TILDE = r'~' 80 | t_AT = r'@' 81 | 82 | def newToken(newType, lineno): 83 | tok = lex.LexToken() 84 | tok.type = newType 85 | tok.value = None 86 | tok.lineno = lineno 87 | tok.lexpos = -100 88 | return tok 89 | def t_LPAREN(t): 90 | r"\(" 91 | t.lexer.parenthesisCount+=1 92 | return t 93 | def t_RPAREN(t): 94 | r"\)" 95 | t.lexer.parenthesisCount-=1 96 | return t 97 | def t_LBRACE(t): 98 | r"\{" 99 | t.lexer.parenthesisCount+=1 100 | return t 101 | def t_RBRACE(t): 102 | r"\}" 103 | t.lexer.parenthesisCount-=1 104 | return t 105 | def t_LSQB(t): 106 | r"\[" 107 | t.lexer.parenthesisCount+=1 108 | return t 109 | def t_RSQB(t): 110 | r"\]" 111 | t.lexer.parenthesisCount-=1 112 | return t 113 | 114 | #ignore comments in source code 115 | def t_comment(t): 116 | r"[ ]*\043[^\n]*" 117 | pass 118 | @TOKEN(tokenize.Imagnumber) 119 | def t_INUMBER(t): 120 | return t 121 | @TOKEN(tokenize.Floatnumber) 122 | def t_FNUMBER(t): 123 | return t 124 | # FP number above integers 125 | def t_BINARYNUMBER(t): 126 | r'0[bB]([0-1]+)' 127 | return t 128 | def t_OCTALNUMBER(t): 129 | r'0[oO]([0-7]+)' 130 | return t 131 | def t_HEXADECIMALNUMBER(t): 132 | r'0[xX]([0-9a-fA-F]+)' 133 | return t 134 | 135 | def t_NUMBER(t): 136 | r'\d+' 137 | t.value = int(t.value) 138 | return t 139 | 140 | def t_TRIPLESTRING(t): 141 | r'"{3}([\s\S]*?"{3}) | \'{3}([\s\S]*?\'{3})' 142 | return t 143 | def t_RAWSTRING(t): 144 | r'[rR](\"(\\.|[^\"\n]|(\\\n))*\") | [rR](\'(\\.|[^\'\n]|(\\\n))*\')' 145 | return t 146 | def t_UNICODESTRING(t): 147 | r'[uU](\"(\\.|[^\"\n]|(\\\n))*\") | [uU](\'(\\.|[^\'\n]|(\\\n))*\')' 148 | return t 149 | def t_STRING(t): 150 | r'(\"(\\.|[^\"\n]|(\\\n))*\") | (\'(\\.|[^\'\n]|(\\\n))*\')' 151 | return t 152 | def t_continueLine(t): 153 | r'\\(\n)+' 154 | def t_newline(t): 155 | r'\n+' 156 | t.lexer.lineno += len(t.value) 157 | t.type = "NEWLINE" 158 | if(t.lexer.parenthesisCount == 0): 159 | return t 160 | 161 | def t_NAME(t): 162 | r"[a-zA-Z_][a-zA-Z0-9_]*" 163 | t.type = RESERVED.get(t.value, "NAME") 164 | return t 165 | 166 | # Error handling rule 167 | def t_error(t): 168 | message = "\n# ERROR: Illegal character '%s' in %s at line %d" % (t.value[0], t.value, t.lineno) 169 | print message 170 | errorList.append(message) 171 | t.lexer.skip(1) 172 | 173 | # REFERENCE: https://docs.python.org/2/reference/lexical_analysis.html 174 | # WHITESPACE 175 | def t_WS(t): 176 | r" [ \t\f]+ " 177 | value = t.value 178 | value = value.rsplit("\f", 1)[-1] 179 | pos = 0 180 | while True: 181 | pos = value.find("\t") 182 | if pos == -1: 183 | break 184 | n = 8 - (pos % 8) # Convert each \t to 8 spaces (Python Documentation) 185 | value = value[:pos] + " "*n + value[pos+1:] 186 | t.value = value 187 | if t.lexer.atLineStart and t.lexer.parenthesisCount == 0: 188 | return t 189 | def INDENT(lineno): 190 | return newToken("INDENT", lineno) 191 | def DEDENT(lineno): 192 | return newToken("DEDENT",lineno) 193 | # From Python 2 documentation: 194 | # The indentation levels of consecutive lines are used to generate INDENT and DEDENT tokens, 195 | # using a stack, as follows. 196 | # Before the first line of the file is read, a single zero is pushed on the stack; 197 | # this will never be popped off again. The numbers pushed on the stack will always 198 | # be strictly increasing from bottom to top. At the beginning of each logical line, 199 | # the line's indentation level is compared to the top of the stack. If it is equal, 200 | # nothing happens. If it is larger, it is pushed on the stack, and one INDENT token 201 | # is generated. If it is smaller, it must be one of the numbers occurring on the stack; 202 | # all numbers on the stack that are larger are popped off, and for each number popped 203 | # off a DEDENT token is generated. At the end of the file, a DEDENT token is generated 204 | # for each number remaining on the stack that is larger than zero. 205 | 206 | def identifyIndenations(lexer, token_stream): 207 | lexer.atLineStart = atLineStart = True 208 | indent = NO_INDENT 209 | saw_colon = False 210 | for token in token_stream: 211 | token.atLineStart = atLineStart 212 | if token.type == "COLON": 213 | atLineStart = False 214 | indent = MAY_INDENT 215 | token.must_indent = False 216 | elif token.type == "NEWLINE": 217 | atLineStart = True 218 | if indent == MAY_INDENT: 219 | indent = MUST_INDENT # MUST INDENT 220 | token.must_indent = False 221 | elif token.type == "WS": 222 | assert token.atLineStart == True 223 | atLineStart = True 224 | token.must_indent = False 225 | else: 226 | if indent == MUST_INDENT: 227 | token.must_indent = True 228 | else: 229 | token.must_indent = False 230 | atLineStart = False 231 | indent = NO_INDENT 232 | 233 | yield token 234 | lexer.atLineStart = atLineStart 235 | 236 | def assignIndentations(token_stream): 237 | levels = [0] 238 | token = None 239 | depth = 0 240 | lastSeenWhitespace = False 241 | for token in token_stream: 242 | if token.type == "WS": 243 | assert depth == 0 244 | depth = len(token.value) 245 | lastSeenWhitespace = True 246 | continue 247 | if token.type == "NEWLINE": 248 | depth = 0 249 | if lastSeenWhitespace or token.atLineStart: 250 | continue 251 | yield token 252 | continue 253 | lastSeenWhitespace = False 254 | if token.must_indent: 255 | if not (depth > levels[-1]): 256 | # raise IndentationError("Expected an indented block") 257 | print "Indentation Error in line no "+str(token.lineno) 258 | sys.exit() 259 | levels.append(depth) 260 | yield INDENT(token.lineno) 261 | elif token.atLineStart: 262 | if depth == levels[-1]: 263 | pass 264 | elif depth > levels[-1]: 265 | print "Indentation Error in line no "+str(token.lineno) 266 | sys.exit() 267 | # raise IndentationError("IndentationError: not in new block") 268 | else: 269 | try: 270 | i = levels.index(depth) 271 | except ValueError: 272 | print "Indentation Error in line no "+str(token.lineno) 273 | sys.exit() 274 | # raise IndentationError("Inconsistent Indentation") 275 | for z in range(i+1, len(levels)): 276 | yield DEDENT(token.lineno) 277 | levels.pop() 278 | yield token 279 | if len(levels) > 1: 280 | assert token is not None 281 | for z in range(1, len(levels)): 282 | yield DEDENT(token.lineno) 283 | 284 | # This filter was in main() of previous lexer 285 | def filter(lexer, addEndMarker = True): 286 | token_stream = iter(lexer.token, None) 287 | token_stream = identifyIndenations(lexer, token_stream) 288 | token_stream = assignIndentations(token_stream) 289 | tok = None 290 | for tok in token_stream: 291 | yield tok 292 | if addEndMarker: 293 | lineno = 1 294 | if tok is not None: 295 | lineno = tok.lineno 296 | yield newToken("ENDMARKER", lineno) 297 | 298 | # To merge ply's lexer with indent feature 299 | # Built from previous main() 300 | class G1Lexer(object): 301 | def __init__(self): 302 | self.lexer = lex.lex() 303 | self.token_stream = None 304 | def input(self, data, addEndMarker=True): 305 | self.lexer.parenthesisCount = 0 306 | data+="\n" 307 | self.lexer.input(data) 308 | self.token_stream = filter(self.lexer, addEndMarker) 309 | def token(self): 310 | try: 311 | return self.token_stream.next() 312 | except StopIteration: 313 | return None 314 | 315 | # g1 = G1Lexer() 316 | # data = open('../test/test1.py').read() 317 | # g1.input(data) 318 | # t = g1.token() 319 | # while t: 320 | # print t 321 | # t = g1.token() -------------------------------------------------------------------------------- /parser and icg/bin/lexer.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/lexer.pyc -------------------------------------------------------------------------------- /parser and icg/bin/op: -------------------------------------------------------------------------------- 1 | 2 | i=10 3 | 4 | if(i<10): 5 | 6 | print(i) 7 | 8 | def fun(): 9 | 10 | i=20 11 | 12 | print(i) 13 | 14 | j=34+2 15 | 16 | print(j) 17 | 18 | -------------------------------------------------------------------------------- /parser and icg/bin/op.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | i=10 4 | 5 | if(i<10): 6 | 7 | print(i) 8 | 9 | def fun(): 10 | 11 | i=20 12 | 13 | print(i) 14 | 15 | j=34+2 16 | 17 | print(j) 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /parser and icg/bin/op.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/op.pyc -------------------------------------------------------------------------------- /parser and icg/bin/out.txt: -------------------------------------------------------------------------------- 1 | fun : 2 | 0: ['var4', 20, '', '='] 3 | 1: ['var4', '', 'NUMBER', 'PRINT'] 4 | 2: ['"\n"', '', 'STRING', 'PRINT'] 5 | 3: ['', '', '', 'JUMP_RETURN'] 6 | program : 7 | 0: ['var1', 10, '', '='] 8 | 1: ['var2', 'var1', 10, '<'] 9 | 2: ['var2', 0, 5, 'COND_GOTO'] 10 | 3: ['var1', '', 'NUMBER', 'PRINT'] 11 | 4: ['"\n"', '', 'STRING', 'PRINT'] 12 | 5: ['var5', 34, 2, '+'] 13 | 6: ['var6', 'var5', '', '='] 14 | 7: ['var6', '', 'NUMBER', 'PRINT'] 15 | 8: ['"\n"', '', 'STRING', 'PRINT'] 16 | 9: ['', '', -1, 'HALT'] 17 | 18 | 19 | SYMBOL TABLE 20 | -------------- 21 | 22 | SCOPE: fun 23 | ----------------------- 24 | {'numParam': 0, 25 | 'parentName': 'program', 26 | 'returnType': 'UNDEFINED', 27 | 'scopeName': 'fun', 28 | 'type': 'FUNCTION', 29 | 'width': 0} 30 | ----------------------- 31 | 32 | 33 | SCOPE: program 34 | ----------------------- 35 | {'False': {'fun': 0, 36 | 'offset': 11, 37 | 'program': 0, 38 | 'type': 'BOOLEAN', 39 | 'width': 1}, 40 | 'True': {'fun': 1, 'offset': 10, 'program': 1, 'type': 'BOOLEAN', 'width': 1}, 41 | 'fun': {'numParam': 0, 42 | 'parentName': 'program', 43 | 'returnType': 'UNDEFINED', 44 | 'scopeName': 'fun', 45 | 'type': 'FUNCTION', 46 | 'width': 0}, 47 | 'i': {'fun': 'var4', 48 | 'offset': 2, 49 | 'program': 'var1', 50 | 'type': 'NUMBER', 51 | 'width': 4}, 52 | 'j': {'offset': 12, 'program': 'var6', 'type': 'NUMBER', 'width': 4}, 53 | 'numParam': 0, 54 | 'returnType': 'UNDEFINED', 55 | 'scopeName': 'program', 56 | 'type': 'FUNCTION', 57 | 'width': 16} 58 | ----------------------- 59 | 60 | -------------------------------------------------------------------------------- /parser and icg/bin/parser.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/parser.pyc -------------------------------------------------------------------------------- /parser and icg/bin/parsetab.py: -------------------------------------------------------------------------------- 1 | 2 | # parsetab.py 3 | # This file is automatically generated. Do not edit. 4 | _tabversion = '3.2' 5 | 6 | _lr_method = 'LALR' 7 | 8 | _lr_signature = ')\x8e3\x01\xb59\xb96n\x82B\xc3\xa57%\xb7' 9 | 10 | _lr_action_items = {'DEDENT':([6,24,30,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,163,168,169,170,174,175,176,179,],[-46,-21,-20,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,-5,-50,174,-46,-53,-106,-107,-44,]),'NOTEQUAL':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,96,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'ENDMARKER':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,163,168,174,179,],[-3,3,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,-5,-50,-53,-44,]),'AMPER':([4,16,19,27,28,31,37,43,45,51,53,61,63,69,82,88,116,117,118,121,124,127,128,129,130,139,],[-91,-86,68,-82,-93,-95,-89,-79,-76,-94,-92,-91,-88,-87,-98,-96,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'LESS':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,99,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'NUMBER':([0,2,6,7,10,11,12,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,122,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,53,-46,-46,53,53,53,-2,53,-21,53,-20,-4,53,-46,53,-46,53,53,-46,-46,53,-42,53,53,53,53,53,53,53,53,53,-39,53,53,-41,53,53,-38,53,53,-69,53,-65,-64,-67,-68,-66,-40,-22,-10,53,53,53,53,-48,-11,-47,53,53,-51,-43,-52,-45,53,53,53,53,-5,-50,53,-49,-53,53,-44,]),'CIRCUMFLEX':([4,16,19,25,27,28,31,37,43,45,51,53,61,63,69,82,88,112,116,117,118,121,124,127,128,129,130,139,],[-91,-86,-74,72,-82,-93,-95,-89,-79,-76,-94,-92,-91,-88,-87,-98,-96,-75,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'WHILE':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,161,163,168,170,174,179,],[-3,7,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,7,-5,-50,7,-53,-44,]),'VBAR':([4,15,16,19,25,27,28,31,37,43,45,51,53,61,63,69,82,88,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,66,-86,-74,-72,-82,-93,-95,-89,-79,-76,-94,-92,-91,-88,-87,-98,-96,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'GREATER':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,98,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'PRINT':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,126,132,133,141,142,149,151,152,153,154,160,161,163,168,170,171,174,177,179,],[-3,10,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-48,-11,-47,10,10,-51,-43,-52,-45,10,10,10,-5,-50,10,-49,-53,10,-44,]),'RETURN':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,126,132,133,141,142,149,151,152,153,154,160,161,163,168,170,171,174,177,179,],[-3,11,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-48,-11,-47,11,11,-51,-43,-52,-45,11,11,11,-5,-50,11,-49,-53,11,-44,]),'MINUS':([0,2,4,6,7,10,11,12,16,18,20,24,27,28,30,31,32,33,34,36,37,38,39,41,43,44,49,51,53,54,55,56,58,61,63,66,68,69,71,72,74,75,76,79,80,82,84,85,88,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,116,117,118,119,121,122,124,125,126,132,133,139,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,12,-91,-46,-46,12,12,12,-86,-2,12,-21,-82,-93,-20,-95,-4,12,-46,12,-89,-46,12,12,92,-46,-46,-94,-92,12,-42,12,12,-91,-88,12,12,-87,12,12,12,12,12,-39,12,-98,12,-41,-96,12,12,-38,12,12,-69,12,-65,-64,-67,-68,-66,-40,-22,-10,12,-85,-83,-84,12,-99,12,-97,12,-48,-11,-47,-90,12,12,-51,-43,-52,-45,12,12,12,12,-5,-50,12,-49,-53,12,-44,]),'DEF':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,161,163,168,170,174,179,],[-3,13,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,13,-5,-50,13,-53,-44,]),'LEFTSHIFT':([4,16,27,28,31,37,43,45,51,53,61,63,69,82,88,116,117,118,121,124,127,128,139,],[-91,-86,-82,-93,-95,-89,-79,94,-94,-92,-91,-88,-87,-98,-96,-85,-83,-84,-99,-97,-80,-81,-90,]),'GREATEREQUAL':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,100,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'RPAREN':([9,15,16,19,23,25,27,28,31,35,36,37,42,43,45,46,47,51,53,54,59,61,63,69,78,81,82,83,88,106,108,111,112,115,116,117,118,120,121,124,127,128,129,130,131,134,136,138,139,145,146,147,158,159,164,165,167,173,178,],[-58,-70,-86,-74,-54,-72,-82,-93,-95,-56,82,-89,-61,-79,-76,-62,-55,-94,-92,105,-104,-91,-88,-87,-60,121,-98,-102,-96,132,-59,-71,-75,-73,-85,-83,-84,-57,-99,-97,-80,-81,-77,-78,-63,-105,144,-103,-90,-16,-12,157,-18,167,-14,-13,-17,-19,-15,]),'NEWLINE':([0,2,4,5,6,8,9,10,11,14,15,16,17,18,19,21,23,24,25,26,27,28,30,31,32,34,35,37,38,40,42,43,44,45,46,47,48,49,50,51,52,53,55,57,59,60,61,62,63,65,67,69,70,73,78,79,82,85,88,89,93,103,104,105,108,111,112,113,114,115,116,117,118,120,121,124,126,127,128,129,130,131,132,133,134,139,141,142,149,151,152,153,154,160,163,168,171,174,177,179,],[-3,18,-91,-23,-46,-46,-58,-29,-36,-46,-70,-86,-46,-2,-74,-46,-54,-21,-72,-46,-82,-93,-20,-95,-4,-46,-56,-89,-46,-46,-61,-79,-46,-76,-62,-55,-34,-46,-35,-94,104,-92,-42,-32,-104,-30,-91,-37,-88,-24,-33,-87,-26,-31,-60,-39,-98,-41,-96,-25,-38,-40,-22,-10,-59,-71,-75,-28,-27,-73,-85,-83,-84,-57,-99,-97,-48,-80,-81,-77,-78,-63,-11,-47,-105,-90,150,150,-51,-43,-52,-45,150,150,-5,-50,-49,-53,150,-44,]),'PLUS':([0,2,4,6,7,10,11,12,16,18,20,24,27,28,30,31,32,33,34,36,37,38,39,41,43,44,49,51,53,54,55,56,58,61,63,66,68,69,71,72,74,75,76,79,80,82,84,85,88,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,116,117,118,119,121,122,124,125,126,132,133,139,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,20,-91,-46,-46,20,20,20,-86,-2,20,-21,-82,-93,-20,-95,-4,20,-46,20,-89,-46,20,20,91,-46,-46,-94,-92,20,-42,20,20,-91,-88,20,20,-87,20,20,20,20,20,-39,20,-98,20,-41,-96,20,20,-38,20,20,-69,20,-65,-64,-67,-68,-66,-40,-22,-10,20,-85,-83,-84,20,-99,20,-97,20,-48,-11,-47,-90,20,20,-51,-43,-52,-45,20,20,20,20,-5,-50,20,-49,-53,20,-44,]),'COLON':([9,15,16,19,23,25,27,28,31,35,37,42,43,45,46,47,51,53,61,63,69,78,82,88,90,107,108,111,112,115,116,117,118,120,121,124,127,128,129,130,131,135,137,139,143,144,157,162,],[-58,-70,-86,-74,-54,-72,-82,-93,-95,-56,-89,-61,-79,-76,-62,-55,-94,-92,-91,-88,-87,-60,-98,-96,126,133,-59,-71,-75,-73,-85,-83,-84,-57,-99,-97,-80,-81,-77,-78,-63,-7,149,-90,154,-8,-9,171,]),'RSQB':([9,15,16,19,23,25,27,28,31,35,37,39,42,43,45,46,47,51,53,61,63,69,78,82,86,87,88,108,111,112,115,116,117,118,120,121,123,124,127,128,129,130,131,139,140,],[-58,-70,-86,-74,-54,-72,-82,-93,-95,-56,-89,88,-61,-79,-76,-62,-55,-94,-92,-91,-88,-87,-60,-98,124,-100,-96,-59,-71,-75,-73,-85,-83,-84,-57,-99,139,-97,-80,-81,-77,-78,-63,-90,-101,]),'EQEQUAL':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,102,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'$end':([1,3,],[0,-1,]),'RIGHTSHIFT':([4,16,27,28,31,37,43,45,51,53,61,63,69,82,88,116,117,118,121,124,127,128,139,],[-91,-86,-82,-93,-95,-89,-79,95,-94,-92,-91,-88,-87,-98,-96,-85,-83,-84,-99,-97,-80,-81,-90,]),'STRING':([0,2,6,7,10,11,12,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,122,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,28,-46,-46,28,28,28,-2,28,-21,28,-20,-4,28,-46,28,-46,28,28,-46,-46,28,-42,28,28,28,28,28,28,28,28,28,-39,28,28,-41,28,28,-38,28,28,-69,28,-65,-64,-67,-68,-66,-40,-22,-10,28,28,28,28,-48,-11,-47,28,28,-51,-43,-52,-45,28,28,28,28,-5,-50,28,-49,-53,28,-44,]),'FOR':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,161,163,168,170,174,179,],[-3,29,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,29,-5,-50,29,-53,-44,]),'PERCENT':([4,16,27,28,31,37,51,53,61,63,69,82,88,121,124,139,],[-91,-86,74,-93,-95,-89,-94,-92,-91,-88,-87,-98,-96,-99,-97,-90,]),'EQUAL':([4,9,15,16,19,22,23,25,27,28,31,35,37,42,43,45,46,47,51,53,61,63,69,78,82,88,108,111,112,115,116,117,118,120,121,124,127,128,129,130,131,139,145,146,167,],[-91,-58,-70,-86,-74,71,-54,-72,-82,-93,-95,-56,-89,-61,-79,-76,-62,-55,-94,-92,-91,-88,-87,-60,-98,-96,-59,-71,-75,-73,-85,-83,-84,-57,-99,-97,-80,-81,-77,-78,-63,-90,-16,156,-17,]),'COMMA':([9,15,16,19,23,25,27,28,31,35,37,42,43,45,46,47,51,53,59,61,63,69,78,82,83,87,88,108,111,112,115,116,117,118,120,121,124,127,128,129,130,131,139,145,146,158,165,167,],[-58,-70,-86,-74,-54,-72,-82,-93,-95,-56,-89,-61,-79,-76,-62,-55,-94,-92,109,-91,-88,-87,-60,-98,122,125,-96,-59,-71,-75,-73,-85,-83,-84,-57,-99,-97,-80,-81,-77,-78,-63,-90,-16,155,166,172,-17,]),'STAR':([4,16,27,28,31,37,51,53,61,63,69,82,88,121,124,139,],[-91,-86,75,-93,-95,-89,-94,-92,-91,-88,-87,-98,-96,-99,-97,-90,]),'LPAREN':([0,2,4,6,7,10,11,12,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,64,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,110,119,122,125,126,132,133,136,141,142,148,149,151,152,153,154,155,156,160,161,163,166,168,170,171,172,174,177,179,],[-3,36,54,-46,-46,36,36,36,-2,36,-21,36,-20,-4,36,-46,36,-46,36,36,-46,-46,36,-42,36,36,-6,36,36,36,36,36,36,36,-39,36,36,-41,36,36,-38,36,36,-69,36,-65,-64,-67,-68,-66,-40,-22,-10,36,136,36,36,36,-48,-11,-47,148,36,36,148,-51,-43,-52,-45,36,148,36,36,36,-5,148,-50,36,-49,148,-53,36,-44,]),'IN':([28,31,51,53,61,77,82,88,121,124,],[-93,-95,-94,-92,-91,119,-98,-96,-99,-97,]),'LESSEQUAL':([4,15,16,19,25,27,28,31,37,43,45,46,51,53,61,63,69,82,88,111,112,115,116,117,118,121,124,127,128,129,130,139,],[-91,-70,-86,-74,-72,-82,-93,-95,-89,-79,-76,101,-94,-92,-91,-88,-87,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-90,]),'LSQB':([0,2,4,6,7,10,11,12,18,20,24,28,29,30,31,32,33,34,36,37,38,39,41,44,49,51,53,54,55,56,58,61,66,68,71,72,74,75,76,79,80,82,84,85,88,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,121,122,124,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,39,-91,-46,-46,39,39,39,-2,39,-21,-93,39,-20,-95,-4,39,-46,39,84,-46,39,39,-46,-46,-94,-92,39,-42,39,39,-91,39,39,39,39,39,39,39,-39,39,-98,39,-41,-96,39,39,-38,39,39,-69,39,-65,-64,-67,-68,-66,-40,-22,-10,39,39,-99,39,-97,39,-48,-11,-47,39,39,-51,-43,-52,-45,39,39,39,39,-5,-50,39,-49,-53,39,-44,]),'ELSE':([104,151,152,174,],[-22,162,-52,-53,]),'IF':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,132,151,152,153,161,163,168,170,174,179,],[-3,41,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-11,-43,-52,-45,41,-5,-50,41,-53,-44,]),'AND':([4,9,15,16,19,25,27,28,31,37,42,43,45,46,51,53,61,63,69,78,82,88,111,112,115,116,117,118,121,124,127,128,129,130,131,139,],[-91,58,-70,-86,-74,-72,-82,-93,-95,-89,-61,-79,-76,-62,-94,-92,-91,-88,-87,-60,-98,-96,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-63,-90,]),'FNUMBER':([0,2,6,7,10,11,12,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,122,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,31,-46,-46,31,31,31,-2,31,-21,31,-20,-4,31,-46,31,-46,31,31,-46,-46,31,-42,31,31,31,31,31,31,31,31,31,-39,31,31,-41,31,31,-38,31,31,-69,31,-65,-64,-67,-68,-66,-40,-22,-10,31,31,31,31,-48,-11,-47,31,31,-51,-43,-52,-45,31,31,31,31,-5,-50,31,-49,-53,31,-44,]),'INDENT':([150,],[161,]),'NAME':([0,2,6,7,10,11,12,13,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,122,125,126,132,133,136,141,142,148,149,151,152,153,154,155,156,160,161,163,166,168,170,171,172,174,177,179,],[-3,4,-46,-46,61,61,61,64,-2,61,-21,61,-20,-4,61,-46,61,-46,61,61,-46,-46,61,-42,61,61,61,61,4,61,61,61,61,-39,61,61,-41,61,61,-38,61,61,-69,61,-65,-64,-67,-68,-66,-40,-22,-10,61,61,61,61,-48,-11,-47,145,61,61,145,-51,-43,-52,-45,61,145,61,61,4,-5,145,-50,4,-49,145,-53,61,-44,]),'SLASH':([4,16,27,28,31,37,51,53,61,63,69,82,88,121,124,139,],[-91,-86,76,-93,-95,-89,-94,-92,-91,-88,-87,-98,-96,-99,-97,-90,]),'BREAK':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,126,132,133,141,142,149,151,152,153,154,160,161,163,168,170,171,174,177,179,],[-3,48,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-48,-11,-47,48,48,-51,-43,-52,-45,48,48,48,-5,-50,48,-49,-53,48,-44,]),'CONTINUE':([0,2,6,18,24,30,32,34,38,44,49,55,79,85,93,103,104,105,126,132,133,141,142,149,151,152,153,154,160,161,163,168,170,171,174,177,179,],[-3,50,-46,-2,-21,-20,-4,-46,-46,-46,-46,-42,-39,-41,-38,-40,-22,-10,-48,-11,-47,50,50,-51,-43,-52,-45,50,50,50,-5,-50,50,-49,-53,50,-44,]),'NOT':([0,2,6,7,10,11,18,24,30,32,33,34,36,38,39,41,44,49,54,55,56,58,71,79,80,84,85,93,103,104,105,109,119,122,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,33,-46,-46,33,33,-2,-21,-20,-4,33,-46,33,-46,33,33,-46,-46,33,-42,33,33,33,-39,33,33,-41,-38,-40,-22,-10,33,33,33,33,-48,-11,-47,33,33,-51,-43,-52,-45,33,33,33,33,-5,-50,33,-49,-53,33,-44,]),'TRIPLESTRING':([0,2,6,7,10,11,12,18,20,24,29,30,32,33,34,36,38,39,41,44,49,54,55,56,58,66,68,71,72,74,75,76,79,80,84,85,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,109,119,122,125,126,132,133,141,142,149,151,152,153,154,156,160,161,163,168,170,171,174,177,179,],[-3,51,-46,-46,51,51,51,-2,51,-21,51,-20,-4,51,-46,51,-46,51,51,-46,-46,51,-42,51,51,51,51,51,51,51,51,51,-39,51,51,-41,51,51,-38,51,51,-69,51,-65,-64,-67,-68,-66,-40,-22,-10,51,51,51,51,-48,-11,-47,51,51,-51,-43,-52,-45,51,51,51,51,-5,-50,51,-49,-53,51,-44,]),'OR':([4,9,15,16,19,25,27,28,31,35,37,42,43,45,46,51,53,61,63,69,78,82,88,108,111,112,115,116,117,118,121,124,127,128,129,130,131,139,],[-91,-58,-70,-86,-74,-72,-82,-93,-95,80,-89,-61,-79,-76,-62,-94,-92,-91,-88,-87,-60,-98,-96,-59,-71,-75,-73,-85,-83,-84,-99,-97,-80,-81,-77,-78,-63,-90,]),} 11 | 12 | _lr_action = { } 13 | for _k, _v in _lr_action_items.items(): 14 | for _x,_y in zip(_v[0],_v[1]): 15 | if not _x in _lr_action: _lr_action[_x] = { } 16 | _lr_action[_x][_k] = _y 17 | del _lr_action_items 18 | 19 | _lr_goto_items = {'small_stmt':([2,141,142,154,160,161,170,177,],[5,5,5,5,5,5,5,5,]),'function_call':([2,71,161,170,],[6,113,6,6,]),'fplist':([148,166,],[159,173,]),'return_stmt':([2,141,142,154,160,161,170,177,],[8,8,8,8,8,8,8,8,]),'not_test':([2,10,11,33,36,39,41,54,56,58,71,80,84,109,119,122,125,141,142,154,156,160,161,170,177,],[9,9,9,78,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,]),'testlist_comp':([36,122,],[81,138,]),'listmaker':([39,125,],[86,140,]),'flow_stmt':([2,141,142,154,160,161,170,177,],[14,14,14,14,14,14,14,14,]),'MarkerScope':([64,],[110,]),'comp_op':([46,],[97,]),'expr_stmt':([2,141,142,154,160,161,170,177,],[40,40,40,40,40,40,40,40,]),'parameters':([110,],[135,]),'MarkerArg':([135,],[143,]),'stmts':([161,170,],[169,175,]),'continue_stmt':([2,141,142,154,160,161,170,177,],[17,17,17,17,17,17,17,17,]),'fpdef':([136,148,155,166,172,],[146,158,146,158,146,]),'shift_expr':([2,10,11,33,36,39,41,54,56,58,66,68,71,72,80,84,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,129,130,19,19,19,19,19,19,19,19,19,19,19,19,19,]),'simple_stmt':([2,141,142,154,160,161,170,177,],[30,152,152,152,152,30,30,152,]),'factor':([2,10,11,12,20,33,36,39,41,54,56,58,66,68,71,72,74,75,76,80,84,91,92,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[27,27,27,63,69,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,]),'test':([2,10,11,36,39,41,54,56,71,84,109,119,122,125,141,142,154,156,160,161,170,177,],[22,59,62,83,87,90,59,107,114,123,59,137,83,87,22,22,22,165,22,22,22,22,]),'suite':([141,142,154,160,177,],[151,153,163,168,179,]),'compound_stmt':([2,161,170,],[24,24,24,]),'and_expr':([2,10,11,33,36,39,41,54,56,58,66,68,71,72,80,84,97,109,119,122,125,141,142,154,156,160,161,170,177,],[25,25,25,25,25,25,25,25,25,25,25,112,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,]),'break_stmt':([2,141,142,154,160,161,170,177,],[26,26,26,26,26,26,26,26,]),'power':([2,10,11,12,20,33,36,39,41,54,56,58,66,68,71,72,74,75,76,80,84,91,92,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,]),'print_stmt':([2,141,142,154,160,161,170,177,],[21,21,21,21,21,21,21,21,]),'MarkerIf':([126,],[141,]),'testlist':([10,54,109,],[60,106,134,]),'stmt':([2,161,170,],[32,170,170,]),'for_stmt':([2,161,170,],[34,34,34,]),'and_test':([2,10,11,36,39,41,54,56,58,71,80,84,109,119,122,125,141,142,154,156,160,161,170,177,],[35,35,35,35,35,35,35,35,108,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,]),'atom':([2,10,11,12,20,29,33,36,39,41,54,56,58,66,68,71,72,74,75,76,80,84,91,92,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[37,37,37,37,37,77,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,]),'funcdef':([2,161,170,],[38,38,38,]),'xor_expr':([2,10,11,33,36,39,41,54,56,58,66,71,72,80,84,97,109,119,122,125,141,142,154,156,160,161,170,177,],[15,15,15,15,15,15,15,15,15,15,15,15,115,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,]),'test_expr':([2,10,11,36,39,41,54,56,71,84,109,119,122,125,141,142,154,156,160,161,170,177,],[23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,]),'comparison':([2,10,11,33,36,39,41,54,56,58,71,80,84,109,119,122,125,141,142,154,156,160,161,170,177,],[42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,]),'term':([2,10,11,33,36,39,41,54,56,58,66,68,71,72,74,75,76,80,84,91,92,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[43,43,43,43,43,43,43,43,43,43,43,43,43,43,116,117,118,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,]),'if_stmt':([2,161,170,],[44,44,44,]),'arith_expr':([2,10,11,33,36,39,41,54,56,58,66,68,71,72,80,84,91,92,94,95,97,109,119,122,125,141,142,154,156,160,161,170,177,],[45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,127,128,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,]),'file_input':([0,],[1,]),'or_test':([2,10,11,36,39,41,54,56,71,80,84,109,119,122,125,141,142,154,156,160,161,170,177,],[47,47,47,47,47,47,47,47,47,120,47,47,47,47,47,47,47,47,47,47,47,47,47,]),'MarkerWhile':([133,],[142,]),'MarkerElse':([171,],[177,]),'while_stmt':([2,161,170,],[49,49,49,]),'varargslist':([136,155,172,],[147,164,178,]),'single_stmt':([0,],[2,]),'expr':([2,10,11,33,36,39,41,54,56,58,66,71,80,84,97,109,119,122,125,141,142,154,156,160,161,170,177,],[46,46,46,46,46,46,46,46,46,46,111,46,46,46,131,46,46,46,46,46,46,46,46,46,46,46,46,]),'Marker':([6,7,8,14,17,21,26,34,38,40,44,49,170,],[55,56,57,65,67,70,73,79,85,89,93,103,176,]),'MarkerFor':([149,],[160,]),'small_stmts':([2,141,142,154,160,161,170,177,],[52,52,52,52,52,52,52,52,]),} 20 | 21 | _lr_goto = { } 22 | for _k, _v in _lr_goto_items.items(): 23 | for _x,_y in zip(_v[0],_v[1]): 24 | if not _x in _lr_goto: _lr_goto[_x] = { } 25 | _lr_goto[_x][_k] = _y 26 | del _lr_goto_items 27 | _lr_productions = [ 28 | ("S' -> file_input","S'",1,None,None,None), 29 | ('file_input -> single_stmt ENDMARKER','file_input',2,'p_file_input','bin/irgen',13), 30 | ('single_stmt -> single_stmt NEWLINE','single_stmt',2,'p_single_stmt','bin/irgen',24), 31 | ('single_stmt -> ','single_stmt',0,'p_single_stmt','bin/irgen',25), 32 | ('single_stmt -> single_stmt stmt','single_stmt',2,'p_single_stmt1','bin/irgen',33), 33 | ('funcdef -> DEF NAME MarkerScope parameters MarkerArg COLON suite','funcdef',7,'p_funcdef','bin/irgen',40), 34 | ('MarkerScope -> ','MarkerScope',0,'p_MarkerScope','bin/irgen',52), 35 | ('MarkerArg -> ','MarkerArg',0,'p_MarkerArg','bin/irgen',68), 36 | ('parameters -> LPAREN RPAREN','parameters',2,'p_parameters','bin/irgen',81), 37 | ('parameters -> LPAREN varargslist RPAREN','parameters',3,'p_parameters','bin/irgen',82), 38 | ('function_call -> NAME LPAREN RPAREN','function_call',3,'p_function_call','bin/irgen',89), 39 | ('function_call -> NAME LPAREN testlist RPAREN','function_call',4,'p_function_call','bin/irgen',90), 40 | ('varargslist -> fpdef','varargslist',1,'p_varargslist','bin/irgen',118), 41 | ('varargslist -> fpdef EQUAL test','varargslist',3,'p_varargslist','bin/irgen',119), 42 | ('varargslist -> fpdef COMMA varargslist','varargslist',3,'p_varargslistext','bin/irgen',127), 43 | ('varargslist -> fpdef EQUAL test COMMA varargslist','varargslist',5,'p_varargslistext','bin/irgen',128), 44 | ('fpdef -> NAME','fpdef',1,'p_fpdef','bin/irgen',137), 45 | ('fpdef -> LPAREN fplist RPAREN','fpdef',3,'p_fpdef','bin/irgen',138), 46 | ('fplist -> fpdef','fplist',1,'p_fplist','bin/irgen',147), 47 | ('fplist -> fpdef COMMA fplist','fplist',3,'p_fplist','bin/irgen',148), 48 | ('stmt -> simple_stmt','stmt',1,'p_stmt','bin/irgen',158), 49 | ('stmt -> compound_stmt','stmt',1,'p_stmt','bin/irgen',159), 50 | ('simple_stmt -> small_stmts NEWLINE','simple_stmt',2,'p_simple_stmt','bin/irgen',166), 51 | ('small_stmts -> small_stmt','small_stmts',1,'p_small_stmts','bin/irgen',171), 52 | ('small_stmt -> flow_stmt Marker','small_stmt',2,'p_small_stmt','bin/irgen',180), 53 | ('small_stmt -> expr_stmt Marker','small_stmt',2,'p_small_stmt','bin/irgen',181), 54 | ('small_stmt -> print_stmt Marker','small_stmt',2,'p_small_stmt','bin/irgen',182), 55 | ('expr_stmt -> test EQUAL test','expr_stmt',3,'p_expr_stmt','bin/irgen',197), 56 | ('expr_stmt -> test EQUAL function_call','expr_stmt',3,'p_expr_stmt','bin/irgen',198), 57 | ('print_stmt -> PRINT','print_stmt',1,'p_print_stmt','bin/irgen',322), 58 | ('print_stmt -> PRINT testlist','print_stmt',2,'p_print_stmt','bin/irgen',323), 59 | ('flow_stmt -> break_stmt Marker','flow_stmt',2,'p_flow_stmt','bin/irgen',344), 60 | ('flow_stmt -> return_stmt Marker','flow_stmt',2,'p_flow_stmt','bin/irgen',345), 61 | ('flow_stmt -> continue_stmt Marker','flow_stmt',2,'p_flow_stmt2','bin/irgen',352), 62 | ('break_stmt -> BREAK','break_stmt',1,'p_break_stmt','bin/irgen',359), 63 | ('continue_stmt -> CONTINUE','continue_stmt',1,'p_continue_stmt','bin/irgen',367), 64 | ('return_stmt -> RETURN','return_stmt',1,'p_return_stmt','bin/irgen',375), 65 | ('return_stmt -> RETURN test','return_stmt',2,'p_return_stmt','bin/irgen',376), 66 | ('compound_stmt -> if_stmt Marker','compound_stmt',2,'p_compound_stmt','bin/irgen',419), 67 | ('compound_stmt -> for_stmt Marker','compound_stmt',2,'p_compound_stmt','bin/irgen',420), 68 | ('compound_stmt -> while_stmt Marker','compound_stmt',2,'p_compound_stmt','bin/irgen',421), 69 | ('compound_stmt -> funcdef Marker','compound_stmt',2,'p_compound_stmt','bin/irgen',422), 70 | ('compound_stmt -> function_call Marker','compound_stmt',2,'p_compound_stmt','bin/irgen',423), 71 | ('if_stmt -> IF test COLON MarkerIf suite','if_stmt',5,'p_if_stmt','bin/irgen',433), 72 | ('if_stmt -> IF test COLON MarkerIf suite ELSE COLON MarkerElse suite','if_stmt',9,'p_if_stmt','bin/irgen',434), 73 | ('while_stmt -> WHILE Marker test COLON MarkerWhile suite','while_stmt',6,'p_while_stmt','bin/irgen',455), 74 | ('Marker -> ','Marker',0,'p_Marker','bin/irgen',469), 75 | ('MarkerWhile -> ','MarkerWhile',0,'p_MarkerWhile','bin/irgen',475), 76 | ('MarkerIf -> ','MarkerIf',0,'p_MarkerIf','bin/irgen',482), 77 | ('MarkerElse -> ','MarkerElse',0,'p_MarkerElse','bin/irgen',489), 78 | ('for_stmt -> FOR atom IN test COLON MarkerFor suite','for_stmt',7,'p_for_stmt','bin/irgen',500), 79 | ('MarkerFor -> ','MarkerFor',0,'p_MarkerFor','bin/irgen',509), 80 | ('suite -> simple_stmt','suite',1,'p_suite','bin/irgen',556), 81 | ('suite -> NEWLINE INDENT stmts DEDENT','suite',4,'p_suite','bin/irgen',557), 82 | ('test -> test_expr','test',1,'p_array','bin/irgen',566), 83 | ('test_expr -> or_test','test_expr',1,'p_test','bin/irgen',589), 84 | ('or_test -> and_test','or_test',1,'p_or_test','bin/irgen',596), 85 | ('or_test -> and_test OR or_test','or_test',3,'p_or_test','bin/irgen',597), 86 | ('and_test -> not_test','and_test',1,'p_and_test','bin/irgen',615), 87 | ('and_test -> not_test AND and_test','and_test',3,'p_and_test','bin/irgen',616), 88 | ('not_test -> NOT not_test','not_test',2,'p_not_test','bin/irgen',633), 89 | ('not_test -> comparison','not_test',1,'p_not_test','bin/irgen',634), 90 | ('comparison -> expr','comparison',1,'p_comparision','bin/irgen',651), 91 | ('comparison -> expr comp_op expr','comparison',3,'p_comparision','bin/irgen',652), 92 | ('comp_op -> LESS','comp_op',1,'p_comp_op','bin/irgen',673), 93 | ('comp_op -> GREATER','comp_op',1,'p_comp_op','bin/irgen',674), 94 | ('comp_op -> EQEQUAL','comp_op',1,'p_comp_op','bin/irgen',675), 95 | ('comp_op -> GREATEREQUAL','comp_op',1,'p_comp_op','bin/irgen',676), 96 | ('comp_op -> LESSEQUAL','comp_op',1,'p_comp_op','bin/irgen',677), 97 | ('comp_op -> NOTEQUAL','comp_op',1,'p_comp_op','bin/irgen',678), 98 | ('expr -> xor_expr','expr',1,'p_expr','bin/irgen',684), 99 | ('expr -> xor_expr VBAR expr','expr',3,'p_expr','bin/irgen',685), 100 | ('xor_expr -> and_expr','xor_expr',1,'p_xor_expr','bin/irgen',702), 101 | ('xor_expr -> and_expr CIRCUMFLEX xor_expr','xor_expr',3,'p_xor_expr','bin/irgen',703), 102 | ('and_expr -> shift_expr','and_expr',1,'p_and_expr','bin/irgen',720), 103 | ('and_expr -> shift_expr AMPER and_expr','and_expr',3,'p_and_expr','bin/irgen',721), 104 | ('shift_expr -> arith_expr','shift_expr',1,'p_shift_expr','bin/irgen',738), 105 | ('shift_expr -> arith_expr LEFTSHIFT shift_expr','shift_expr',3,'p_shift_expr','bin/irgen',739), 106 | ('shift_expr -> arith_expr RIGHTSHIFT shift_expr','shift_expr',3,'p_shift_expr','bin/irgen',740), 107 | ('arith_expr -> term','arith_expr',1,'p_arith_expr','bin/irgen',757), 108 | ('arith_expr -> term PLUS arith_expr','arith_expr',3,'p_arith_expr','bin/irgen',758), 109 | ('arith_expr -> term MINUS arith_expr','arith_expr',3,'p_arith_expr','bin/irgen',759), 110 | ('term -> factor','term',1,'p_term','bin/irgen',777), 111 | ('term -> factor STAR term','term',3,'p_term','bin/irgen',778), 112 | ('term -> factor SLASH term','term',3,'p_term','bin/irgen',779), 113 | ('term -> factor PERCENT term','term',3,'p_term','bin/irgen',780), 114 | ('factor -> power','factor',1,'p_factor','bin/irgen',797), 115 | ('factor -> PLUS factor','factor',2,'p_factor','bin/irgen',798), 116 | ('factor -> MINUS factor','factor',2,'p_factor','bin/irgen',799), 117 | ('power -> atom','power',1,'p_power','bin/irgen',812), 118 | ('power -> atom LSQB test RSQB','power',4,'p_power','bin/irgen',813), 119 | ('atom -> NAME','atom',1,'p_atom1','bin/irgen',855), 120 | ('atom -> NUMBER','atom',1,'p_atom2','bin/irgen',876), 121 | ('atom -> STRING','atom',1,'p_atom3','bin/irgen',884), 122 | ('atom -> TRIPLESTRING','atom',1,'p_atom3','bin/irgen',885), 123 | ('atom -> FNUMBER','atom',1,'p_atom4','bin/irgen',892), 124 | ('atom -> LSQB RSQB','atom',2,'p_atom5','bin/irgen',899), 125 | ('atom -> LSQB listmaker RSQB','atom',3,'p_atom5','bin/irgen',900), 126 | ('atom -> LPAREN RPAREN','atom',2,'p_atom6','bin/irgen',918), 127 | ('atom -> LPAREN testlist_comp RPAREN','atom',3,'p_atom6','bin/irgen',919), 128 | ('listmaker -> test','listmaker',1,'p_listmaker','bin/irgen',927), 129 | ('listmaker -> test COMMA listmaker','listmaker',3,'p_listmaker','bin/irgen',928), 130 | ('testlist_comp -> test','testlist_comp',1,'p_testlist_comp','bin/irgen',949), 131 | ('testlist_comp -> test COMMA testlist_comp','testlist_comp',3,'p_testlist_comp','bin/irgen',950), 132 | ('testlist -> test','testlist',1,'p_testlist','bin/irgen',960), 133 | ('testlist -> test COMMA testlist','testlist',3,'p_testlist','bin/irgen',961), 134 | ('stmts -> stmt stmts','stmts',2,'p_stmts','bin/irgen',978), 135 | ('stmts -> stmt Marker','stmts',2,'p_stmts','bin/irgen',979), 136 | ] 137 | -------------------------------------------------------------------------------- /parser and icg/bin/parsetab.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/parsetab.pyc -------------------------------------------------------------------------------- /parser and icg/bin/pcom.py: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'while' : 'WHILE', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | } 15 | 16 | rl = [] #reserved word list 17 | for k in reserved: 18 | rl.append(reserved[k]) 19 | 20 | # List of token names. This is always required 21 | tokens = ['LBRACE','RBRACE','NAME', 22 | 'LPAREN','RPAREN', 23 | 'ID','FUNC', 24 | 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 25 | 'NEWLINE','WHITE','NUMBER','INDENT', 26 | 'COMMENT',#'MULTCOM', 27 | 'ERROR','COL', 28 | 'INTEGER','FLOAT','STRING', 29 | 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 30 | 31 | literals = [ '{', '}' , '(' , ')'] 32 | 33 | t_PLUS = r'\+' 34 | t_MINUS = r'-' 35 | t_TIMES = r'\*' 36 | t_DIVIDE = r'/' 37 | t_EQUALS = r'\=' 38 | t_GRT = r'>' 39 | t_LSR = r'<' 40 | t_GRTEQ = r'>=' 41 | t_LSREQ = r'<=' 42 | t_EQ = r'==' 43 | t_COL = r':' 44 | t_INTEGER = r'\d+' 45 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 46 | t_STRING = r'\".*?\"' 47 | t_LPAREN = r'\(' 48 | t_RBRACE = r'\}' 49 | t_RPAREN = r'\)' 50 | t_LBRACE = r'\{' 51 | 52 | #def t_lbrace(t): 53 | # r'\{' 54 | # t.type = '{' # Set token type to the expected literal 55 | # return t 56 | 57 | #def t_rbrace(t): 58 | # r'\}' 59 | # t.type = '}' # Set token type to the expected literal 60 | # return t 61 | 62 | #def t_lparen(t): 63 | # r'\(' 64 | # t.type = '(' # Set token type to the expected literal 65 | # return t 66 | 67 | #def t_rparen(t): 68 | # r'\)' 69 | # t.type = ')' # Set token type to the expected literal 70 | # return t 71 | 72 | #def t_FUNC(t): 73 | # r'[d][e][f][\s][a-zA-Z_]*[a-zA-Z_0-9]*[(]*' 74 | # t.value = str(t.value)[4:len(str(t.value))-2] 75 | # return t 76 | 77 | def t_ID(t): 78 | r'[a-zA-Z_][a-zA-Z_0-9]*' 79 | t.type = reserved.get(t.value,'ID') # Check for reserved words 80 | return t 81 | 82 | def t_NUMBER(t): 83 | r'\d+' 84 | t.value = int(t.value) 85 | return t 86 | 87 | #def t_indent(t): 88 | # c = 0 89 | # for i in str(t.value): 90 | # if i in ['\s']: 91 | # c=c+1 92 | # else: 93 | # break 94 | 95 | # global indent 96 | # if c>0: 97 | # indent = [True, c] 98 | # else: 99 | # indent = [False, 0] 100 | 101 | 102 | # Define a rule so we can track line numbers 103 | def t_NEWLINE(t): 104 | r'\n+' 105 | t.lexer.lineno += len(t.value) 106 | op.write('\n') 107 | return t 108 | 109 | # Error handling rule 110 | def t_error(t): 111 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 112 | t.lexer.skip(1) 113 | 114 | def t_COMMENT(t): 115 | r'\#.*' 116 | pass 117 | # No return value. Token discarded 118 | 119 | def t_WHITE(t): 120 | r'\s+' 121 | op.write(str(t.value)) 122 | return t 123 | 124 | 125 | #def t_MULTCOM(t): 126 | # r'\""".*.\"""' 127 | # pass 128 | 129 | # Build the lexer 130 | lex.lex() 131 | 132 | 133 | # Give the lexer some input 134 | data = open('/root/Desktop/cd/temp.py','r') 135 | lex.input(data.read()) 136 | data.close() 137 | 138 | #modified code file 139 | op = open('/root/Desktop/cd/op','w') 140 | 141 | #symbol table file 142 | st = open('/root/Desktop/cd/st','w') 143 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 144 | 145 | l=[] #tokens list of lists 146 | al =[] #all tokens 147 | 148 | newl = [0 , 0] # [ lineno , lexpos ] 149 | 150 | ti = 0 #token index 151 | # Tokenize 152 | while True: 153 | tok = lex.token() 154 | 155 | if not tok: 156 | break # No more input 157 | # print(tok) 158 | al.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 159 | op.write(str(tok.value)) #modified code 160 | 161 | # if (tok.type == 'NEWLINE'): 162 | # newl = [tok.lineno , tok.lexpos] 163 | # print(newl) 164 | 165 | # if (tok.type == 'WHITE'): 166 | # if(tok.lexpos == newl[1]+1): 167 | # indent[0] = True 168 | # indent[1] = indent[1] + 1 169 | # else: 170 | 171 | # if (tok.type == 'ID'): 172 | # plno = tok.lineno-1 #present line no -1 173 | # while(plno>0 and 'WHITE' in [str(x[1]) for x in l if x[2]==plno ] ): 174 | # plno -= 1 175 | 176 | 177 | 178 | #symbol table file 179 | if(tok.type in rl or str(tok.type) in ['NUMBER','INTEGER','FLOAT','STRING']): 180 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 181 | st.write(line) 182 | 183 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 184 | ti += 1 185 | 186 | if (str(tok.type) == 'ID'): 187 | # print([x[1] for x in l]) 188 | if tok.value not in [x[1] for x in l]: 189 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 190 | st.write(line) 191 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 192 | else: 193 | ln = tok.lineno - 1 194 | while len([ x[0] for x in al if int(x[2])==ln ])>0 and [ x[0] for x in al if int(x[2])==ln ][0] == 'WHITE' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 195 | ln -= 1 196 | 197 | if len([x[0] for x in al if int(x[2]==ln)])>0 and [x[0] for x in al if int(x[2]==ln)][0] == 'DEF' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 198 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 199 | st.write(line) 200 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 201 | total = tok.lineno 202 | 203 | """x=[] 204 | print('\n\n\n') 205 | for i in range(1,total+1): 206 | temp = [] 207 | for j in al: 208 | if (int(j[2]) == i): 209 | temp.append(j) 210 | x.append(temp) 211 | 212 | for i in x: 213 | print(i) 214 | """ 215 | print('\n\n') 216 | #[print(x) for x in l] 217 | 218 | 219 | #writing to csv file 220 | myFile = open('symbol_table.csv', 'w') 221 | with myFile: 222 | writer = csv.writer(myFile) 223 | writer.writerows(l) 224 | #yacc 225 | 226 | # Precedence rules for the arithmetic operators 227 | precedence = ( 228 | ('left','PLUS','MINUS'), 229 | ('left','TIMES','DIVIDE'), 230 | ('right','UMINUS'), 231 | ) 232 | 233 | # dictionary of names (for storing variables) 234 | names = { } 235 | 236 | def p_while(p): 237 | 'statement : WHILE LPAREN expression RPAREN COL statement' 238 | if p[3] > 0 : print(p[6]) 239 | 240 | def p_check_if(p): 241 | '''statement : IF LPAREN expression RPAREN COL statement ELIF LPAREN expression RPAREN statement 242 | | IF LPAREN expression RPAREN COL statement ELSE COL statement 243 | | IF LPAREN expression RPAREN COL statement''' 244 | 245 | if p[3] > 0: print(p[6]) 246 | elif p[3]<0 and p[9]>0: print(p[9]) 247 | elif p[3]<0 : print(p[8]) 248 | 249 | def p_statement_assign(p): 250 | 'statement : NAME EQUALS expression' 251 | names[p[1]] = p[3] 252 | 253 | def p_statement_expr(p): 254 | 'statement : expression' 255 | print(p[1]) 256 | 257 | def p_expression_binop(p): 258 | '''expression : expression PLUS expression 259 | | expression MINUS expression 260 | | expression TIMES expression 261 | | expression DIVIDE expression''' 262 | if p[2] == '+' : p[0] = p[1] + p[3] 263 | elif p[2] == '-': p[0] = p[1] - p[3] 264 | elif p[2] == '*': p[0] = p[1] * p[3] 265 | elif p[2] == '/': p[0] = p[1] / p[3] 266 | 267 | def p_expression_uminus(p): 268 | 'expression : MINUS expression %prec UMINUS' 269 | p[0] = -p[2] 270 | 271 | def p_expression_group(p): 272 | 'expression : LPAREN expression RPAREN' 273 | p[0] = p[2] 274 | 275 | def p_expression_number(p): 276 | 'expression : NUMBER' 277 | p[0] = p[1] 278 | 279 | def p_expression_name(p): 280 | 'expression : NAME' 281 | try: 282 | p[0] = names[p[1]] 283 | except LookupError: 284 | print("Undefined name '%s'" % p[1]) 285 | p[0] = 0 286 | 287 | def p_error(p): 288 | print("Syntax error at '%s'" % p.value) 289 | 290 | import ply.yacc as yacc 291 | yacc.yacc() 292 | 293 | o=open('op','r') 294 | for line in o: 295 | try: 296 | yacc.parse(line) 297 | except EOFError: 298 | break 299 | 300 | 301 | -------------------------------------------------------------------------------- /parser and icg/bin/pcom.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/pcom.pyc -------------------------------------------------------------------------------- /parser and icg/bin/pyac.py: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'while' : 'WHILE', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | } 15 | 16 | rl = [] #reserved word list 17 | for k in reserved: 18 | rl.append(reserved[k]) 19 | 20 | # List of token names. This is always required 21 | tokens = ['LBRACE','RBRACE','NAME', 22 | 'LPAREN','RPAREN', 23 | 'ID','FUNC', 24 | 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 25 | 'NEWLINE','WHITE','NUMBER','INDENT', 26 | 'COMMENT',#'MULTCOM', 27 | 'ERROR','COL', 28 | 'INTEGER','FLOAT','STRING', 29 | 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 30 | 31 | literals = [ '{', '}' , '(' , ')'] 32 | 33 | t_PLUS = r'\+' 34 | t_MINUS = r'-' 35 | t_TIMES = r'\*' 36 | t_DIVIDE = r'/' 37 | t_EQUALS = r'\=' 38 | t_GRT = r'>' 39 | t_LSR = r'<' 40 | t_GRTEQ = r'>=' 41 | t_LSREQ = r'<=' 42 | t_EQ = r'==' 43 | t_COL = r':' 44 | t_INTEGER = r'\d+' 45 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 46 | t_STRING = r'\".*?\"' 47 | t_LPAREN = r'\(' 48 | t_RBRACE = r'\}' 49 | t_RPAREN = r'\)' 50 | t_LBRACE = r'\{' 51 | 52 | #def t_lbrace(t): 53 | # r'\{' 54 | # t.type = '{' # Set token type to the expected literal 55 | # return t 56 | 57 | #def t_rbrace(t): 58 | # r'\}' 59 | # t.type = '}' # Set token type to the expected literal 60 | # return t 61 | 62 | #def t_lparen(t): 63 | # r'\(' 64 | # t.type = '(' # Set token type to the expected literal 65 | # return t 66 | 67 | #def t_rparen(t): 68 | # r'\)' 69 | # t.type = ')' # Set token type to the expected literal 70 | # return t 71 | 72 | #def t_FUNC(t): 73 | # r'[d][e][f][\s][a-zA-Z_]*[a-zA-Z_0-9]*[(]*' 74 | # t.value = str(t.value)[4:len(str(t.value))-2] 75 | # return t 76 | 77 | def t_ID(t): 78 | r'[a-zA-Z_][a-zA-Z_0-9]*' 79 | t.type = reserved.get(t.value,'ID') # Check for reserved words 80 | return t 81 | 82 | def t_NUMBER(t): 83 | r'\d+' 84 | t.value = int(t.value) 85 | return t 86 | 87 | #def t_indent(t): 88 | # c = 0 89 | # for i in str(t.value): 90 | # if i in ['\s']: 91 | # c=c+1 92 | # else: 93 | # break 94 | 95 | # global indent 96 | # if c>0: 97 | # indent = [True, c] 98 | # else: 99 | # indent = [False, 0] 100 | 101 | 102 | # Define a rule so we can track line numbers 103 | def t_NEWLINE(t): 104 | r'\n+' 105 | t.lexer.lineno += len(t.value) 106 | op.write('\n') 107 | return t 108 | 109 | # Error handling rule 110 | def t_error(t): 111 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 112 | t.lexer.skip(1) 113 | 114 | def t_COMMENT(t): 115 | r'\#.*' 116 | pass 117 | # No return value. Token discarded 118 | 119 | def t_WHITE(t): 120 | r'\s+' 121 | op.write(str(t.value)) 122 | return t 123 | 124 | 125 | #def t_MULTCOM(t): 126 | # r'\""".*.\"""' 127 | # pass 128 | 129 | # Build the lexer 130 | lex.lex() 131 | 132 | 133 | # Give the lexer some input 134 | data = open('temp.py','r') 135 | lex.input(data.read()) 136 | data.close() 137 | 138 | #modified code file 139 | op = open('code.py','w') 140 | 141 | #symbol table file 142 | st = open('st','w') 143 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 144 | 145 | l=[] #tokens list of lists 146 | al =[] #all tokens 147 | 148 | newl = [0 , 0] # [ lineno , lexpos ] 149 | 150 | ti = 0 #token index 151 | # Tokenize 152 | while True: 153 | tok = lex.token() 154 | 155 | if not tok: 156 | break # No more input 157 | # print(tok) 158 | al.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 159 | op.write(str(tok.value)) #modified code 160 | 161 | # if (tok.type == 'NEWLINE'): 162 | # newl = [tok.lineno , tok.lexpos] 163 | # print(newl) 164 | 165 | # if (tok.type == 'WHITE'): 166 | # if(tok.lexpos == newl[1]+1): 167 | # indent[0] = True 168 | # indent[1] = indent[1] + 1 169 | # else: 170 | 171 | # if (tok.type == 'ID'): 172 | # plno = tok.lineno-1 #present line no -1 173 | # while(plno>0 and 'WHITE' in [str(x[1]) for x in l if x[2]==plno ] ): 174 | # plno -= 1 175 | 176 | 177 | 178 | #symbol table file 179 | if(tok.type in rl or str(tok.type) in ['NUMBER','INTEGER','FLOAT','STRING']): 180 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 181 | st.write(line) 182 | 183 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 184 | ti += 1 185 | 186 | if (str(tok.type) == 'ID'): 187 | # print([x[1] for x in l]) 188 | if tok.value not in [x[1] for x in l]: 189 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 190 | st.write(line) 191 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 192 | else: 193 | ln = tok.lineno - 1 194 | while len([ x[0] for x in al if int(x[2])==ln ])>0 and [ x[0] for x in al if int(x[2])==ln ][0] == 'WHITE' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 195 | ln -= 1 196 | 197 | if len([x[0] for x in al if int(x[2]==ln)])>0 and [x[0] for x in al if int(x[2]==ln)][0] == 'DEF' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 198 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 199 | st.write(line) 200 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 201 | total = tok.lineno 202 | 203 | """x=[] 204 | print('\n\n\n') 205 | for i in range(1,total+1): 206 | temp = [] 207 | for j in al: 208 | if (int(j[2]) == i): 209 | temp.append(j) 210 | x.append(temp) 211 | 212 | for i in x: 213 | print(i) 214 | """ 215 | print('\n\n') 216 | #[print(x) for x in l] 217 | 218 | 219 | #writing to csv file 220 | myFile = open('symbol_table.csv', 'w') 221 | with myFile: 222 | writer = csv.writer(myFile) 223 | writer.writerows(l) 224 | #yacc 225 | 226 | # Precedence rules for the arithmetic operators 227 | precedence = ( 228 | ('left','PLUS','MINUS'), 229 | ('left','TIMES','DIVIDE'), 230 | ('right','UMINUS'), 231 | ) 232 | 233 | # dictionary of names (for storing variables) 234 | names = { } 235 | 236 | def p_while(p): 237 | 'statement : WHILE LPAREN expression RPAREN COL statement' 238 | if p[3] > 0 : print(p[6]) 239 | 240 | def p_check_if(p): 241 | '''statement : IF LPAREN expression RPAREN COL statement ELIF LPAREN expression RPAREN statement 242 | | IF LPAREN expression RPAREN COL statement ELSE COL statement 243 | | IF LPAREN expression RPAREN COL statement''' 244 | 245 | if p[3] > 0: print(p[6]) 246 | elif p[3]<0 and p[9]>0: print(p[9]) 247 | elif p[3]<0 : print(p[8]) 248 | 249 | def p_statement_assign(p): 250 | 'statement : NAME EQUALS expression' 251 | names[p[1]] = p[3] 252 | 253 | def p_statement_expr(p): 254 | 'statement : expression' 255 | print(p[1]) 256 | 257 | def p_expression_binop(p): 258 | '''expression : expression PLUS expression 259 | | expression MINUS expression 260 | | expression TIMES expression 261 | | expression DIVIDE expression''' 262 | if p[2] == '+' : p[0] = p[1] + p[3] 263 | elif p[2] == '-': p[0] = p[1] - p[3] 264 | elif p[2] == '*': p[0] = p[1] * p[3] 265 | elif p[2] == '/': p[0] = p[1] / p[3] 266 | 267 | def p_expression_uminus(p): 268 | 'expression : MINUS expression %prec UMINUS' 269 | p[0] = -p[2] 270 | 271 | def p_expression_group(p): 272 | 'expression : LPAREN expression RPAREN' 273 | p[0] = p[2] 274 | 275 | def p_expression_number(p): 276 | 'expression : NUMBER' 277 | p[0] = p[1] 278 | 279 | def p_expression_name(p): 280 | 'expression : NAME' 281 | try: 282 | p[0] = names[p[1]] 283 | except LookupError: 284 | print("Undefined name '%s'" % p[1]) 285 | p[0] = 0 286 | 287 | def p_error(p): 288 | print("Syntax error at '%s'" % p.value) 289 | 290 | import ply.yacc as yacc 291 | yacc.yacc() 292 | 293 | o=open('op','r') 294 | for line in o: 295 | try: 296 | yacc.parse(line) 297 | except EOFError: 298 | break 299 | -------------------------------------------------------------------------------- /parser and icg/bin/pyac.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/pyac.pyc -------------------------------------------------------------------------------- /parser and icg/bin/st: -------------------------------------------------------------------------------- 1 | TYPE VALUE LINE_NO LEXPOS 2 | 3 | ID i 4 3 4 | NUMBER 10 4 5 5 | IF if 7 10 6 | NUMBER 10 7 15 7 | PRINT print 10 26 8 | DEF def 13 37 9 | ID fun 13 44 10 | NUMBER 20 16 59 11 | PRINT print 19 68 12 | ID j 22 79 13 | NUMBER 34 22 81 14 | NUMBER 2 22 84 15 | PRINT print 25 88 16 | -------------------------------------------------------------------------------- /parser and icg/bin/symbolTable.py: -------------------------------------------------------------------------------- 1 | import pprint 2 | 3 | symbolTable = { 4 | "program" : { 5 | "scopeName" : "program", 6 | "type" : "FUNCTION", 7 | "returnType" : "UNDEFINED", 8 | } 9 | } 10 | stackHistory = [] 11 | offsetStack = [0] 12 | functionlist = {'program':symbolTable['program']} 13 | scopeStack = [symbolTable["program"]] 14 | 15 | def lookup(identifier): 16 | global scopeStack 17 | currentScope = len(scopeStack) 18 | return lookupScopeStack(identifier, currentScope - 1) 19 | 20 | def lookupScopeStack(identifier, position): 21 | if position == -1: 22 | return None 23 | global scopeStack 24 | currentScope = scopeStack[position] 25 | # if sought identifier is not in current scope, it may be in parent 26 | if identifier in currentScope: 27 | return currentScope[identifier] 28 | else: 29 | return lookupScopeStack(identifier, position - 1) 30 | 31 | def getCurrentScope(): 32 | global scopeStack 33 | return scopeStack[len(scopeStack) - 1]["scopeName"] 34 | # ensure every scope has this key 35 | 36 | def addScope(scopeName): 37 | global scopeStack 38 | currentScope = scopeStack[len(scopeStack) - 1] 39 | currentScope[scopeName] = { 40 | "scopeName" : scopeName, 41 | "parentName" : currentScope["scopeName"], 42 | "type" : "FUNCTION", 43 | "returnType" : "UNDEFINED" 44 | } 45 | addIdentifier('True', 'BOOLEAN') 46 | addAttribute('True', scopeName, 1) 47 | addIdentifier('False', 'BOOLEAN') 48 | addAttribute('False', scopeName, 0) 49 | scopeStack.append(currentScope[scopeName]) 50 | 51 | # start new relative addressing 52 | offsetStack.append(0) 53 | functionlist[scopeName] = currentScope[scopeName] 54 | 55 | def addIdentifier(identifier, identifierType): 56 | global scopeStack 57 | currentScope = scopeStack[len(scopeStack) - 1] 58 | width = getWidthFromType(identifierType) 59 | # TODO Add other types 60 | 61 | currentOffset = offsetStack.pop() 62 | if not identifier in currentScope: 63 | currentScope[identifier] = dict() 64 | currentScope[identifier]["offset"] = currentOffset 65 | currentScope[identifier]["type"] = identifierType 66 | currentScope[identifier]["width"] = width 67 | 68 | offsetStack.append(currentOffset + width) 69 | 70 | def addAttribute(identifier, key, value): 71 | entry = lookup(identifier) 72 | entry[key] = value 73 | 74 | def getAttribute(identifier, key): 75 | entry = lookup(identifier) 76 | if key in entry: 77 | return entry[key] 78 | else: 79 | return None 80 | 81 | def getAttributeFromCurrentScope(key): 82 | global scopeStack 83 | currentScope = scopeStack[len(scopeStack) - 1] 84 | return currentScope[key] 85 | 86 | def addAttributeToCurrentScope(key, value): 87 | global scopeStack 88 | currentScope = scopeStack[len(scopeStack) - 1] 89 | currentScope[key] = value 90 | 91 | def exists(identifier): 92 | if lookup(identifier) != None: 93 | return True 94 | return False 95 | 96 | def existsInCurrentScope(identifier): 97 | global scopeStack 98 | return scopeStack[len(scopeStack)-1].get(identifier, False) != False 99 | 100 | def removeCurrentScope(): 101 | global scopeStack, stackHistory 102 | currentScope = scopeStack.pop() 103 | currentScope["width"] = offsetStack.pop() 104 | stackHistory.append(currentScope) 105 | 106 | # print scopeStack 107 | def printST(): 108 | print scopeStack 109 | 110 | def getAttributeFromFunctionList(function, key): 111 | if function in functionlist: 112 | return functionlist[function][key] 113 | else : 114 | return None 115 | 116 | def getBaseAddress(scopeName, key): 117 | return 100 118 | 119 | def getWidthFromType(identifierType): 120 | if identifierType == 'NUMBER': 121 | width = 4 122 | elif identifierType == 'STRING': 123 | width = 256 124 | elif identifierType == 'UNDEFINED': 125 | width = 0 126 | elif identifierType == 'FUNCTION': 127 | width = 4 128 | elif identifierType == 'BOOLEAN': 129 | width = 1 130 | else: 131 | width = 0 132 | return width 133 | 134 | def printSymbolTableHistory(): 135 | print "\n\n SYMBOL TABLE" 136 | print "--------------" 137 | for st in stackHistory: 138 | print "\nSCOPE: " + st['scopeName'] 139 | print "-----------------------" 140 | pprint.pprint (st) 141 | print "-----------------------\n" 142 | -------------------------------------------------------------------------------- /parser and icg/bin/symbolTable.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/symbolTable.pyc -------------------------------------------------------------------------------- /parser and icg/bin/symbol_table.csv: -------------------------------------------------------------------------------- 1 | ID,i,4,3 2 | NUMBER,10,4,5 3 | IF,if,7,10 4 | NUMBER,10,7,15 5 | PRINT,print,10,26 6 | DEF,def,13,37 7 | ID,fun,13,44 8 | NUMBER,20,16,59 9 | PRINT,print,19,68 10 | ID,j,22,79 11 | NUMBER,34,22,81 12 | NUMBER,2,22,84 13 | PRINT,print,25,88 14 | -------------------------------------------------------------------------------- /parser and icg/bin/tac.py: -------------------------------------------------------------------------------- 1 | #Code stores array of all three address codes 2 | code = {'program': []} 3 | quad = {'program': -1} 4 | nextQuad = {"program": 0} 5 | 6 | tempVarBaseName = "var" 7 | varCount = 0 8 | 9 | def getNewTempVar(): 10 | global varCount 11 | varCount += 1 12 | return tempVarBaseName + str(varCount) 13 | 14 | def incrementQuad(functionName): 15 | global quad 16 | quad[functionName] = nextQuad[functionName] 17 | nextQuad[functionName] += 1 18 | return quad[functionName] 19 | 20 | def getNextQuad(functionName): 21 | return nextQuad[functionName] 22 | 23 | def getCodeLength(functionName): 24 | return quad[functionName] 25 | 26 | def emit(functionName, regDest, regSrc1, regSrc2, op): 27 | global code 28 | incrementQuad(functionName) 29 | code[functionName].append([regDest, regSrc1, regSrc2, op]) 30 | 31 | def createNewFucntionCode(functionName): 32 | global code , quad 33 | code[functionName] = [] 34 | quad[functionName] = -1 35 | nextQuad[functionName] = 0 36 | 37 | def printCode(): 38 | for functionName in code.keys(): 39 | print functionName,":" 40 | for i in range(len(code[functionName])): 41 | print "%5d: \t" %i, code[functionName][i] 42 | 43 | def merge(list1, list2): 44 | return list1+list2 45 | 46 | def backpatch(functionName, locationList, location): 47 | global code 48 | for position in locationList: 49 | code[functionName][position][2] = location 50 | 51 | def noop(functionName, locationList): 52 | global code 53 | for position in locationList: 54 | code[functionName][position][3] = 'NOOP' -------------------------------------------------------------------------------- /parser and icg/bin/tac.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/tac.pyc -------------------------------------------------------------------------------- /parser and icg/bin/temp.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | i=10 5 | 6 | 7 | if(i<10): 8 | 9 | 10 | print(i) 11 | 12 | 13 | def fun(): 14 | 15 | 16 | i=20 17 | 18 | 19 | print(i) 20 | 21 | 22 | j=34+2 23 | 24 | 25 | print(j) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /parser and icg/bin/temp.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/temp.pyc -------------------------------------------------------------------------------- /parser and icg/bin/test2.out: -------------------------------------------------------------------------------- 1 | program : 2 | 0: ['var1', [1, 2, 3, 9, 7, 3], 'ARRAY', '='] 3 | 1: ['var2', 'var1', 'ARRAY', '='] 4 | 2: ['var4', 0, '', '='] 5 | 3: ['var5', 'var2', 'ARRAY', '='] 6 | 4: ['var6', 4, '', '='] 7 | 5: ['var7', 'var4', 'var6', '=='] 8 | 6: ['var7', 1, 16, 'COND_GOTO'] 9 | 7: ['var8', 'var4', 4, '*'] 10 | 8: ['var9', 100, 'var8', '+'] 11 | 9: ['var3', 'var9', '', 'LW'] 12 | 10: ['var10', 'var3', 'var3', '*'] 13 | 11: ['var11', 3, 2, '/'] 14 | 12: ['var12', 'var10', 'var11', '+'] 15 | 13: ['var13', 'var12', '', '='] 16 | 14: ['var4', 'var4', 1, '+'] 17 | 15: ['', '', 5, 'GOTO'] 18 | 16: ['var14', [1, 3, 6, 7], 'ARRAY', '='] 19 | 17: ['var16', 0, '', '='] 20 | 18: ['var17', [1, 3, 6, 7], 'ARRAY', '='] 21 | 19: ['var18', 4, '', '='] 22 | 20: ['var19', 'var16', 'var18', '=='] 23 | 21: ['var19', 1, 30, 'COND_GOTO'] 24 | 22: ['var20', 'var16', 4, '*'] 25 | 23: ['var21', 100, 'var20', '+'] 26 | 24: ['var15', 'var21', '', 'LW'] 27 | 25: ['var22', 'var15', 'var15', '*'] 28 | 26: ['var22', '', 'NUMBER', 'PRINT'] 29 | 27: ['"\n"', '', 'STRING', 'PRINT'] 30 | 28: ['var16', 'var16', 1, '+'] 31 | 29: ['', '', 20, 'GOTO'] 32 | 30: ['', '', -1, 'HALT'] 33 | 34 | 35 | SYMBOL TABLE 36 | -------------- 37 | 38 | SCOPE: program 39 | ----------------------- 40 | {'False': {'offset': 1, 'program': 0, 'type': 'BOOLEAN', 'width': 1}, 41 | 'True': {'offset': 0, 'program': 1, 'type': 'BOOLEAN', 'width': 1}, 42 | 'a': {'offset': 6, 'program': 'var2', 'type': 'NUMBER', 'width': 4}, 43 | 'c': {'offset': 14, 'program': 'var13', 'type': 'NUMBER', 'width': 4}, 44 | 'i': {'offset': 10, 'program': 'var3', 'type': 'NUMBER', 'width': 4}, 45 | 'numParam': 0, 46 | 'returnType': 'UNDEFINED', 47 | 'scopeName': 'program', 48 | 'type': 'FUNCTION', 49 | 'var': {'offset': 22, 'program': 'var15', 'type': 'NUMBER', 'width': 4}, 50 | 'var1': {'isArray': 'True', 51 | 'offset': 2, 52 | 'place': [1, 2, 3, 9, 7, 3], 53 | 'type': 'NUMBER', 54 | 'width': 4}, 55 | 'var14': {'isArray': 'True', 56 | 'offset': 18, 57 | 'place': [1, 3, 6, 7], 58 | 'type': 'NUMBER', 59 | 'width': 4}, 60 | 'width': 26} 61 | ----------------------- 62 | 63 | -------------------------------------------------------------------------------- /parser and icg/bin/yacc.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/bin/yacc.pyc -------------------------------------------------------------------------------- /parser and icg/makefile: -------------------------------------------------------------------------------- 1 | parser: src/* 2 | cp src/* bin/ 3 | python2 -m py_compile bin/*.py 4 | mv bin/parser.py bin/irgen 5 | chmod +x bin/irgen 6 | bin/irgen test/tf.py 2>/dev/null > /dev/null # to create parsetable once 7 | rm parser.out 8 | mv parsetab.py bin/parsetab.py 9 | 10 | clean: 11 | rm -f -rf bin/* 12 | rm -f *.dot 13 | rm -f *.png 14 | rm -f parse* 15 | rm -f dump 16 | -------------------------------------------------------------------------------- /parser and icg/op.py: -------------------------------------------------------------------------------- 1 | a=8 2 | 3 | i=10 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | def fun(): 14 | 15 | j=10 16 | 17 | print("hi HEllo") 18 | 19 | -------------------------------------------------------------------------------- /parser and icg/parsetab.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VamsiUdaykumar/MyPythonCompiler/4ebb1e131d9ff0299636a5639f51c9a8a436629a/parser and icg/parsetab.pyc -------------------------------------------------------------------------------- /parser and icg/pyac.py: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'while' : 'WHILE', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | } 15 | 16 | rl = [] #reserved word list 17 | for k in reserved: 18 | rl.append(reserved[k]) 19 | 20 | # List of token names. This is always required 21 | tokens = ['LBRACE','RBRACE','NAME', 22 | 'LPAREN','RPAREN', 23 | 'ID','FUNC', 24 | 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 25 | 'NEWLINE','WHITE','NUMBER','INDENT', 26 | 'COMMENT',#'MULTCOM', 27 | 'ERROR','COL', 28 | 'INTEGER','FLOAT','STRING', 29 | 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 30 | 31 | literals = [ '{', '}' , '(' , ')'] 32 | 33 | t_PLUS = r'\+' 34 | t_MINUS = r'-' 35 | t_TIMES = r'\*' 36 | t_DIVIDE = r'/' 37 | t_EQUALS = r'\=' 38 | t_GRT = r'>' 39 | t_LSR = r'<' 40 | t_GRTEQ = r'>=' 41 | t_LSREQ = r'<=' 42 | t_EQ = r'==' 43 | t_COL = r':' 44 | t_INTEGER = r'\d+' 45 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 46 | t_STRING = r'\".*?\"' 47 | t_LPAREN = r'\(' 48 | t_RBRACE = r'\}' 49 | t_RPAREN = r'\)' 50 | t_LBRACE = r'\{' 51 | 52 | 53 | 54 | def t_ID(t): 55 | r'[a-zA-Z_][a-zA-Z_0-9]*' 56 | t.type = reserved.get(t.value,'ID') # Check for reserved words 57 | return t 58 | 59 | def t_NUMBER(t): 60 | r'\d+' 61 | t.value = int(t.value) 62 | return t 63 | 64 | 65 | # Define a rule so we can track line numbers 66 | def t_NEWLINE(t): 67 | r'\n+' 68 | t.lexer.lineno += len(t.value) 69 | op.write('\n') 70 | return t 71 | 72 | # Error handling rule 73 | def t_error(t): 74 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 75 | t.lexer.skip(1) 76 | def t_PRINT(t): 77 | r'PRINT(\"[a-zA-Z0-9]\")' 78 | return t 79 | 80 | def t_COMMENT(t): 81 | r'\#.*' 82 | pass 83 | # No return value. Token discarded 84 | 85 | def t_WHITE(t): 86 | r'\s+' 87 | op.write(str(t.value)) 88 | return t 89 | 90 | 91 | 92 | # Build the lexer 93 | lex.lex() 94 | 95 | 96 | # Give the lexer some input 97 | data = open('test.py','r') 98 | lex.input(data.read()) 99 | data.close() 100 | 101 | #modified code file 102 | op = open('op.py','w') 103 | 104 | #symbol table file 105 | st = open('st','w') 106 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 107 | 108 | l=[] #tokens list of lists 109 | al =[] #all tokens 110 | 111 | newl = [0 , 0] # [ lineno , lexpos ] 112 | 113 | ti = 0 #token index 114 | # Tokenize 115 | while True: 116 | tok = lex.token() 117 | 118 | if not tok: 119 | break # No more input 120 | # print(tok) 121 | al.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 122 | op.write(str(tok.value)) #modified code 123 | 124 | 125 | #symbol table file 126 | if(tok.type in rl or str(tok.type) in ['NUMBER','INTEGER','FLOAT','STRING']): 127 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 128 | st.write(line) 129 | 130 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 131 | ti += 1 132 | #to Check for duplicates 133 | if (str(tok.type) == 'ID'): 134 | # print([x[1] for x in l]) 135 | if tok.value not in [x[1] for x in l]: 136 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 137 | st.write(line) 138 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 139 | else: 140 | ln = tok.lineno - 1 141 | while len([ x[0] for x in al if int(x[2])==ln ])>0 and [ x[0] for x in al if int(x[2])==ln ][0] == 'WHITE' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 142 | ln -= 1 143 | 144 | if len([x[0] for x in al if int(x[2]==ln)])>0 and [x[0] for x in al if int(x[2]==ln)][0] == 'DEF' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 145 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 146 | st.write(line) 147 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 148 | total = tok.lineno 149 | 150 | """x=[] 151 | print('\n\n\n') 152 | for i in range(1,total+1): 153 | temp = [] 154 | for j in al: 155 | if (int(j[2]) == i): 156 | temp.append(j) 157 | x.append(temp) 158 | 159 | for i in x: 160 | print(i) 161 | """ 162 | print('\n\n') 163 | #[print(x) for x in l] 164 | 165 | 166 | #writing to csv file 167 | myFile = open('symbol_table.csv', 'w') 168 | with myFile: 169 | writer = csv.writer(myFile) 170 | writer.writerows(l) 171 | #yacc 172 | 173 | # Precedence rules for the arithmetic operators 174 | precedence = ( 175 | ('left','PLUS','MINUS'), 176 | ('left','TIMES','DIVIDE'), 177 | ('right','UMINUS'), 178 | ) 179 | 180 | # dictionary of names (for storing variables) 181 | names = { } 182 | 183 | def p_while(p): 184 | 'statement : WHILE LPAREN expression RPAREN COL statement' 185 | if p[3] > 0 : print(p[6]) 186 | 187 | def p_check_if(p): 188 | '''statement : IF LPAREN expression RPAREN COL statement ELIF LPAREN expression RPAREN statement 189 | | IF LPAREN expression RPAREN COL statement ELSE COL statement 190 | | IF LPAREN expression RPAREN COL statement''' 191 | 192 | if p[3] > 0: print(p[6]) 193 | elif p[3]<0 and p[9]>0: print(p[9]) 194 | elif p[3]<0 : print(p[8]) 195 | 196 | def p_statement_assign(p): 197 | 'statement : NAME EQUALS expression' 198 | names[p[1]] = p[3] 199 | 200 | def p_statement_expr(p): 201 | 'statement : expression' 202 | print(p[1]) 203 | 204 | def p_expression_binop(p): 205 | '''expression : expression PLUS expression 206 | | expression MINUS expression 207 | | expression TIMES expression 208 | | expression DIVIDE expression''' 209 | if p[2] == '+' : p[0] = p[1] + p[3] 210 | elif p[2] == '-': p[0] = p[1] - p[3] 211 | elif p[2] == '*': p[0] = p[1] * p[3] 212 | elif p[2] == '/': p[0] = p[1] / p[3] 213 | 214 | def p_expression_uminus(p): 215 | 'expression : MINUS expression %prec UMINUS' 216 | p[0] = -p[2] 217 | 218 | def p_expression_group(p): 219 | 'expression : LPAREN expression RPAREN' 220 | p[0] = p[2] 221 | 222 | def p_expression_number(p): 223 | 'expression : NUMBER' 224 | p[0] = p[1] 225 | 226 | def p_expression_name(p): 227 | 'expression : NAME' 228 | try: 229 | p[0] = names[p[1]] 230 | except LookupError: 231 | print("Undefined name '%s'" % p[1]) 232 | p[0] = 0 233 | 234 | def p_error(p): 235 | print("Syntax error at '%s'" % p.value) 236 | 237 | import ply.yacc as yacc 238 | yacc.yacc() 239 | 240 | o=open('op.py','r') 241 | for line in o: 242 | try: 243 | yacc.parse(line) 244 | except EOFError: 245 | break 246 | -------------------------------------------------------------------------------- /parser and icg/pyac.py~: -------------------------------------------------------------------------------- 1 | import ply.lex as lex 2 | import csv 3 | 4 | reserved = { 5 | 'if' : 'IF', 6 | 'else' : 'ELSE', 7 | 'elif' : 'ELIF', 8 | 'while' : 'WHILE', 9 | 'import' : 'IMPORT', 10 | 'def' : 'DEF', 11 | 'print' : 'PRINT', 12 | 'global' : 'GLOBAL', 13 | 'lambda' : 'LAMBDA', 14 | } 15 | 16 | rl = [] #reserved word list 17 | for k in reserved: 18 | rl.append(reserved[k]) 19 | 20 | # List of token names. This is always required 21 | tokens = ['LBRACE','RBRACE','NAME', 22 | 'LPAREN','RPAREN', 23 | 'ID','FUNC', 24 | 'PLUS','MINUS','TIMES','DIVIDE','EQUALS', 25 | 'NEWLINE','WHITE','NUMBER','INDENT', 26 | 'COMMENT',#'MULTCOM', 27 | 'ERROR','COL', 28 | 'INTEGER','FLOAT','STRING', 29 | 'GRT','LSR','EQ','GRTEQ','LSREQ',] + list(reserved.values()) 30 | 31 | literals = [ '{', '}' , '(' , ')'] 32 | 33 | t_PLUS = r'\+' 34 | t_MINUS = r'-' 35 | t_TIMES = r'\*' 36 | t_DIVIDE = r'/' 37 | t_EQUALS = r'\=' 38 | t_GRT = r'>' 39 | t_LSR = r'<' 40 | t_GRTEQ = r'>=' 41 | t_LSREQ = r'<=' 42 | t_EQ = r'==' 43 | t_COL = r':' 44 | t_INTEGER = r'\d+' 45 | t_FLOAT = r'((\d*\.\d+)(E[\+-]?\d+)?|([1-9]\d*E[\+-]?\d+))' 46 | t_STRING = r'\".*?\"' 47 | t_LPAREN = r'\(' 48 | t_RBRACE = r'\}' 49 | t_RPAREN = r'\)' 50 | t_LBRACE = r'\{' 51 | 52 | #def t_lbrace(t): 53 | # r'\{' 54 | # t.type = '{' # Set token type to the expected literal 55 | # return t 56 | 57 | #def t_rbrace(t): 58 | # r'\}' 59 | # t.type = '}' # Set token type to the expected literal 60 | # return t 61 | 62 | #def t_lparen(t): 63 | # r'\(' 64 | # t.type = '(' # Set token type to the expected literal 65 | # return t 66 | 67 | #def t_rparen(t): 68 | # r'\)' 69 | # t.type = ')' # Set token type to the expected literal 70 | # return t 71 | 72 | #def t_FUNC(t): 73 | # r'[d][e][f][\s][a-zA-Z_]*[a-zA-Z_0-9]*[(]*' 74 | # t.value = str(t.value)[4:len(str(t.value))-2] 75 | # return t 76 | 77 | def t_ID(t): 78 | r'[a-zA-Z_][a-zA-Z_0-9]*' 79 | t.type = reserved.get(t.value,'ID') # Check for reserved words 80 | return t 81 | 82 | def t_NUMBER(t): 83 | r'\d+' 84 | t.value = int(t.value) 85 | return t 86 | 87 | #def t_indent(t): 88 | # c = 0 89 | # for i in str(t.value): 90 | # if i in ['\s']: 91 | # c=c+1 92 | # else: 93 | # break 94 | 95 | # global indent 96 | # if c>0: 97 | # indent = [True, c] 98 | # else: 99 | # indent = [False, 0] 100 | 101 | 102 | # Define a rule so we can track line numbers 103 | def t_NEWLINE(t): 104 | r'\n+' 105 | t.lexer.lineno += len(t.value) 106 | op.write('\n') 107 | return t 108 | 109 | # Error handling rule 110 | def t_error(t): 111 | print("Illegal character '%s'" % t.value[0],"on line no",t.lexer.lineno ) 112 | t.lexer.skip(1) 113 | def t_PRINT(t): 114 | r'PRINT(\"[a-zA-Z0-9]\")' 115 | return t 116 | 117 | def t_COMMENT(t): 118 | r'\#.*' 119 | pass 120 | # No return value. Token discarded 121 | 122 | def t_WHITE(t): 123 | r'\s+' 124 | op.write(str(t.value)) 125 | return t 126 | 127 | 128 | #def t_MULTCOM(t): 129 | # r'\""".*.\"""' 130 | # pass 131 | 132 | # Build the lexer 133 | lex.lex() 134 | 135 | 136 | # Give the lexer some input 137 | data = open('test.py','r') 138 | lex.input(data.read()) 139 | data.close() 140 | 141 | #modified code file 142 | op = open('op.py','w') 143 | 144 | #symbol table file 145 | st = open('st','w') 146 | st.write('TYPE'+'\t'+'VALUE'+'\t'+'LINE_NO'+'\t'+'LEXPOS'+'\n\n') 147 | 148 | l=[] #tokens list of lists 149 | al =[] #all tokens 150 | 151 | newl = [0 , 0] # [ lineno , lexpos ] 152 | 153 | ti = 0 #token index 154 | # Tokenize 155 | while True: 156 | tok = lex.token() 157 | 158 | if not tok: 159 | break # No more input 160 | # print(tok) 161 | al.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 162 | op.write(str(tok.value)) #modified code 163 | 164 | # if (tok.type == 'NEWLINE'): 165 | # newl = [tok.lineno , tok.lexpos] 166 | # print(newl) 167 | 168 | # if (tok.type == 'WHITE'): 169 | # if(tok.lexpos == newl[1]+1): 170 | # indent[0] = True 171 | # indent[1] = indent[1] + 1 172 | # else: 173 | 174 | # if (tok.type == 'ID'): 175 | # plno = tok.lineno-1 #present line no -1 176 | # while(plno>0 and 'WHITE' in [str(x[1]) for x in l if x[2]==plno ] ): 177 | # plno -= 1 178 | 179 | 180 | 181 | #symbol table file 182 | if(tok.type in rl or str(tok.type) in ['NUMBER','INTEGER','FLOAT','STRING']): 183 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 184 | st.write(line) 185 | 186 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 187 | ti += 1 188 | 189 | if (str(tok.type) == 'ID'): 190 | # print([x[1] for x in l]) 191 | if tok.value not in [x[1] for x in l]: 192 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 193 | st.write(line) 194 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 195 | else: 196 | ln = tok.lineno - 1 197 | while len([ x[0] for x in al if int(x[2])==ln ])>0 and [ x[0] for x in al if int(x[2])==ln ][0] == 'WHITE' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 198 | ln -= 1 199 | 200 | if len([x[0] for x in al if int(x[2]==ln)])>0 and [x[0] for x in al if int(x[2]==ln)][0] == 'DEF' and str(tok.value) not in [ x[0] for x in al if int(x[2])==ln ]: 201 | line = str(tok.type)+'\t'+str(tok.value)+'\t'+str(tok.lineno)+'\t'+str(tok.lexpos)+'\n' 202 | st.write(line) 203 | l.append([tok.type,tok.value,tok.lineno,tok.lexpos]) 204 | total = tok.lineno 205 | 206 | """x=[] 207 | print('\n\n\n') 208 | for i in range(1,total+1): 209 | temp = [] 210 | for j in al: 211 | if (int(j[2]) == i): 212 | temp.append(j) 213 | x.append(temp) 214 | 215 | for i in x: 216 | print(i) 217 | """ 218 | print('\n\n') 219 | #[print(x) for x in l] 220 | 221 | 222 | #writing to csv file 223 | myFile = open('symbol_table.csv', 'w') 224 | with myFile: 225 | writer = csv.writer(myFile) 226 | writer.writerows(l) 227 | #yacc 228 | 229 | # Precedence rules for the arithmetic operators 230 | precedence = ( 231 | ('left','PLUS','MINUS'), 232 | ('left','TIMES','DIVIDE'), 233 | ('right','UMINUS'), 234 | ) 235 | 236 | # dictionary of names (for storing variables) 237 | names = { } 238 | 239 | def p_while(p): 240 | 'statement : WHILE LPAREN expression RPAREN COL statement' 241 | if p[3] > 0 : print(p[6]) 242 | 243 | def p_check_if(p): 244 | '''statement : IF LPAREN expression RPAREN COL statement ELIF LPAREN expression RPAREN statement 245 | | IF LPAREN expression RPAREN COL statement ELSE COL statement 246 | | IF LPAREN expression RPAREN COL statement''' 247 | 248 | if p[3] > 0: print(p[6]) 249 | elif p[3]<0 and p[9]>0: print(p[9]) 250 | elif p[3]<0 : print(p[8]) 251 | 252 | def p_statement_assign(p): 253 | 'statement : NAME EQUALS expression' 254 | names[p[1]] = p[3] 255 | 256 | def p_statement_expr(p): 257 | 'statement : expression' 258 | print(p[1]) 259 | 260 | def p_expression_binop(p): 261 | '''expression : expression PLUS expression 262 | | expression MINUS expression 263 | | expression TIMES expression 264 | | expression DIVIDE expression''' 265 | if p[2] == '+' : p[0] = p[1] + p[3] 266 | elif p[2] == '-': p[0] = p[1] - p[3] 267 | elif p[2] == '*': p[0] = p[1] * p[3] 268 | elif p[2] == '/': p[0] = p[1] / p[3] 269 | 270 | def p_expression_uminus(p): 271 | 'expression : MINUS expression %prec UMINUS' 272 | p[0] = -p[2] 273 | 274 | def p_expression_group(p): 275 | 'expression : LPAREN expression RPAREN' 276 | p[0] = p[2] 277 | 278 | def p_expression_number(p): 279 | 'expression : NUMBER' 280 | p[0] = p[1] 281 | 282 | def p_expression_name(p): 283 | 'expression : NAME' 284 | try: 285 | p[0] = names[p[1]] 286 | except LookupError: 287 | print("Undefined name '%s'" % p[1]) 288 | p[0] = 0 289 | 290 | def p_error(p): 291 | print("Syntax error at '%s'" % p.value) 292 | 293 | import ply.yacc as yacc 294 | yacc.yacc() 295 | 296 | o=open('op.py','r') 297 | for line in o: 298 | try: 299 | yacc.parse(line) 300 | except EOFError: 301 | break 302 | -------------------------------------------------------------------------------- /parser and icg/readme.md: -------------------------------------------------------------------------------- 1 | CS335A: Compiler Design (Assignment 3: INTERMEDIATE CODE GENERATOR) 2 | =================================================================== 3 | 4 | * Source Language: *Python* 5 | * Target Language: *MIPS Assembly* 6 | * Implementation Language: *Python* 7 | * Authors: Abhilash Kumar, Arnab Ghosh and Saurav Kumar 8 | 9 | * Tool Used : PLY (Python Lex and Yacc) 10 | 11 | ### Three Address Code Representation 12 | _____________________________________ 13 | 14 | 1. Representation: ```regDest, regSrc1, regSrc2, op``` 15 | 16 | 2. Operators: 17 | 18 | - HALT 19 | - JUMP_RETURN 20 | - PARAM 21 | - SW 22 | - LW 23 | - = 24 | - PRINT 25 | - GOTO 26 | - RETURN 27 | - COND_GOTO 28 | - % 29 | - / 30 | - * 31 | - + 32 | - - 33 | - > 34 | - < 35 | - >= 36 | - <= 37 | - == 38 | - != 39 | - | 40 | - ^ 41 | - & 42 | - not 43 | - and 44 | - or 45 | - << 46 | - >> 47 | 48 | 49 | 50 | ### Running Instruction 51 | _______________________ 52 | 1. Run the makefile 53 | ``` 54 | make 55 | ``` 56 | 2. To run the IR Generator, pass the path of filename as argument. 57 | ``` 58 | bin/irgen test/.py 59 | ``` 60 | 61 | 3. To clean the executables and other helper files, run make clean. 62 | ``` 63 | make clean 64 | ``` 65 | 66 | ### Directory Structure 67 | _______________________ 68 | * bin: 69 | * converter.py [Python source file to convert the dump of parser into dot file: may be needed for debugging] 70 | * lex.py [Python source file from PLY for lexing] 71 | * lexer.py [Python source file to specify language lexemes] 72 | * irgen [Python dependent bytecode for parsing and semantic analysis] 73 | * parser.py [Python source file to specify grammar] 74 | * yacc.py [Python source file from PLY for parsing ] 75 | * symbolTable.py [Python source file with necessary functions related to symbol table] 76 | * tac.py [Python scource file with necessary functions related to Three Address Code Representation] 77 | * src: 78 | * converter.py [Python source file to convert the dump of parser into dot file: may be needed for debugging] 79 | * lex.py [Python source file from PLY for lexing] 80 | * lexer.py [Python source file to specify language lexemes] 81 | * irgen [Python dependent bytecode for parsing and semantic analysis] 82 | * parser.py [Python source file to specify grammar] 83 | * yacc.py [Python source file from PLY for parsing ] 84 | * symbolTable.py [Python source file with necessary functions related to symbol table] 85 | * tac.py [Python scource file with necessary functions related to Three Address Code Representation] 86 | * test: 87 | * 'filename'.py [Test files] 88 | * .gitignore 89 | * makefile [To move the source files to bin directory and compile bytecode for lexer and making it executable] 90 | * readme.md 91 | 92 | -------------------------------------------------------------------------------- /parser and icg/src/converter.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def isAction(x): 4 | first = x[:x.find(":")] 5 | if first=="Action ": 6 | return True 7 | 8 | def isReduce(x): 9 | third = x[x.find(":")+2:x.find(":")+3] 10 | if third == "R": 11 | return True 12 | else: 13 | return False 14 | 15 | def getRule(x): 16 | rule = x[x.find("[")+1:x.find("]")] 17 | return rule 18 | 19 | def left(x): 20 | return x[:x.find(" ")] 21 | 22 | def right(x): 23 | children = x[x.find("->")+3:] 24 | children = children.split() 25 | return children 26 | 27 | def getValue(x): 28 | value = x[x.find("with [")+6:x.find("] and")] 29 | value = value.replace("\\","\\\\") 30 | value = value.replace('"','\\\"') 31 | ans = [] 32 | i = 0 33 | while i < len(value): 34 | if(value[i]==','): 35 | i+=1 36 | S = "" 37 | count = 0 38 | if value[i]!="'": 39 | while i"): 75 | continue 76 | nodeId+=1 77 | stack.append((child,nodeId,item[2])) 78 | if(value[i]!="None"): 79 | print "\tnode"+str(nodeId)+" [label= \""+child+"\\n"+value[i]+"\"];" 80 | else: 81 | print "\tnode"+str(nodeId)+" [label= \""+child+"\"];" 82 | 83 | print "\tnode"+str(item[1])+" -> node"+str(nodeId)+";" 84 | i+=1 85 | else: 86 | stack.pop() 87 | pass 88 | print "}" 89 | assert(len(stack)==0) -------------------------------------------------------------------------------- /parser and icg/src/lexer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import lex 3 | from lex import TOKEN 4 | import tokenize 5 | 6 | NO_INDENT = 0 7 | MAY_INDENT = 1 8 | MUST_INDENT = 2 9 | errorList=[] 10 | tokens=[] 11 | keywordlist = [ 12 | 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 13 | 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 14 | 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 15 | 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 16 | 'with', 'yield' 17 | ] 18 | 19 | RESERVED = {} 20 | for keyword in keywordlist: 21 | name = keyword.upper() 22 | RESERVED[keyword] = name 23 | tokens.append(name) 24 | 25 | tokens = tuple(tokens) + ( 26 | 'EQEQUAL','NOTEQUAL','LESSEQUAL','LEFTSHIFT','GREATEREQUAL', 27 | 'RIGHTSHIFT','PLUSEQUAL','MINEQUAL','STAREQUAL','SLASHEQUAL','PERCENTEQUAL', 28 | 'STARSTAR','SLASHSLASH','STARSTAREQUAL','SLASHSLASHEQUAL', 29 | 'COLON','COMMA','SEMI','PLUS','MINUS','STAR','SLASH','VBAR','AMPER','LESS', 30 | 'GREATER','EQUAL','DOT','PERCENT','BACKQUOTE','CIRCUMFLEX','TILDE', 'AT', 31 | 32 | 'LPAREN', 'RPAREN', 33 | 'LBRACE', 'RBRACE', 34 | 'LSQB', 'RSQB', 35 | 'NEWLINE', 36 | 'INUMBER','FNUMBER', 37 | 'BINARYNUMBER','OCTALNUMBER','HEXADECIMALNUMBER', 38 | 'NUMBER', 39 | 'INDENT', 'DEDENT', 40 | 'TRIPLESTRING', 'STRING', 41 | 'RAWSTRING','UNICODESTRING', 42 | 'NAME','WS', 43 | 'ENDMARKER' 44 | ) 45 | 46 | # Regular expression rules for simple tokens 47 | t_EQEQUAL = r'==' 48 | t_NOTEQUAL = r'!=' 49 | t_LESSEQUAL = r'<=' 50 | t_LEFTSHIFT = r'<<' 51 | t_GREATEREQUAL = r'>=' 52 | t_RIGHTSHIFT = r'>>' 53 | t_PLUSEQUAL = r'\+=' 54 | t_MINEQUAL = r'-=' 55 | t_STAREQUAL = r'\*=' 56 | t_SLASHEQUAL = r'/=' 57 | t_PERCENTEQUAL = r'%=' 58 | t_STARSTAR = r'\*\*' 59 | t_SLASHSLASH = r'//' 60 | t_STARSTAREQUAL = r'\*\*=' 61 | t_SLASHSLASHEQUAL = r'//=' 62 | 63 | t_COLON = r':' 64 | t_COMMA = r',' 65 | t_SEMI = r';' 66 | t_PLUS = r'\+' 67 | t_MINUS = r'-' 68 | t_STAR = r'\*' 69 | t_SLASH = r'/' 70 | t_VBAR = r'\|' 71 | t_AMPER = r'&' 72 | t_LESS = r'<' 73 | t_GREATER = r'>' 74 | t_EQUAL = r'=' 75 | t_DOT = r'\.' 76 | t_PERCENT = r'%' 77 | t_BACKQUOTE = r'`' 78 | t_CIRCUMFLEX = r'\^' 79 | t_TILDE = r'~' 80 | t_AT = r'@' 81 | 82 | def newToken(newType, lineno): 83 | tok = lex.LexToken() 84 | tok.type = newType 85 | tok.value = None 86 | tok.lineno = lineno 87 | tok.lexpos = -100 88 | return tok 89 | def t_LPAREN(t): 90 | r"\(" 91 | t.lexer.parenthesisCount+=1 92 | return t 93 | def t_RPAREN(t): 94 | r"\)" 95 | t.lexer.parenthesisCount-=1 96 | return t 97 | def t_LBRACE(t): 98 | r"\{" 99 | t.lexer.parenthesisCount+=1 100 | return t 101 | def t_RBRACE(t): 102 | r"\}" 103 | t.lexer.parenthesisCount-=1 104 | return t 105 | def t_LSQB(t): 106 | r"\[" 107 | t.lexer.parenthesisCount+=1 108 | return t 109 | def t_RSQB(t): 110 | r"\]" 111 | t.lexer.parenthesisCount-=1 112 | return t 113 | 114 | #ignore comments in source code 115 | def t_comment(t): 116 | r"[ ]*\043[^\n]*" 117 | pass 118 | @TOKEN(tokenize.Imagnumber) 119 | def t_INUMBER(t): 120 | return t 121 | @TOKEN(tokenize.Floatnumber) 122 | def t_FNUMBER(t): 123 | return t 124 | # FP number above integers 125 | def t_BINARYNUMBER(t): 126 | r'0[bB]([0-1]+)' 127 | return t 128 | def t_OCTALNUMBER(t): 129 | r'0[oO]([0-7]+)' 130 | return t 131 | def t_HEXADECIMALNUMBER(t): 132 | r'0[xX]([0-9a-fA-F]+)' 133 | return t 134 | 135 | def t_NUMBER(t): 136 | r'\d+' 137 | t.value = int(t.value) 138 | return t 139 | 140 | def t_TRIPLESTRING(t): 141 | r'"{3}([\s\S]*?"{3}) | \'{3}([\s\S]*?\'{3})' 142 | return t 143 | def t_RAWSTRING(t): 144 | r'[rR](\"(\\.|[^\"\n]|(\\\n))*\") | [rR](\'(\\.|[^\'\n]|(\\\n))*\')' 145 | return t 146 | def t_UNICODESTRING(t): 147 | r'[uU](\"(\\.|[^\"\n]|(\\\n))*\") | [uU](\'(\\.|[^\'\n]|(\\\n))*\')' 148 | return t 149 | def t_STRING(t): 150 | r'(\"(\\.|[^\"\n]|(\\\n))*\") | (\'(\\.|[^\'\n]|(\\\n))*\')' 151 | return t 152 | def t_continueLine(t): 153 | r'\\(\n)+' 154 | def t_newline(t): 155 | r'\n+' 156 | t.lexer.lineno += len(t.value) 157 | t.type = "NEWLINE" 158 | if(t.lexer.parenthesisCount == 0): 159 | return t 160 | 161 | def t_NAME(t): 162 | r"[a-zA-Z_][a-zA-Z0-9_]*" 163 | t.type = RESERVED.get(t.value, "NAME") 164 | return t 165 | 166 | # Error handling rule 167 | def t_error(t): 168 | message = "\n# ERROR: Illegal character '%s' in %s at line %d" % (t.value[0], t.value, t.lineno) 169 | print message 170 | errorList.append(message) 171 | t.lexer.skip(1) 172 | 173 | # REFERENCE: https://docs.python.org/2/reference/lexical_analysis.html 174 | # WHITESPACE 175 | def t_WS(t): 176 | r" [ \t\f]+ " 177 | value = t.value 178 | value = value.rsplit("\f", 1)[-1] 179 | pos = 0 180 | while True: 181 | pos = value.find("\t") 182 | if pos == -1: 183 | break 184 | n = 8 - (pos % 8) # Convert each \t to 8 spaces (Python Documentation) 185 | value = value[:pos] + " "*n + value[pos+1:] 186 | t.value = value 187 | if t.lexer.atLineStart and t.lexer.parenthesisCount == 0: 188 | return t 189 | def INDENT(lineno): 190 | return newToken("INDENT", lineno) 191 | def DEDENT(lineno): 192 | return newToken("DEDENT",lineno) 193 | # From Python 2 documentation: 194 | # The indentation levels of consecutive lines are used to generate INDENT and DEDENT tokens, 195 | # using a stack, as follows. 196 | # Before the first line of the file is read, a single zero is pushed on the stack; 197 | # this will never be popped off again. The numbers pushed on the stack will always 198 | # be strictly increasing from bottom to top. At the beginning of each logical line, 199 | # the line's indentation level is compared to the top of the stack. If it is equal, 200 | # nothing happens. If it is larger, it is pushed on the stack, and one INDENT token 201 | # is generated. If it is smaller, it must be one of the numbers occurring on the stack; 202 | # all numbers on the stack that are larger are popped off, and for each number popped 203 | # off a DEDENT token is generated. At the end of the file, a DEDENT token is generated 204 | # for each number remaining on the stack that is larger than zero. 205 | 206 | def identifyIndenations(lexer, token_stream): 207 | lexer.atLineStart = atLineStart = True 208 | indent = NO_INDENT 209 | saw_colon = False 210 | for token in token_stream: 211 | token.atLineStart = atLineStart 212 | if token.type == "COLON": 213 | atLineStart = False 214 | indent = MAY_INDENT 215 | token.must_indent = False 216 | elif token.type == "NEWLINE": 217 | atLineStart = True 218 | if indent == MAY_INDENT: 219 | indent = MUST_INDENT # MUST INDENT 220 | token.must_indent = False 221 | elif token.type == "WS": 222 | assert token.atLineStart == True 223 | atLineStart = True 224 | token.must_indent = False 225 | else: 226 | if indent == MUST_INDENT: 227 | token.must_indent = True 228 | else: 229 | token.must_indent = False 230 | atLineStart = False 231 | indent = NO_INDENT 232 | 233 | yield token 234 | lexer.atLineStart = atLineStart 235 | 236 | def assignIndentations(token_stream): 237 | levels = [0] 238 | token = None 239 | depth = 0 240 | lastSeenWhitespace = False 241 | for token in token_stream: 242 | if token.type == "WS": 243 | assert depth == 0 244 | depth = len(token.value) 245 | lastSeenWhitespace = True 246 | continue 247 | if token.type == "NEWLINE": 248 | depth = 0 249 | if lastSeenWhitespace or token.atLineStart: 250 | continue 251 | yield token 252 | continue 253 | lastSeenWhitespace = False 254 | if token.must_indent: 255 | if not (depth > levels[-1]): 256 | # raise IndentationError("Expected an indented block") 257 | print "Indentation Error in line no "+str(token.lineno) 258 | sys.exit() 259 | levels.append(depth) 260 | yield INDENT(token.lineno) 261 | elif token.atLineStart: 262 | if depth == levels[-1]: 263 | pass 264 | elif depth > levels[-1]: 265 | print "Indentation Error in line no "+str(token.lineno) 266 | sys.exit() 267 | # raise IndentationError("IndentationError: not in new block") 268 | else: 269 | try: 270 | i = levels.index(depth) 271 | except ValueError: 272 | print "Indentation Error in line no "+str(token.lineno) 273 | sys.exit() 274 | # raise IndentationError("Inconsistent Indentation") 275 | for z in range(i+1, len(levels)): 276 | yield DEDENT(token.lineno) 277 | levels.pop() 278 | yield token 279 | if len(levels) > 1: 280 | assert token is not None 281 | for z in range(1, len(levels)): 282 | yield DEDENT(token.lineno) 283 | 284 | # This filter was in main() of previous lexer 285 | def filter(lexer, addEndMarker = True): 286 | token_stream = iter(lexer.token, None) 287 | token_stream = identifyIndenations(lexer, token_stream) 288 | token_stream = assignIndentations(token_stream) 289 | tok = None 290 | for tok in token_stream: 291 | yield tok 292 | if addEndMarker: 293 | lineno = 1 294 | if tok is not None: 295 | lineno = tok.lineno 296 | yield newToken("ENDMARKER", lineno) 297 | 298 | # To merge ply's lexer with indent feature 299 | # Built from previous main() 300 | class G1Lexer(object): 301 | def __init__(self): 302 | self.lexer = lex.lex() 303 | self.token_stream = None 304 | def input(self, data, addEndMarker=True): 305 | self.lexer.parenthesisCount = 0 306 | data+="\n" 307 | self.lexer.input(data) 308 | self.token_stream = filter(self.lexer, addEndMarker) 309 | def token(self): 310 | try: 311 | return self.token_stream.next() 312 | except StopIteration: 313 | return None 314 | 315 | # g1 = G1Lexer() 316 | # data = open('../test/test1.py').read() 317 | # g1.input(data) 318 | # t = g1.token() 319 | # while t: 320 | # print t 321 | # t = g1.token() -------------------------------------------------------------------------------- /parser and icg/src/symbolTable.py: -------------------------------------------------------------------------------- 1 | import pprint 2 | 3 | symbolTable = { 4 | "program" : { 5 | "scopeName" : "program", 6 | "type" : "FUNCTION", 7 | "returnType" : "UNDEFINED", 8 | } 9 | } 10 | stackHistory = [] 11 | offsetStack = [0] 12 | functionlist = {'program':symbolTable['program']} 13 | scopeStack = [symbolTable["program"]] 14 | 15 | def lookup(identifier): 16 | global scopeStack 17 | currentScope = len(scopeStack) 18 | return lookupScopeStack(identifier, currentScope - 1) 19 | 20 | def lookupScopeStack(identifier, position): 21 | if position == -1: 22 | return None 23 | global scopeStack 24 | currentScope = scopeStack[position] 25 | # if sought identifier is not in current scope, it may be in parent 26 | if identifier in currentScope: 27 | return currentScope[identifier] 28 | else: 29 | return lookupScopeStack(identifier, position - 1) 30 | 31 | def getCurrentScope(): 32 | global scopeStack 33 | return scopeStack[len(scopeStack) - 1]["scopeName"] 34 | # ensure every scope has this key 35 | 36 | def addScope(scopeName): 37 | global scopeStack 38 | currentScope = scopeStack[len(scopeStack) - 1] 39 | currentScope[scopeName] = { 40 | "scopeName" : scopeName, 41 | "parentName" : currentScope["scopeName"], 42 | "type" : "FUNCTION", 43 | "returnType" : "UNDEFINED" 44 | } 45 | addIdentifier('True', 'BOOLEAN') 46 | addAttribute('True', scopeName, 1) 47 | addIdentifier('False', 'BOOLEAN') 48 | addAttribute('False', scopeName, 0) 49 | scopeStack.append(currentScope[scopeName]) 50 | 51 | # start new relative addressing 52 | offsetStack.append(0) 53 | functionlist[scopeName] = currentScope[scopeName] 54 | 55 | def addIdentifier(identifier, identifierType): 56 | global scopeStack 57 | currentScope = scopeStack[len(scopeStack) - 1] 58 | width = getWidthFromType(identifierType) 59 | # TODO Add other types 60 | 61 | currentOffset = offsetStack.pop() 62 | if not identifier in currentScope: 63 | currentScope[identifier] = dict() 64 | currentScope[identifier]["offset"] = currentOffset 65 | currentScope[identifier]["type"] = identifierType 66 | currentScope[identifier]["width"] = width 67 | 68 | offsetStack.append(currentOffset + width) 69 | 70 | def addAttribute(identifier, key, value): 71 | entry = lookup(identifier) 72 | entry[key] = value 73 | 74 | def getAttribute(identifier, key): 75 | entry = lookup(identifier) 76 | if key in entry: 77 | return entry[key] 78 | else: 79 | return None 80 | 81 | def getAttributeFromCurrentScope(key): 82 | global scopeStack 83 | currentScope = scopeStack[len(scopeStack) - 1] 84 | return currentScope[key] 85 | 86 | def addAttributeToCurrentScope(key, value): 87 | global scopeStack 88 | currentScope = scopeStack[len(scopeStack) - 1] 89 | currentScope[key] = value 90 | 91 | def exists(identifier): 92 | if lookup(identifier) != None: 93 | return True 94 | return False 95 | 96 | def existsInCurrentScope(identifier): 97 | global scopeStack 98 | return scopeStack[len(scopeStack)-1].get(identifier, False) != False 99 | 100 | def removeCurrentScope(): 101 | global scopeStack, stackHistory 102 | currentScope = scopeStack.pop() 103 | currentScope["width"] = offsetStack.pop() 104 | stackHistory.append(currentScope) 105 | 106 | # print scopeStack 107 | def printST(): 108 | print scopeStack 109 | 110 | def getAttributeFromFunctionList(function, key): 111 | if function in functionlist: 112 | return functionlist[function][key] 113 | else : 114 | return None 115 | 116 | def getBaseAddress(scopeName, key): 117 | return 100 118 | 119 | def getWidthFromType(identifierType): 120 | if identifierType == 'NUMBER': 121 | width = 4 122 | elif identifierType == 'STRING': 123 | width = 256 124 | elif identifierType == 'UNDEFINED': 125 | width = 0 126 | elif identifierType == 'FUNCTION': 127 | width = 4 128 | elif identifierType == 'BOOLEAN': 129 | width = 1 130 | else: 131 | width = 0 132 | return width 133 | 134 | def printSymbolTableHistory(): 135 | print "\n\n SYMBOL TABLE" 136 | print "--------------" 137 | for st in stackHistory: 138 | print "\nSCOPE: " + st['scopeName'] 139 | print "-----------------------" 140 | pprint.pprint (st) 141 | print "-----------------------\n" 142 | -------------------------------------------------------------------------------- /parser and icg/src/tac.py: -------------------------------------------------------------------------------- 1 | #Code stores array of all three address codes 2 | code = {'program': []} 3 | quad = {'program': -1} 4 | nextQuad = {"program": 0} 5 | 6 | tempVarBaseName = "var" 7 | varCount = 0 8 | 9 | def getNewTempVar(): 10 | global varCount 11 | varCount += 1 12 | return tempVarBaseName + str(varCount) 13 | 14 | def incrementQuad(functionName): 15 | global quad 16 | quad[functionName] = nextQuad[functionName] 17 | nextQuad[functionName] += 1 18 | return quad[functionName] 19 | 20 | def getNextQuad(functionName): 21 | return nextQuad[functionName] 22 | 23 | def getCodeLength(functionName): 24 | return quad[functionName] 25 | 26 | def emit(functionName, regDest, regSrc1, regSrc2, op): 27 | global code 28 | incrementQuad(functionName) 29 | code[functionName].append([regDest, regSrc1, regSrc2, op]) 30 | 31 | def createNewFucntionCode(functionName): 32 | global code , quad 33 | code[functionName] = [] 34 | quad[functionName] = -1 35 | nextQuad[functionName] = 0 36 | 37 | def printCode(): 38 | for functionName in code.keys(): 39 | print functionName,":" 40 | for i in range(len(code[functionName])): 41 | print "%5d: \t" %i, code[functionName][i] 42 | 43 | def merge(list1, list2): 44 | return list1+list2 45 | 46 | def backpatch(functionName, locationList, location): 47 | global code 48 | for position in locationList: 49 | code[functionName][position][2] = location 50 | 51 | def noop(functionName, locationList): 52 | global code 53 | for position in locationList: 54 | code[functionName][position][3] = 'NOOP' -------------------------------------------------------------------------------- /parser and icg/st: -------------------------------------------------------------------------------- 1 | TYPE VALUE LINE_NO LEXPOS 2 | 3 | ID a 1 0 4 | NUMBER 8 1 2 5 | ID i 2 4 6 | NUMBER 10 2 6 7 | DEF def 7 68 8 | ID fun 7 72 9 | ID j 8 80 10 | NUMBER 10 8 82 11 | PRINT print 9 85 12 | STRING "hi HEllo" 9 91 13 | -------------------------------------------------------------------------------- /parser and icg/symbol_table.csv: -------------------------------------------------------------------------------- 1 | ID,a,1,0 2 | NUMBER,8,1,2 3 | ID,i,2,4 4 | NUMBER,10,2,6 5 | DEF,def,7,68 6 | ID,fun,7,72 7 | ID,j,8,80 8 | NUMBER,10,8,82 9 | PRINT,print,9,85 10 | STRING,"""hi HEllo""",9,91 11 | -------------------------------------------------------------------------------- /parser and icg/test.py: -------------------------------------------------------------------------------- 1 | a=8 2 | i=10 #Comment is to be cleaned 3 | #if i < 15 : 4 | # i++ 5 | #else : 6 | # a++ 7 | def fun(): 8 | j=10 9 | print("hi HEllo") 10 | -------------------------------------------------------------------------------- /parser and icg/test.py~: -------------------------------------------------------------------------------- 1 | a=8 2 | i=10 #Comment is to be cleaned 3 | #if i < 15 : 4 | # i++ 5 | #else : 6 | # a++ 7 | def fun(): 8 | j=10 9 | print("hi HEllo") 10 | -------------------------------------------------------------------------------- /parser and icg/test/assignment.py: -------------------------------------------------------------------------------- 1 | a = [1,2,3] 2 | a[1] = a[2] 3 | 4 | -------------------------------------------------------------------------------- /parser and icg/test/conti.py: -------------------------------------------------------------------------------- 1 | for i in [1,2,3]: 2 | if i == 2: 3 | continue 4 | else : 5 | i = 3 6 | -------------------------------------------------------------------------------- /parser and icg/test/dead.py: -------------------------------------------------------------------------------- 1 | 2 | file=open("out.txt",'r') 3 | f=open("ot.txt",'w') 4 | for i in file: 5 | line=i.split(" ")[3].split("\'")[1] 6 | f.write(str(line)+'\n') 7 | 8 | f.close() 9 | f2=open("op",'r') 10 | f3=open("final",'w') 11 | f1=open("ot.txt",'r') 12 | for i in f1: 13 | 14 | v=str(i.split(" ")[0]) 15 | print(type(v)) 16 | for line in f2: 17 | l=line.split("=")[0] 18 | print(l) 19 | if(v in l): 20 | print('dd') 21 | # else: 22 | # f3.write(line) 23 | -------------------------------------------------------------------------------- /parser and icg/test/dead.py.save: -------------------------------------------------------------------------------- 1 | file=open("out.txt",'r') 2 | f=open("ot.txt",'w') 3 | for i in file: 4 | line=i.split(" ")[3].split("\'")[1] 5 | f.write(str(line)) 6 | 7 | f.close() 8 | f2=open("op",'r') 9 | f3=open("final",'w') 10 | lst=[] 11 | f1=open("ot.txt",'r') 12 | for i in f1: 13 | v=str(i.split(" ")[0]) 14 | lst.append(v) 15 | 16 | for line in f2: 17 | l=str(line.split("=")[0]) 18 | print(l) 19 | if(v==l): 20 | print(l) 21 | # else: 22 | # f3.write(line) 23 | -------------------------------------------------------------------------------- /parser and icg/test/expr.py: -------------------------------------------------------------------------------- 1 | a = 1+7823 * 234 - 9 -------9 + 7^8 + 1<<8 2 | b = a* a + 7 * a -2 +a 3 | c = 4 4 | while a < 4 and b > 2 or c == 4: 5 | a = a + 1 6 | b = b -1 7 | c = c*c +a -b 8 | if a == b: 9 | break 10 | else : 11 | c = 10 12 | 13 | if a + b == 89: 14 | break 15 | 16 | a = b + a 17 | print a , b 18 | print c -------------------------------------------------------------------------------- /parser and icg/test/extra.py: -------------------------------------------------------------------------------- 1 | z=24 2 | v=44 3 | a = [0,1,2,3,4,5] 4 | b = a[1] + a[a[a[0]]] 5 | a[2] = a[ a[2] + 1 + b*1] 6 | print (a) 7 | -------------------------------------------------------------------------------- /parser and icg/test/for.py: -------------------------------------------------------------------------------- 1 | a = [1, 2, 3, 9, 7, 3] 2 | b=1 3 | for i in a: 4 | c = i * i + 3 / 2 5 | for var in [1,3,6,7]: 6 | print var*var 7 | -------------------------------------------------------------------------------- /parser and icg/test/func.py: -------------------------------------------------------------------------------- 1 | def sum(a,b): 2 | if a > b: 3 | mysum = a + b 4 | else: 5 | if a == b: 6 | mysum = a + b 7 | else: 8 | mysum = b + a 9 | return a + b 10 | 11 | x = sum(1,2) 12 | 13 | def noarg(): 14 | life = 42 15 | universe = 0 16 | ans = sum(life, universe) 17 | return ans 18 | 19 | val = noarg() 20 | print val -------------------------------------------------------------------------------- /parser and icg/test/if.py: -------------------------------------------------------------------------------- 1 | a = 100 2 | if a < 200: 3 | c = 2000 4 | d = 200*10 5 | isEqual = (c==d) 6 | if isEqual==True: 7 | print "Hello" 8 | else: 9 | d = 1000 10 | -------------------------------------------------------------------------------- /parser and icg/test/op.py: -------------------------------------------------------------------------------- 1 | 2 | v=45 3 | 4 | x=22 5 | 6 | i=10 7 | 8 | if(i<10): 9 | 10 | print(i) 11 | 12 | def fun(): 13 | 14 | i=20 15 | 16 | print(i) 17 | 18 | j=34+2 19 | 20 | print(j) 21 | 22 | -------------------------------------------------------------------------------- /parser and icg/test/ot.txt: -------------------------------------------------------------------------------- 1 | v 2 | z 3 | -------------------------------------------------------------------------------- /parser and icg/test/out.txt: -------------------------------------------------------------------------------- 1 | extra.py:1: unused variable 'v' (60% confidence) 2 | extra.py:2: unused variable 'z' (60% confidence) 3 | -------------------------------------------------------------------------------- /parser and icg/test/temp.py: -------------------------------------------------------------------------------- 1 | # Python program to find the factorial of a number provided by the user. 2 | 3 | # change the value for a different result 4 | num = 7 5 | 6 | # uncomment to take input from the user 7 | #num = int(input("Enter a number: ")) 8 | 9 | factorial = 1 10 | 11 | # check if the number is negative, positive or zero 12 | if num < 0: 13 | print("undefined") 14 | 15 | else: 16 | for i in range(0,1): 17 | for j in range(0,1): 18 | factorial = factorial*i 19 | print("fact=",factorial) 20 | -------------------------------------------------------------------------------- /parser and icg/test/test.py: -------------------------------------------------------------------------------- 1 | v = 45 2 | 3 | z = 455 4 | 5 | z = "kri" 6 | 7 | d=4 8 | print(d) 9 | -------------------------------------------------------------------------------- /parser and icg/test/test1.out: -------------------------------------------------------------------------------- 1 | program : 2 | 0: ['var1', 5, '', '='] ✓ var2 is index 3 | 1: ['var2', 0, '', '='] ✓ 4 | 2: ['var3', [1, 2, 3], 'ARRAY', '='] ✓ 5 | 3: ['var4', 3, '', '='] ✓ Len 6 | 4: ['var5', 'var2', 3, '=='] ✓ Contidition 7 | 5: ['var5', 1, 34, 'COND_GOTO'] ✓ Jump to outside for loop 8 | 6: ['var1', 'var3[var2]', '', '='] ✓ set var 1 9 | 7: ['var6', 5, '', '='] ✓ 10 | 8: ['var7', 'var6', 10, '<'] ✓ 11 | 9: ['var7', 0, 27, 'COND_GOTO'] ✓ 12 | 10: ['var8', 'var6', 8, '=='] ✓ 13 | 11: ['var8', 0, 15, 'COND_GOTO'] ✓ 14 | 12: ['var6', '', 'NUMBER', 'PRINT'] ✓ 15 | 13: ['"\n"', '', 'STRING', 'PRINT'] ✓ 16 | 14: ['', '', 24, 'GOTO'] ✓ 17 | 15: ['var9', 'var6', 5, '>'] ✓ 18 | 16: ['var9', 0, 22, 'COND_GOTO'] ✓ 19 | 17: ['var10', 'var6', 'var1', '*'] ✓ 20 | 18: ['var10', '', 'NUMBER', 'PRINT'] ✓ 21 | 19: ['"\n"', '', 'STRING', 'PRINT'] ✓ 22 | 20: ['', '', 27, 'GOTO'] ✓ 23 | 21: ['', '', 24, 'GOTO'] ✓ 24 | 22: ['"HI"', '', 'STRING', 'PRINT'] ✓ 25 | 23: ['"\n"', '', 'STRING', 'PRINT'] ✓ 26 | 24: ['var11', 'var6', 'var1', '+'] ✓ 27 | 25: ['var6', 'var11', '', '='] ✓ 28 | 26: ['', '', 8, 'GOTO'] ✓ 29 | 27: ['var12', 'var1', 2, '=='] ✓ 30 | 28: ['var12', 0, 31, 'COND_GOTO'] ✓ 31 | 29: ['', '', -1, 'GOTO'] X 32 | 30: ['', '', 32, 'GOTO'] ✓ 33 | 31: ['var1', 3, '', '='] ✓ 34 | 32: ['var2', 'var2', 1, '+'] ✓ 35 | 33: ['', '', 4, 'GOTO'] ✓ 36 | 34: ['"hello"', '', 'STRING', 'PRINT'] ✓ 37 | 35: ['"\n"', '', 'STRING', 'PRINT'] ✓ 38 | 36: ['', '', -1, 'HALT'] ✓ -------------------------------------------------------------------------------- /parser and icg/test/test1.py: -------------------------------------------------------------------------------- 1 | for i in [1,2,3,4]: 2 | if i == 2: 3 | continue 4 | else: 5 | i = 3 -------------------------------------------------------------------------------- /parser and icg/test/testfor.py: -------------------------------------------------------------------------------- 1 | for x in [1,2,3,4]: 2 | print x 3 | x = 4 -------------------------------------------------------------------------------- /parser and icg/test/tf.py: -------------------------------------------------------------------------------- 1 | True = 1 2 | False = 0 -------------------------------------------------------------------------------- /parser and icg/test/while.py: -------------------------------------------------------------------------------- 1 | a = 10 2 | while a > 0: 3 | a = a - 1 4 | print a*a --------------------------------------------------------------------------------