├── .DS_Store ├── doc ├── build │ ├── html │ │ ├── _static │ │ │ ├── custom.css │ │ │ ├── pygments.css │ │ │ ├── file.png │ │ │ ├── minus.png │ │ │ ├── plus.png │ │ │ ├── fonts │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ └── fontawesome-webfont.woff │ │ │ ├── documentation_options.js │ │ │ ├── js │ │ │ │ └── theme.js │ │ │ ├── css │ │ │ │ └── badge_only.css │ │ │ ├── doctools.js │ │ │ ├── underscore.js │ │ │ ├── language_data.js │ │ │ └── alabaster.css │ │ ├── objects.inv │ │ ├── _sources │ │ │ ├── Lexer.rst.txt │ │ │ ├── Helper.rst.txt │ │ │ ├── Parser.rst.txt │ │ │ ├── Analyzer.rst.txt │ │ │ ├── Grammar.rst.txt │ │ │ ├── Starter.rst.txt │ │ │ ├── modules.rst.txt │ │ │ └── index.rst.txt │ │ ├── .buildinfo │ │ ├── searchindex.js │ │ ├── search.html │ │ ├── Starter.html │ │ ├── modules.html │ │ ├── index.html │ │ ├── py-modindex.html │ │ ├── Helper.html │ │ ├── Lexer.html │ │ ├── Grammar.html │ │ ├── Parser.html │ │ └── Analyzer.html │ ├── .DS_Store │ └── doctrees │ │ ├── Lexer.doctree │ │ ├── index.doctree │ │ ├── Analyzer.doctree │ │ ├── Grammar.doctree │ │ ├── Helper.doctree │ │ ├── Parser.doctree │ │ ├── Starter.doctree │ │ ├── modules.doctree │ │ └── environment.pickle ├── .DS_Store ├── source │ ├── Helper.rst │ ├── Lexer.rst │ ├── Parser.rst │ ├── Grammar.rst │ ├── Starter.rst │ ├── Analyzer.rst │ ├── modules.rst │ ├── index.rst │ └── conf.py ├── Makefile └── make.bat ├── venv ├── bin │ ├── python │ ├── python3 │ ├── activate.csh │ ├── activate │ └── activate.fish └── pyvenv.cfg ├── output ├── goto_dict ├── Symbols.txt ├── action_dict ├── IntermediateCode.txt ├── Tokens.txt ├── GotoTable.txt └── ActionTable.txt ├── __pycache__ ├── lexer.cpython-37.pyc ├── grammar.cpython-37.pyc ├── helper.cpython-37.pyc ├── parser.cpython-37.pyc └── semantic_analyzer.cpython-37.pyc ├── grammar&code ├── SimpleCode.txt ├── SimpleGrammar.txt ├── ComplexCode.txt └── ComplexGrammar.txt ├── main.py ├── helper.py ├── README.md ├── grammar.py ├── lexer.py ├── Parser └── .idea │ └── workspace.xml └── semantic_analyzer.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/.DS_Store -------------------------------------------------------------------------------- /doc/build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /doc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/.DS_Store -------------------------------------------------------------------------------- /venv/bin/python: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/venv/bin/python -------------------------------------------------------------------------------- /output/goto_dict: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/output/goto_dict -------------------------------------------------------------------------------- /venv/bin/python3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/venv/bin/python3 -------------------------------------------------------------------------------- /doc/build/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/.DS_Store -------------------------------------------------------------------------------- /output/Symbols.txt: -------------------------------------------------------------------------------- 1 | x int 0 0x0 2 | y int 0 0x4 3 | z double 0 0x8 4 | a int 0 0x10 5 | b int 0 0x14 6 | -------------------------------------------------------------------------------- /output/action_dict: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/output/action_dict -------------------------------------------------------------------------------- /doc/build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/objects.inv -------------------------------------------------------------------------------- /doc/build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #ffffff; } -------------------------------------------------------------------------------- /__pycache__/lexer.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/__pycache__/lexer.cpython-37.pyc -------------------------------------------------------------------------------- /doc/build/doctrees/Lexer.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Lexer.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/index.doctree -------------------------------------------------------------------------------- /doc/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/file.png -------------------------------------------------------------------------------- /doc/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/minus.png -------------------------------------------------------------------------------- /doc/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/plus.png -------------------------------------------------------------------------------- /__pycache__/grammar.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/__pycache__/grammar.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/helper.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/__pycache__/helper.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/parser.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/__pycache__/parser.cpython-37.pyc -------------------------------------------------------------------------------- /doc/build/doctrees/Analyzer.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Analyzer.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/Grammar.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Grammar.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/Helper.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Helper.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/Parser.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Parser.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/Starter.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/Starter.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/modules.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/modules.doctree -------------------------------------------------------------------------------- /doc/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /venv/pyvenv.cfg: -------------------------------------------------------------------------------- 1 | home = /Library/Frameworks/Python.framework/Versions/3.7/bin 2 | include-system-site-packages = true 3 | version = 3.7.0 4 | -------------------------------------------------------------------------------- /__pycache__/semantic_analyzer.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/__pycache__/semantic_analyzer.cpython-37.pyc -------------------------------------------------------------------------------- /doc/source/Helper.rst: -------------------------------------------------------------------------------- 1 | Helper module 2 | ============= 3 | 4 | .. automodule:: Helper 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/source/Lexer.rst: -------------------------------------------------------------------------------- 1 | Lexer module 2 | ============ 3 | 4 | .. automodule:: Lexer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/source/Parser.rst: -------------------------------------------------------------------------------- 1 | Parser module 2 | ============= 3 | 4 | .. automodule:: Parser 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/source/Grammar.rst: -------------------------------------------------------------------------------- 1 | Grammar module 2 | ============== 3 | 4 | .. automodule:: Grammar 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/source/Starter.rst: -------------------------------------------------------------------------------- 1 | Starter module 2 | ============== 3 | 4 | .. automodule:: Starter 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /doc/build/html/_static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /doc/source/Analyzer.rst: -------------------------------------------------------------------------------- 1 | Analyzer module 2 | =============== 3 | 4 | .. automodule:: Analyzer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_sources/Lexer.rst.txt: -------------------------------------------------------------------------------- 1 | Lexer module 2 | ============ 3 | 4 | .. automodule:: Lexer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Charles2Alvin/HIT-Compliers/HEAD/doc/build/html/_static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /doc/build/html/_sources/Helper.rst.txt: -------------------------------------------------------------------------------- 1 | Helper module 2 | ============= 3 | 4 | .. automodule:: Helper 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_sources/Parser.rst.txt: -------------------------------------------------------------------------------- 1 | Parser module 2 | ============= 3 | 4 | .. automodule:: Parser 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_sources/Analyzer.rst.txt: -------------------------------------------------------------------------------- 1 | Analyzer module 2 | =============== 3 | 4 | .. automodule:: Analyzer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_sources/Grammar.rst.txt: -------------------------------------------------------------------------------- 1 | Grammar module 2 | ============== 3 | 4 | .. automodule:: Grammar 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /doc/build/html/_sources/Starter.rst.txt: -------------------------------------------------------------------------------- 1 | Starter module 2 | ============== 3 | 4 | .. automodule:: Starter 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /grammar&code/SimpleCode.txt: -------------------------------------------------------------------------------- 1 | int x 2 | int y 3 | double z 4 | int a 5 | int b 6 | x = y + z 7 | while ( a < b ) 8 | if ( c < d ) 9 | x = y + z 10 | else 11 | y = x + x 12 | -------------------------------------------------------------------------------- /doc/source/modules.rst: -------------------------------------------------------------------------------- 1 | S-Complier 2 | ========== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | Analyzer 8 | Grammar 9 | Helper 10 | Lexer 11 | Parser 12 | Starter 13 | -------------------------------------------------------------------------------- /doc/build/html/_sources/modules.rst.txt: -------------------------------------------------------------------------------- 1 | S-Complier 2 | ========== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | Analyzer 8 | Grammar 9 | Helper 10 | Lexer 11 | Parser 12 | Starter 13 | -------------------------------------------------------------------------------- /output/IntermediateCode.txt: -------------------------------------------------------------------------------- 1 | (+, y, z, t1) 2 | (=, t1, -, x) 3 | (j<, a, b, 5) 4 | (j, -, -, 13) 5 | (j<, c, d, 7) 6 | (j, -, -, 9) 7 | (+, y, z, t2) 8 | (=, t2, -, x) 9 | (j, -, -, 12) 10 | (+, x, x, t3) 11 | (=, t3, -, y) 12 | (j, -, -, 3) 13 | -------------------------------------------------------------------------------- /doc/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 1a40aecea9c778fb18e54418ed935dd7 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /doc/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt', 9 | NAVIGATION_WITH_KEYS: false 10 | }; -------------------------------------------------------------------------------- /grammar&code/SimpleGrammar.txt: -------------------------------------------------------------------------------- 1 | P -> D S 2 | # 声明语句 3 | D -> D D 4 | D -> type IDN 5 | type -> int 6 | type -> double 7 | # 表达式语句 8 | S -> S S 9 | S -> IDN = E 10 | E -> E + T 11 | E -> T 12 | T -> T * F 13 | T -> F 14 | F -> ( E ) 15 | F -> digit 16 | F -> IDN 17 | # 逻辑表达式 18 | C -> true 19 | C -> false 20 | C -> E relop E 21 | relop -> > 22 | relop -> < 23 | # 分支结构 24 | S -> if ( C ) S else S 25 | # 循环结构 26 | S -> while ( C ) S 27 | 28 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Compliers documentation master file, created by 2 | sphinx-quickstart on Mon Apr 29 22:18:36 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Compliers's documentation! 7 | ===================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | modules 14 | 15 | 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | -------------------------------------------------------------------------------- /doc/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. Compliers documentation master file, created by 2 | sphinx-quickstart on Mon Apr 29 22:18:36 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Compliers's documentation! 7 | ===================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | modules 14 | 15 | 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = source 8 | BUILDDIR = build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /output/Tokens.txt: -------------------------------------------------------------------------------- 1 | int 1 2 | x 1 3 | int 2 4 | y 2 5 | double 3 6 | z 3 7 | int 4 8 | a 4 9 | int 5 10 | b 5 11 | x 6 12 | = 6 13 | y 6 14 | + 6 15 | z 6 16 | while 7 17 | ( 7 18 | a 7 19 | < 7 20 | b 7 21 | ) 7 22 | if 8 23 | ( 8 24 | c 8 25 | < 8 26 | d 8 27 | ) 8 28 | x 9 29 | = 9 30 | y 9 31 | + 9 32 | z 9 33 | else 10 34 | y 11 35 | = 11 36 | x 11 37 | + 11 38 | x 11 39 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from parser import * 2 | from grammar import * 3 | from lexer import * 4 | if __name__ == "__main__": 5 | lexer = Lexer() 6 | lexer.configure('./grammar&code/SimpleCode.txt') 7 | 8 | g = Grammar() 9 | g.configure('./grammar&code/SimpleGrammar.txt') 10 | 11 | print("\nBuilding automata...") 12 | t1 = time.time() 13 | p = Parser() 14 | p.configure(g) 15 | print("Analysis table completed in", '{:.4f}s'.format(time.time() - t1)) 16 | 17 | print("\nParsing...") 18 | t2 = time.time() 19 | # p.parse(lexer.output) 20 | p.update_parse(lexer.output) 21 | print("Syntactic analysis completed in", '{:.4f}s'.format(time.time() - t2)) 22 | 23 | print("\nAnalyzing...") 24 | t3 = time.time() 25 | analyzer = Analyzer(p.root, p.Dlist, p.Slist) 26 | analyzer.configure() -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /grammar&code/ComplexCode.txt: -------------------------------------------------------------------------------- 1 | class QuickSort { 2 | private int [] array; 3 | public int sort( int [] array, int low, int high ) { 4 | if ( low < high ) { 5 | int index = partition(array, low, high); 6 | sort(array, low, index); 7 | sort(array, index + 1, high); 8 | } 9 | } 10 | public void partition(int [] array, int low, int high) { 11 | int index = low; 12 | swap(index, low); 13 | int pivot = array[low]; 14 | while (low < high && high >= pivot) { 15 | while ( low < high) { 16 | high--; 17 | } 18 | array[low] = array[high]; 19 | while (low < high && array[low] < pivot) { 20 | high++; 21 | } 22 | array[high] = array[low]; 23 | } 24 | array[low] = pivot; 25 | return low; 26 | } 27 | public void swap(int i, int j) { 28 | int temp = array[i]; 29 | array[i] = array[j]; 30 | array[j] = temp; 31 | } 32 | public void main(int y) { 33 | int [] array = {3, 2, 4, 1, 6, 9, 14, 2, 5, 7, 0}; 34 | QuickSort q = new QuickSort(array); 35 | q @ sort(array, 0, length - 1); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /venv/bin/activate.csh: -------------------------------------------------------------------------------- 1 | # This file must be used with "source bin/activate.csh" *from csh*. 2 | # You cannot run it directly. 3 | # Created by Davide Di Blasi . 4 | # Ported to Python 3.3 venv by Andrew Svetlov 5 | 6 | alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' 7 | 8 | # Unset irrelevant variables. 9 | deactivate nondestructive 10 | 11 | setenv VIRTUAL_ENV "/Users/mohaitao/Library/Mobile Documents/com~apple~CloudDocs/2019 Spring/Compliers/expr2/Code/venv" 12 | 13 | set _OLD_VIRTUAL_PATH="$PATH" 14 | setenv PATH "$VIRTUAL_ENV/bin:$PATH" 15 | 16 | 17 | set _OLD_VIRTUAL_PROMPT="$prompt" 18 | 19 | if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then 20 | if ("venv" != "") then 21 | set env_name = "venv" 22 | else 23 | if (`basename "VIRTUAL_ENV"` == "__") then 24 | # special case for Aspen magic directories 25 | # see http://www.zetadev.com/software/aspen/ 26 | set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` 27 | else 28 | set env_name = `basename "$VIRTUAL_ENV"` 29 | endif 30 | endif 31 | set prompt = "[$env_name] $prompt" 32 | unset env_name 33 | endif 34 | 35 | alias pydoc python -m pydoc 36 | 37 | rehash 38 | -------------------------------------------------------------------------------- /helper.py: -------------------------------------------------------------------------------- 1 | class Entry: 2 | def __init__(self, state, symbol, action=None, **content): 3 | self.state = state 4 | self.symbol = symbol 5 | self.action = action 6 | self.content = content 7 | 8 | def __eq__(self, other): 9 | if isinstance(other, self.__class__): 10 | return self.state == other.state and self.symbol == other.symbol 11 | else: 12 | return False 13 | 14 | 15 | class DictEntry(object): 16 | def __init__(self, action=None, **content): 17 | self.action = action 18 | self.content = content 19 | 20 | class Production: 21 | def __init__(self, left, right): 22 | self.left = left 23 | self.right = right 24 | self.index = 0 # 产生式的编号 25 | 26 | def __eq__(self, other): 27 | if isinstance(other, self.__class__): 28 | return self.left == other.left and self.right == other.right 29 | else: 30 | return False 31 | 32 | 33 | class Item: 34 | def __init__(self, left, right, lookahead): 35 | self.left = left 36 | self.right = right 37 | self.lookahead = lookahead 38 | 39 | def __eq__(self, other): 40 | if isinstance(other, self.__class__): 41 | return self.left == other.left and self.right == other.right and self.lookahead == other.lookahead 42 | else: 43 | return False 44 | 45 | def __str__(self): 46 | return self.left + " " + str(self.right) + " " + self.lookahead 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /doc/build/html/_static/js/theme.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | // Shift nav in mobile when clicking the menu. 3 | $(document).on('click', "[data-toggle='wy-nav-top']", function() { 4 | $("[data-toggle='wy-nav-shift']").toggleClass("shift"); 5 | $("[data-toggle='rst-versions']").toggleClass("shift"); 6 | }); 7 | // Close menu when you click a link. 8 | $(document).on('click', ".wy-menu-vertical .current ul li a", function() { 9 | $("[data-toggle='wy-nav-shift']").removeClass("shift"); 10 | $("[data-toggle='rst-versions']").toggleClass("shift"); 11 | }); 12 | $(document).on('click', "[data-toggle='rst-current-version']", function() { 13 | $("[data-toggle='rst-versions']").toggleClass("shift-up"); 14 | }); 15 | // Make tables responsive 16 | $("table.docutils:not(.field-list)").wrap("
"); 17 | }); 18 | 19 | window.SphinxRtdTheme = (function (jquery) { 20 | var stickyNav = (function () { 21 | var navBar, 22 | win, 23 | stickyNavCssClass = 'stickynav', 24 | applyStickNav = function () { 25 | if (navBar.height() <= win.height()) { 26 | navBar.addClass(stickyNavCssClass); 27 | } else { 28 | navBar.removeClass(stickyNavCssClass); 29 | } 30 | }, 31 | enable = function () { 32 | applyStickNav(); 33 | win.on('resize', applyStickNav); 34 | }, 35 | init = function () { 36 | navBar = jquery('nav.wy-nav-side:first'); 37 | win = jquery(window); 38 | }; 39 | jquery(init); 40 | return { 41 | enable : enable 42 | }; 43 | }()); 44 | return { 45 | StickyNav : stickyNav 46 | }; 47 | }($)); 48 | -------------------------------------------------------------------------------- /output/GotoTable.txt: -------------------------------------------------------------------------------- 1 | 0 P {'goto_state': 1} 2 | 0 D {'goto_state': 2} 3 | 0 type {'goto_state': 3} 4 | 2 D {'goto_state': 6} 5 | 2 type {'goto_state': 3} 6 | 2 S {'goto_state': 7} 7 | 6 D {'goto_state': 6} 8 | 6 type {'goto_state': 3} 9 | 7 S {'goto_state': 12} 10 | 12 S {'goto_state': 12} 11 | 13 E {'goto_state': 16} 12 | 13 T {'goto_state': 17} 13 | 13 F {'goto_state': 18} 14 | 14 E {'goto_state': 22} 15 | 14 T {'goto_state': 23} 16 | 14 F {'goto_state': 24} 17 | 14 C {'goto_state': 25} 18 | 15 E {'goto_state': 22} 19 | 15 T {'goto_state': 23} 20 | 15 F {'goto_state': 24} 21 | 15 C {'goto_state': 31} 22 | 20 E {'goto_state': 34} 23 | 20 T {'goto_state': 35} 24 | 20 F {'goto_state': 36} 25 | 22 relop {'goto_state': 40} 26 | 27 E {'goto_state': 46} 27 | 27 T {'goto_state': 35} 28 | 27 F {'goto_state': 36} 29 | 32 T {'goto_state': 48} 30 | 32 F {'goto_state': 18} 31 | 33 F {'goto_state': 49} 32 | 38 E {'goto_state': 53} 33 | 38 T {'goto_state': 35} 34 | 38 F {'goto_state': 36} 35 | 40 E {'goto_state': 54} 36 | 40 T {'goto_state': 35} 37 | 40 F {'goto_state': 36} 38 | 41 T {'goto_state': 55} 39 | 41 F {'goto_state': 24} 40 | 44 F {'goto_state': 56} 41 | 45 S {'goto_state': 57} 42 | 47 S {'goto_state': 62} 43 | 50 T {'goto_state': 63} 44 | 50 F {'goto_state': 36} 45 | 52 F {'goto_state': 64} 46 | 57 S {'goto_state': 66} 47 | 62 S {'goto_state': 12} 48 | 66 S {'goto_state': 66} 49 | 67 S {'goto_state': 71} 50 | 68 E {'goto_state': 72} 51 | 68 T {'goto_state': 73} 52 | 68 F {'goto_state': 74} 53 | 69 E {'goto_state': 22} 54 | 69 T {'goto_state': 23} 55 | 69 F {'goto_state': 24} 56 | 69 C {'goto_state': 78} 57 | 70 E {'goto_state': 22} 58 | 70 T {'goto_state': 23} 59 | 70 F {'goto_state': 24} 60 | 70 C {'goto_state': 79} 61 | 71 S {'goto_state': 12} 62 | 76 E {'goto_state': 82} 63 | 76 T {'goto_state': 35} 64 | 76 F {'goto_state': 36} 65 | 80 T {'goto_state': 85} 66 | 80 F {'goto_state': 74} 67 | 81 F {'goto_state': 86} 68 | 83 S {'goto_state': 88} 69 | 84 S {'goto_state': 89} 70 | 88 S {'goto_state': 66} 71 | 89 S {'goto_state': 66} 72 | 90 S {'goto_state': 91} 73 | 91 S {'goto_state': 66} 74 | -------------------------------------------------------------------------------- /grammar&code/ComplexGrammar.txt: -------------------------------------------------------------------------------- 1 | start -> classes 2 | # 类 3 | classes -> classes classes 4 | classes -> class IDN { method } 5 | classes -> class IDN { field method } 6 | # 域和方法 7 | field -> D 8 | field -> access D 9 | method -> method method 10 | method -> type IDN ( ) { P } 11 | method -> type IDN ( args ) { P } 12 | method -> access type IDN ( ) { P } 13 | method -> access type IDN ( args ) { P } 14 | # 参数列表 15 | args -> args , arg 16 | args -> arg 17 | arg -> T IDN 18 | # 访问控制符 19 | access -> public 20 | access -> private 21 | access -> protected 22 | # 程序主体 23 | P -> P P 24 | P -> D 25 | P -> S 26 | S -> S S 27 | # 声明语句 28 | D -> D D 29 | D -> D S 30 | D -> T IDN ; 31 | D -> T M ; 32 | M -> m 33 | M -> M , m 34 | m -> IDN = E ; 35 | D -> T IDN = E ; 36 | D -> T IDN = { A } ; 37 | T -> type 38 | T -> type [ ] 39 | A -> E 40 | A -> A , E 41 | # 数据类型 42 | type -> int 43 | type -> float 44 | type -> long 45 | type -> double 46 | type -> char 47 | type -> void 48 | # 赋值语句 49 | S -> IDN = E ; 50 | S -> IDN op ; 51 | S -> op IDN ; 52 | op -> ++ 53 | op -> -- 54 | S -> L = E ; 55 | S -> R ; 56 | # 返回值 57 | R -> return E 58 | R -> return 59 | # 函数调用 60 | S -> call ; 61 | call -> IDN ( ) 62 | call -> IDN ( param ) 63 | param -> E 64 | param -> param , E 65 | # 类的创建 66 | S -> IDN IDN = new IDN ( ) ; 67 | S -> IDN IDN = new IDN ( param ) ; 68 | # 调用方法 69 | S -> IDN func ; 70 | func -> F 71 | func -> func F 72 | F -> @ IDN ( ) 73 | F -> @ IDN ( param ) 74 | # 运算表达式 75 | E -> E + E 76 | E -> E * E 77 | E -> E - E 78 | E -> E / E 79 | E -> - E 80 | E -> ( E ) 81 | E -> IDN 82 | E -> digit 83 | E -> L 84 | L -> IDN [ E ] 85 | L -> L [ E ] 86 | # 函数调用 87 | E -> call 88 | # 控制流语句 89 | S -> if ( B ) { P } 90 | S -> if ( B ) { P } else { P } 91 | S -> while ( B ) { P } 92 | S -> for ( S B ; IDN op ) { P } 93 | S -> for ( S B ; IDN = E ) { P } 94 | # 布尔表达式 95 | B -> B && B 96 | B -> B || B 97 | B -> E relop E 98 | B -> true 99 | B -> false 100 | # 关系运算符 101 | relop -> < 102 | relop -> <= 103 | relop -> == 104 | relop -> != 105 | relop -> > 106 | relop -> >= 107 | relop -> && 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | import os 20 | import sys 21 | import sphinx_rtd_theme 22 | sys.path.insert(0, os.path.abspath('/Users/mohaitao/Library/Mobile Documents/com~apple~CloudDocs/2019 Spring/Compliers/Complier-Mark-5')) 23 | 24 | project = 'Compliers' 25 | copyright = '2019, Alvin MO' 26 | author = 'Alvin MO' 27 | 28 | 29 | # -- General configuration --------------------------------------------------- 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = ['sphinx.ext.autodoc'] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates'] 38 | 39 | # List of patterns, relative to source directory, that match files and 40 | # directories to ignore when looking for source files. 41 | # This pattern also affects html_static_path and html_extra_path. 42 | exclude_patterns = [] 43 | 44 | 45 | # -- Options for HTML output ------------------------------------------------- 46 | 47 | # The theme to use for HTML and HTML Help pages. See the documentation for 48 | # a list of builtin themes. 49 | # 50 | # html_theme = 'alabaster' 51 | html_theme = "sphinx_rtd_theme" 52 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 53 | 54 | # Add any paths that contain custom static files (such as style sheets) here, 55 | # relative to this directory. They are copied after the builtin static files, 56 | # so a file named "default.css" will overwrite the builtin "default.css". 57 | html_static_path = ['_static'] 58 | -------------------------------------------------------------------------------- /venv/bin/activate: -------------------------------------------------------------------------------- 1 | # This file must be used with "source bin/activate" *from bash* 2 | # you cannot run it directly 3 | 4 | deactivate () { 5 | # reset old environment variables 6 | if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then 7 | PATH="${_OLD_VIRTUAL_PATH:-}" 8 | export PATH 9 | unset _OLD_VIRTUAL_PATH 10 | fi 11 | if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then 12 | PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" 13 | export PYTHONHOME 14 | unset _OLD_VIRTUAL_PYTHONHOME 15 | fi 16 | 17 | # This should detect bash and zsh, which have a hash command that must 18 | # be called to get it to forget past commands. Without forgetting 19 | # past commands the $PATH changes we made may not be respected 20 | if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then 21 | hash -r 22 | fi 23 | 24 | if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then 25 | PS1="${_OLD_VIRTUAL_PS1:-}" 26 | export PS1 27 | unset _OLD_VIRTUAL_PS1 28 | fi 29 | 30 | unset VIRTUAL_ENV 31 | if [ ! "$1" = "nondestructive" ] ; then 32 | # Self destruct! 33 | unset -f deactivate 34 | fi 35 | } 36 | 37 | # unset irrelevant variables 38 | deactivate nondestructive 39 | 40 | VIRTUAL_ENV="/Users/mohaitao/Library/Mobile Documents/com~apple~CloudDocs/2019 Spring/Compliers/expr2/Code/venv" 41 | export VIRTUAL_ENV 42 | 43 | _OLD_VIRTUAL_PATH="$PATH" 44 | PATH="$VIRTUAL_ENV/bin:$PATH" 45 | export PATH 46 | 47 | # unset PYTHONHOME if set 48 | # this will fail if PYTHONHOME is set to the empty string (which is bad anyway) 49 | # could use `if (set -u; : $PYTHONHOME) ;` in bash 50 | if [ -n "${PYTHONHOME:-}" ] ; then 51 | _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" 52 | unset PYTHONHOME 53 | fi 54 | 55 | if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then 56 | _OLD_VIRTUAL_PS1="${PS1:-}" 57 | if [ "x(venv) " != x ] ; then 58 | PS1="(venv) ${PS1:-}" 59 | else 60 | if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then 61 | # special case for Aspen magic directories 62 | # see http://www.zetadev.com/software/aspen/ 63 | PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" 64 | else 65 | PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" 66 | fi 67 | fi 68 | export PS1 69 | fi 70 | 71 | # This should detect bash and zsh, which have a hash command that must 72 | # be called to get it to forget past commands. Without forgetting 73 | # past commands the $PATH changes we made may not be respected 74 | if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then 75 | hash -r 76 | fi 77 | -------------------------------------------------------------------------------- /venv/bin/activate.fish: -------------------------------------------------------------------------------- 1 | # This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) 2 | # you cannot run it directly 3 | 4 | function deactivate -d "Exit virtualenv and return to normal shell environment" 5 | # reset old environment variables 6 | if test -n "$_OLD_VIRTUAL_PATH" 7 | set -gx PATH $_OLD_VIRTUAL_PATH 8 | set -e _OLD_VIRTUAL_PATH 9 | end 10 | if test -n "$_OLD_VIRTUAL_PYTHONHOME" 11 | set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME 12 | set -e _OLD_VIRTUAL_PYTHONHOME 13 | end 14 | 15 | if test -n "$_OLD_FISH_PROMPT_OVERRIDE" 16 | functions -e fish_prompt 17 | set -e _OLD_FISH_PROMPT_OVERRIDE 18 | functions -c _old_fish_prompt fish_prompt 19 | functions -e _old_fish_prompt 20 | end 21 | 22 | set -e VIRTUAL_ENV 23 | if test "$argv[1]" != "nondestructive" 24 | # Self destruct! 25 | functions -e deactivate 26 | end 27 | end 28 | 29 | # unset irrelevant variables 30 | deactivate nondestructive 31 | 32 | set -gx VIRTUAL_ENV "/Users/mohaitao/Library/Mobile Documents/com~apple~CloudDocs/2019 Spring/Compliers/expr2/Code/venv" 33 | 34 | set -gx _OLD_VIRTUAL_PATH $PATH 35 | set -gx PATH "$VIRTUAL_ENV/bin" $PATH 36 | 37 | # unset PYTHONHOME if set 38 | if set -q PYTHONHOME 39 | set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME 40 | set -e PYTHONHOME 41 | end 42 | 43 | if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" 44 | # fish uses a function instead of an env var to generate the prompt. 45 | 46 | # save the current fish_prompt function as the function _old_fish_prompt 47 | functions -c fish_prompt _old_fish_prompt 48 | 49 | # with the original prompt function renamed, we can override with our own. 50 | function fish_prompt 51 | # Save the return status of the last command 52 | set -l old_status $status 53 | 54 | # Prompt override? 55 | if test -n "(venv) " 56 | printf "%s%s" "(venv) " (set_color normal) 57 | else 58 | # ...Otherwise, prepend env 59 | set -l _checkbase (basename "$VIRTUAL_ENV") 60 | if test $_checkbase = "__" 61 | # special case for Aspen magic directories 62 | # see http://www.zetadev.com/software/aspen/ 63 | printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) 64 | else 65 | printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) 66 | end 67 | end 68 | 69 | # Restore the return status of the previous command. 70 | echo "exit $old_status" | . 71 | _old_fish_prompt 72 | end 73 | 74 | set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" 75 | end 76 | -------------------------------------------------------------------------------- /doc/build/html/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} 2 | /*# sourceMappingURL=badge_only.css.map */ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 哈工大编译器实验 2 | 3 | ### 词法分析器 Lexer 4 | 描述: 哈尔滨工业大学 编译原理 实验二 2019.4.19 5 | Python实现词法分析器,输出token序列表 6 | 7 | 主要功能:设计实现高级语言的词法分析器,基本功能为识别以下单词: 8 | (1) 标识符:由大小写字母、数字、下划线组成,但必须以字母和下划线开头; 9 | (2) 关键字:类型关键字(整型、浮点型、布尔型);分支结构中的if、else、then,循环结构中的do、while; 10 | (3) 运算符:算术运算符、关系运算符、逻辑运算符; 11 | (4) 分隔符:用于结尾的“;”,左右圆括号,花括号,中括号; 12 | (5) 常数:整数、浮点数 13 | (6) 注释:/*……*/ 14 | 15 | 16 | ### 语法分析器 Parser 17 | 描述: 哈尔滨工业大学 编译原理 实验二 2019.4.19 18 | Python实现语法分析器,识别由LR(1)文法产生的语言 19 | 20 | 主要功能: 21 | (1) 存储文法的产生式,自动归类终结符与非终结符,自动计算First集、Follow集; 22 | (2) 实现closure函数,对给定的项目集计算其闭包以及项目的展望符(lookahead); 23 | (3) 实现go函数,对给定的自动机状态S(i)与文法符号X,求解其转移状态S(j); 24 | (4) 利用closure函数与goto函数,生成识别LR(1)文法的viable prefix的自动机; 25 | (5) 自动构建action table和goto table; 26 | (6) 实现Parse语法分析,用符号栈和状态栈,结合action table和goto table,进行字符的shift与产生式的reduce,从而实现语法分析; 27 | (7) 处理来自Lexer词法分析器的输入,判断语法的正确性。 28 | 29 | 30 | ### 文法的定义: 31 | 32 | start -> classes 33 | 34 | #### 类 35 | 36 | classes -> classes classes 37 | 38 | classes -> class IDN { method } 39 | 40 | classes -> class IDN { field method } 41 | 42 | #### 域和方法 43 | 44 | field -> D 45 | 46 | field -> access D 47 | 48 | method -> method method 49 | 50 | method -> type IDN ( ) { P } 51 | 52 | method -> type IDN ( args ) { P } 53 | 54 | method -> access type IDN ( ) { P } 55 | 56 | method -> access type IDN ( args ) { P } 57 | 58 | #### 参数列表 59 | 60 | args -> args , arg 61 | 62 | args -> arg 63 | 64 | arg -> T IDN 65 | 66 | #### 访问控制符 67 | 68 | access -> public 69 | 70 | access -> private 71 | 72 | access -> protected 73 | 74 | #### 程序主体 75 | 76 | P -> P P 77 | 78 | P -> D 79 | 80 | P -> S 81 | 82 | S -> S S 83 | 84 | #### 声明语句 85 | 86 | D -> D D 87 | 88 | D -> D S 89 | 90 | D -> T IDN ; 91 | 92 | D -> T M ; 93 | 94 | M -> m 95 | 96 | M -> M , m 97 | 98 | m -> IDN = E ; 99 | 100 | D -> T IDN = E ; 101 | 102 | T -> type 103 | 104 | T -> type [ ] 105 | 106 | #### 数据类型 107 | 108 | type -> int 109 | 110 | type -> float 111 | 112 | type -> long 113 | 114 | type -> double 115 | 116 | type -> char 117 | 118 | type -> void 119 | 120 | #### 赋值语句 121 | 122 | S -> IDN = E ; 123 | 124 | S -> IDN op ; 125 | 126 | S -> op IDN ; 127 | 128 | op -> ++ 129 | 130 | op -> -- 131 | 132 | S -> L = E ; 133 | 134 | #### 函数调用 135 | 136 | S -> call ; 137 | 138 | call -> IDN ( ) 139 | 140 | call -> IDN ( param ) 141 | 142 | param -> E 143 | 144 | param -> param , E 145 | 146 | #### 运算表达式 147 | 148 | E -> E + E 149 | 150 | E -> E * E 151 | 152 | E -> - E 153 | 154 | E -> ( E ) 155 | 156 | E -> IDN 157 | 158 | E -> digit 159 | 160 | E -> L 161 | 162 | L -> IDN [ E ] 163 | 164 | L -> L [ E ] 165 | 166 | #### 函数调用 167 | 168 | E -> call 169 | 170 | #### 控制流语句 171 | 172 | S -> if ( B ) { P } 173 | 174 | S -> if ( B ) { P } else { P } 175 | 176 | S -> while ( B ) { P } 177 | 178 | S -> for ( S B ; IDN op ) { P } 179 | 180 | S -> for ( S B ; IDN = E ) { P } 181 | 182 | #### 布尔表达式 183 | 184 | B -> B and B 185 | 186 | B -> B or B 187 | 188 | B -> E relop E 189 | 190 | B -> true 191 | 192 | B -> false 193 | 194 | #### 关系运算符 195 | 196 | relop -> < 197 | 198 | relop -> <= 199 | 200 | relop -> == 201 | 202 | relop -> != 203 | 204 | relop -> > 205 | 206 | relop -> >= 207 | 208 | relop -> && 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /doc/build/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["Analyzer","Grammar","Helper","Lexer","Parser","Starter","index","modules"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:56},filenames:["Analyzer.rst","Grammar.rst","Helper.rst","Lexer.rst","Parser.rst","Starter.rst","index.rst","modules.rst"],objects:{"":{Analyzer:[0,0,0,"-"],Grammar:[1,0,0,"-"],Helper:[2,0,0,"-"],Lexer:[3,0,0,"-"],Parser:[4,0,0,"-"],Starter:[5,0,0,"-"]},"Analyzer.Analyzer":{check_convert:[0,2,1,""],check_declaration:[0,2,1,""],configure:[0,2,1,""],find_type:[0,2,1,""],generate:[0,2,1,""],is_sub_tree_of:[0,2,1,""],output_code:[0,2,1,""],output_symbol:[0,2,1,""],set_var:[0,2,1,""],show_code:[0,2,1,""],show_symbols:[0,2,1,""]},"Grammar.Grammar":{configure:[1,2,1,""],first:[1,2,1,""],follow:[1,2,1,""],isNullable:[1,2,1,""],load_grammar:[1,2,1,""],setNonterminals:[1,2,1,""],setTerminals:[1,2,1,""],viewFirst:[1,2,1,""],viewFollow:[1,2,1,""],viewProductions:[1,2,1,""]},"Lexer.Lexer":{configure:[3,2,1,""],parse:[3,2,1,""],parseWord:[3,2,1,""],preprocess:[3,2,1,""],readFile:[3,2,1,""],recogIdentifier:[3,2,1,""],recogNum:[3,2,1,""],setTable:[3,2,1,""]},"Parser.Parser":{"goto":[4,2,1,""],build_automata:[4,2,1,""],closure:[4,2,1,""],configure:[4,2,1,""],export_tables:[4,2,1,""],fill_table:[4,2,1,""],parse:[4,2,1,""],production_index:[4,2,1,""],read_tables:[4,2,1,""],update_parse:[4,2,1,""],view_automata:[4,2,1,""]},Analyzer:{Analyzer:[0,1,1,""],Line:[0,1,1,""],Symbol:[0,1,1,""],TreeNode:[0,1,1,""]},Grammar:{Grammar:[1,1,1,""]},Helper:{DictEntry:[2,1,1,""],Entry:[2,1,1,""],Item:[2,1,1,""],Production:[2,1,1,""]},Lexer:{Lexer:[3,1,1,""]},Parser:{Parser:[4,1,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method"},terms:{"\u8bed\u6cd5":1,"class":[0,1,2,3,4],"export":4,"goto":4,"return":4,"var":0,action:[2,4],addr:0,analyz:[6,7],arg:4,assign:0,automata:4,base:[0,1,2,3,4],build:4,build_automata:4,check_convert:0,check_declar:0,closur:4,configur:[0,1,3,4],construct:4,content:[2,6],correct:4,dictentri:2,dictionari:4,dlist:0,entri:2,expand:4,export_t:4,file:4,fill_tabl:4,find_typ:0,first:1,follow:1,gener:0,given:4,grammar:[4,6,7],grammat:4,helper:[0,6,7],hold:4,index:6,input:4,is_sub_tree_of:0,isnul:1,item:[2,4],itemset:4,its:4,judg:4,left:[2,4],lexer:[6,7],line:0,list:4,load:4,load_grammar:1,lookahead:2,lr1:4,modul:[6,7],name:0,none:[0,2],obejct:4,object:[0,1,2,3,4],operand1:0,operand2:0,output_cod:0,output_symbol:0,page:6,paramet:4,pars:[3,4],parser:[6,7],parseword:3,path:[1,3],perform:4,prefix:4,preprocess:3,product:[0,2],production_index:4,read_tabl:4,readfil:3,recogidentifi:3,recogn:4,recognum:3,record:4,right:[2,4],root1:0,root2:0,root:0,sai:4,search:6,self:4,serial:4,set:4,set_var:0,setnontermin:1,settabl:3,settermin:1,show_cod:0,show_symbol:0,slist:0,some:4,starter:[6,7],state:[2,4],symbol:[0,1,2,4],tabl:4,token:4,transfer:4,transit:4,treenod:0,tupl:3,type:0,update_pars:4,viabl:4,view_automata:4,viewfirst:1,viewfollow:1,viewproduct:1,whether:4,which:4,word:3,write:4},titles:["Analyzer module","Grammar module","Helper module","Lexer module","Parser module","Starter module","Welcome to Compliers\u2019s documentation!","S-Complier"],titleterms:{analyz:0,complier:[6,7],document:6,grammar:1,helper:2,indic:6,lexer:3,modul:[0,1,2,3,4,5],parser:4,starter:5,tabl:6,welcom:6}}) -------------------------------------------------------------------------------- /grammar.py: -------------------------------------------------------------------------------- 1 | from helper import * 2 | 3 | 4 | class Grammar(): 5 | """ LR(1)语法 """ 6 | def __init__(self): 7 | self.start_symbol = '' 8 | self.productions = [] 9 | self.firstSet = {} 10 | self.followSet = {} 11 | self.terminals = [] 12 | self.nonterminals = [] 13 | 14 | def load_grammar(self, path): 15 | i = 0 16 | for line in open(path): 17 | if '->' not in line: 18 | continue 19 | parts = line.split('->') 20 | left, right = parts[0].rstrip(), parts[1].strip().split(' ') 21 | if left[0] == '#': 22 | continue 23 | production = Production(left, right) 24 | production.index = i 25 | i += 1 26 | self.productions.append(production) 27 | if self.start_symbol == '': 28 | self.start_symbol = left 29 | 30 | def setNonterminals(self): 31 | for p in self.productions: 32 | if p.left not in self.nonterminals: 33 | self.nonterminals.append(p.left) 34 | 35 | def setTerminals(self): 36 | for p in self.productions: 37 | for item in p.right: 38 | if item not in self.nonterminals and item not in self.terminals: 39 | self.terminals.append(item) 40 | 41 | def isNullable(self, symbol): # 该算法假设文法中所有可空字符都是直接可空的,不存在传递可空 42 | for p in self.productions: 43 | if p.left == symbol and '$' in p.right: 44 | return True 45 | return False 46 | 47 | def first(self): 48 | for symbol in self.terminals: 49 | self.firstSet[symbol] = [symbol] 50 | for symbol in self.nonterminals: 51 | self.firstSet[symbol] = [] 52 | flag = True 53 | while flag: 54 | flag = False # flag值改变说明这一遍扫描有新收获 55 | for p in self.productions: 56 | # 遍历p的右部 57 | for part in p.right: 58 | if part != '$': 59 | for item in self.firstSet[part]: 60 | if item not in self.firstSet[p.left]: 61 | self.firstSet[p.left].append(item) 62 | flag = True 63 | if part == '$': 64 | if '$' not in self.firstSet[p.left]: 65 | self.firstSet[p.left].append('$') 66 | flag = True 67 | # 如果当前字符可空,first集应包含后续首字符的first,一直可空就一直往后看 68 | if not self.isNullable(part): 69 | break 70 | 71 | def follow(self): 72 | for symbol in self.nonterminals: 73 | self.followSet[symbol] = [] 74 | self.followSet[self.start_symbol].append('$') # 开始符号的follow集应有# 75 | flag = True 76 | while flag: 77 | flag = False 78 | for p in self.productions: 79 | for i in range(len(p.right)): # 遍历当前产生式的每个右部 80 | part = p.right[i] # 产生式p的第i个右部 81 | if part not in self.nonterminals: # 只处理非终结符 82 | continue 83 | allNullable = True # part的下一元素的first集包含在part的follow集中 84 | for j in range(i + 1, len(p.right)): # 遍历第i个右部的后面的元素 85 | for item in self.firstSet[p.right[j]]: 86 | if item not in self.followSet[part]: 87 | self.followSet[part].append(item) 88 | flag = True # 说明这一趟有新的收获 89 | if not self.isNullable(p.right[j]): 90 | allNullable = False 91 | break 92 | if allNullable: # 说明当前产生式右部的第i个元素后面的每一个元素都可空 93 | for item in self.followSet[p.left]: 94 | if item not in self.followSet[part]: 95 | self.followSet[part].append(item) 96 | flag = True 97 | 98 | def viewProductions(self): 99 | print("Productions of the grammar:") 100 | for p in self.productions: 101 | print(p.index, p.left, p.right) 102 | 103 | def viewFirst(self): # 查看文法对应的first集 104 | print("First Set of the grammar:") 105 | for k, v in self.firstSet.items(): 106 | print(k, v) 107 | 108 | def viewFollow(self): # 查看文法对应的follow集 109 | print("Follow Set of the grammar:") 110 | for k, v in self.followSet.items(): 111 | print(k, v) 112 | 113 | def configure(self, path): 114 | self.load_grammar(path) 115 | self.setNonterminals() 116 | self.setTerminals() 117 | self.first() 118 | self.follow() 119 | # self.viewProductions() 120 | 121 | 122 | -------------------------------------------------------------------------------- /doc/build/html/search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Search — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 | 48 | 85 | 86 |
87 | 88 | 89 | 93 | 94 | 95 | 96 |
97 |
98 |
99 |
    100 |
  • Docs »
  • 101 | 102 |
  • Search
  • 103 |
  • 104 | 105 |
  • 106 |
107 |
108 |
109 |
110 | 111 | 119 | 120 | 121 |
122 | 123 |
124 | 125 |
126 |
127 | 128 | 129 |
130 | 131 |
132 |

133 | © Copyright 2019, Alvin MO. 134 |

135 |
136 | 137 | Built with Sphinx using a theme provided by Read the Docs. 138 | 139 |
140 |
141 |
142 | 143 |
144 | 145 |
146 | 147 | 148 | 149 | 150 | 151 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 180 | 181 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /doc/build/html/Starter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Starter module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | 87 | 88 |
89 | 90 | 91 | 95 | 96 | 97 | 98 |
99 |
100 |
101 | 113 |
114 |
115 |
116 | 117 |
118 |

Starter module

119 |
120 | 121 | 122 |
123 |
124 | 125 | 131 | 132 | 133 |
134 | 135 |
136 |

137 | © Copyright 2019, Alvin MO. 138 |

139 |
140 | 141 | Built with Sphinx using a theme provided by Read the Docs. 142 | 143 |
144 |
145 |
146 | 147 |
148 | 149 |
150 | 151 | 152 | 153 | 154 | 155 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /doc/build/html/modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | S-Complier — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | 87 | 88 |
89 | 90 | 91 | 95 | 96 | 97 | 98 |
99 |
100 |
101 | 111 |
112 |
113 |
114 | 115 |
116 |

S-Complier

117 |
118 | 126 |
127 |
128 | 129 | 130 |
131 |
132 | 133 | 141 | 142 | 143 |
144 | 145 |
146 |

147 | © Copyright 2019, Alvin MO. 148 |

149 |
150 | 151 | Built with Sphinx using a theme provided by Read the Docs. 152 | 153 |
154 |
155 |
156 | 157 |
158 | 159 |
160 | 161 | 162 | 163 | 164 | 165 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /doc/build/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Welcome to Compliers’s documentation! — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 | 48 | 49 | 86 | 87 |
88 | 89 | 90 | 94 | 95 | 96 | 97 |
98 |
99 |
100 |
    101 |
  • Docs »
  • 102 | 103 |
  • Welcome to Compliers’s documentation!
  • 104 |
  • 105 | 106 | View page source 107 | 108 |
  • 109 |
110 |
111 |
112 |
113 | 114 |
115 |

Welcome to Compliers’s documentation!

116 |
117 |

Contents:

118 | 129 |
130 |
131 |
132 |

Indices and tables

133 | 138 |
139 | 140 | 141 |
142 |
143 | 144 | 150 | 151 | 152 |
153 | 154 |
155 |

156 | © Copyright 2019, Alvin MO. 157 |

158 |
159 | 160 | Built with Sphinx using a theme provided by Read the Docs. 161 | 162 |
163 |
164 |
165 | 166 |
167 | 168 |
169 | 170 | 171 | 172 | 173 | 174 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /doc/build/html/py-modindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Python Module Index — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 54 | 55 | 92 | 93 |
94 | 95 | 96 | 100 | 101 | 102 | 103 |
104 |
105 |
106 |
    107 |
  • Docs »
  • 108 | 109 |
  • Python Module Index
  • 110 |
  • 111 | 112 |
  • 113 |
114 |
115 |
116 |
117 | 118 | 119 |

Python Module Index

120 | 121 |
122 | a | 123 | g | 124 | h | 125 | l | 126 | p | 127 | s 128 |
129 | 130 | 131 | 132 | 134 | 135 | 136 | 139 | 140 | 142 | 143 | 144 | 147 | 148 | 150 | 151 | 152 | 155 | 156 | 158 | 159 | 160 | 163 | 164 | 166 | 167 | 168 | 171 | 172 | 174 | 175 | 176 | 179 |
 
133 | a
137 | Analyzer 138 |
 
141 | g
145 | Grammar 146 |
 
149 | h
153 | Helper 154 |
 
157 | l
161 | Lexer 162 |
 
165 | p
169 | Parser 170 |
 
173 | s
177 | Starter 178 |
180 | 181 | 182 |
183 |
184 | 185 | 186 |
187 | 188 |
189 |

190 | © Copyright 2019, Alvin MO. 191 |

192 |
193 | 194 | Built with Sphinx using a theme provided by Read the Docs. 195 | 196 |
197 |
198 |
199 | 200 |
201 | 202 |
203 | 204 | 205 | 206 | 207 | 208 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /doc/build/html/Helper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Helper module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | 88 | 89 |
90 | 91 | 92 | 96 | 97 | 98 | 99 |
100 |
101 |
102 | 114 |
115 |
116 |
117 | 118 |
119 |

Helper module

120 |
121 |
122 | class Helper.DictEntry(action=None, **content)
123 |

Bases: object

124 |
125 | 126 |
127 |
128 | class Helper.Entry(state, symbol, action=None, **content)
129 |

Bases: object

130 |
131 | 132 |
133 |
134 | class Helper.Item(left, right, lookahead)
135 |

Bases: object

136 |
137 | 138 |
139 |
140 | class Helper.Production(left, right)
141 |

Bases: object

142 |
143 | 144 |
145 | 146 | 147 |
148 |
149 | 150 | 158 | 159 | 160 |
161 | 162 |
163 |

164 | © Copyright 2019, Alvin MO. 165 |

166 |
167 | 168 | Built with Sphinx using a theme provided by Read the Docs. 169 | 170 |
171 |
172 |
173 | 174 |
175 | 176 |
177 | 178 | 179 | 180 | 181 | 182 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /lexer.py: -------------------------------------------------------------------------------- 1 | import time 2 | class Lexer: 3 | def __init__(self): 4 | self.code = '' 5 | self.OPERATOR = ['+', '-', '*', '/', '+=', '-=', '/=', '*=', '++', '--',\ 6 | '==', '>=', '<=', '=', 'and', 'or', \ 7 | '&&', '||', '~',\ 8 | '++', '--'] 9 | self.KEY_WORD = ['if', 'else', 'then', 'for', 'do', 'while', \ 10 | 'int', 'float', 'char', 'long', 'double', 'bool', 'typedef', 'struct','void',\ 11 | 'true', 'false','return', '@', \ 12 | 'include', 'using', 'namespace', 'std', 'new',\ 13 | 'printf', 'scanf', 'System', 'public', 'private', 'protected', 'class'] 14 | self.TYPE = ['int', 'float', 'char', 'long', 'bool'] 15 | self.DELIMITER = ['(', ')', '{', '}','[',']', ';', '<', '>', ','] 16 | self.map = {'if': 'IF', 'else': 'ELSE', 'then': 'THEN', 'for': 'FOR', 'while': 'WHILE', \ 17 | 'int': 'INT', 'float': 'FLOAT', 'char': 'CHAR', 'long': 'LONG', 'bool': 'BOOL', \ 18 | 'true':'TRUE', 'false':'FALSE','double': 'DOUBLE', '@': 'my', \ 19 | 'typedef': 'C', 'struct': 'C', 'void': 'C', 'printf': 'C', 'scanf': 'C', 'return': 'C', \ 20 | 'System': 'JAVA','public': 'ACESS', 'private': 'ACESS', 'protected': 'ACESS', 'class': 'JAVA', \ 21 | 'using': 'CPP', 'namespace': 'CPP', 'main': 'CPP', 'include': 'CPP', 'new':'CPP'} 22 | self.delimiter = {'(': 'LP', ')': 'RP', '{': 'CLP', '}': 'CRP', '[': 'LSB', ']': 'RSB', \ 23 | ';': 'SEMI'} 24 | 25 | self.output = [] 26 | self.variables = {} 27 | self.varCount = 0 28 | self.charError = False 29 | 30 | def readFile(self, path): 31 | f = open(path, 'r') 32 | code = f.read() 33 | self.code = code.split('\n') 34 | f.close() 35 | 36 | def preprocess(self): 37 | lineIndex = 1 38 | tuples = [] 39 | flag = False 40 | for line in self.code: 41 | # # 删除单行内的所有注释 42 | # while '/*' in line and '*/' in line: 43 | # leftNote = line.index('/*') 44 | # rightNote = line.index('*/') 45 | # part1 = line[0:leftNote] 46 | # part2 = line[rightNote + 2:] 47 | # line = part1 + part2 48 | # # 删除跨行注释,出现左部时,保留左边内容 49 | # if '/*' in line: 50 | # leftNote = line.index('/*') 51 | # line = line[0:leftNote] 52 | # li = line.split() 53 | # for word in li: 54 | # tuples.append([word, lineIndex]) 55 | # flag = True 56 | # if '*/' in line and flag is True: 57 | # flag = False 58 | # rightNote = line.index('*/') 59 | # line = line[rightNote + 2:] 60 | # if flag is True: 61 | # lineIndex += 1 62 | # continue 63 | word = '' 64 | for i in range(len(line)): 65 | if line[i] != ' ': 66 | word += line[i] 67 | elif line[i] == ' ': 68 | if word != '' and word != '\t': 69 | word = word.replace('\t', '') 70 | tuples.append([word, lineIndex]) 71 | word = '' 72 | else: 73 | continue 74 | if word != '' and word != '\t': 75 | word = word.replace('\t', '') 76 | tuples.append([word, lineIndex]) 77 | lineIndex += 1 78 | self.charset = set(self.code) 79 | self.tuples = tuples 80 | 81 | def recogNum(self, word): 82 | length = len(word) 83 | decimal, exponent, plus, minus = False, False, False, False 84 | for i in range(length): 85 | char = word[i] 86 | if char.isdigit(): 87 | continue 88 | elif char == '.': 89 | if decimal is False and exponent is False: 90 | decimal = True 91 | continue 92 | else: 93 | return i 94 | elif char == 'E': 95 | if (not exponent) and i in range(1, length - 1) and \ 96 | word[i - 1].isdigit() and (not plus) and (not minus) \ 97 | and (word[i + 1].isdigit() or word[i + 1] in ['+', '-']): 98 | exponent = True 99 | continue 100 | else: 101 | return i 102 | elif char == '+' or char == '-': 103 | if (not plus) and (not minus) and i != 0 and word[i - 1] == 'E': 104 | plus = True 105 | continue 106 | else: 107 | return i 108 | elif char == '-': 109 | if (not plus) and (not minus) and i != 0 and word[i - 1] == 'E': 110 | minus = True 111 | continue 112 | else: 113 | return i 114 | else: 115 | return i 116 | return True 117 | 118 | def recogIdentifier(self, word): 119 | length = len(word) 120 | letter = False 121 | for i in range(length): 122 | char = word[i] 123 | if char.isdigit(): 124 | if letter: 125 | continue 126 | else: 127 | return i 128 | elif char.isalpha(): 129 | letter = True 130 | continue 131 | elif char == '_': 132 | continue 133 | else: 134 | return i 135 | return True 136 | 137 | def parseWord(self, tuple): 138 | word, line = tuple[0], tuple[1] 139 | if len(word) == 0: 140 | return 141 | if len(word) >= 2 and word[0:2] in self.OPERATOR: 142 | self.output.append([word[0:2], "OP", "-", line]) 143 | self.parseWord([word[2:], line]) 144 | return 145 | char = word[0] 146 | if word in self.KEY_WORD: 147 | self.output.append([word, self.map[word], "-", line]) 148 | elif word in self.OPERATOR: 149 | self.output.append([word, 'OP', word, line]) 150 | elif char in self.OPERATOR: 151 | self.output.append([char, 'OP', word, line]) 152 | self.parseWord([word[1:], line]) 153 | elif char.isdigit(): 154 | result = self.recogNum(word) 155 | if result is True: 156 | self.output.append([word, "digit", word, line]) 157 | else: 158 | if result != 0: 159 | self.output.append([word[:result], "digit", word[:result], line]) 160 | self.parseWord([word[result:], line]) 161 | elif char.isalpha(): 162 | result = self.recogIdentifier(word) 163 | if result is True: 164 | self.output.append([word, "IDN", word, line]) 165 | self.varCount += 1 166 | else: 167 | if result != 0: 168 | self.output.append([word[:result], "IDN", word[:result], line]) 169 | word = word[result:] 170 | self.parseWord([word, line]) 171 | elif char in self.DELIMITER: 172 | self.output.append([char, "delimiter", char, line]) 173 | if len(word) >= 2: 174 | word = word[1:] 175 | self.parseWord([word, line]) 176 | 177 | def parse(self): 178 | for tuple in self.tuples: 179 | self.parseWord(tuple) 180 | 181 | def setTable(self): 182 | # 输出token表到文件 183 | f = open('./output/Tokens.txt', 'w') 184 | for term in self.output: 185 | f.write(str(term[0]) + "\t<" + str(term[1]) + "," + str(term[2]) + ">\t" + str(term[3]) + "\n") 186 | f.close() 187 | 188 | def configure(self, path): 189 | print("Conducting lexical analysis...") 190 | t = time.time() 191 | self.readFile(path) 192 | self.preprocess() 193 | self.parse() 194 | self.setTable() 195 | print("Lexical analysis completed in", '{:.4f}s'.format(1000*(time.time() - t))) 196 | 197 | 198 | if __name__ == "__main__": 199 | lexer = Lexer() 200 | # lexer.configure('source.txt') 201 | lexer.configure('SimpleCode.txt') 202 | -------------------------------------------------------------------------------- /doc/build/html/Lexer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Lexer module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | 88 | 89 |
90 | 91 | 92 | 96 | 97 | 98 | 99 |
100 |
101 |
102 | 114 |
115 |
116 |
117 | 118 |
119 |

Lexer module

120 |
121 |
122 | class Lexer.Lexer
123 |

Bases: object

124 |
125 |
126 | configure(path)
127 |
128 | 129 |
130 |
131 | parse()
132 |
133 | 134 |
135 |
136 | parseWord(tuple)
137 |
138 | 139 |
140 |
141 | preprocess()
142 |
143 | 144 |
145 |
146 | readFile(path)
147 |
148 | 149 |
150 |
151 | recogIdentifier(word)
152 |
153 | 154 |
155 |
156 | recogNum(word)
157 |
158 | 159 |
160 |
161 | setTable()
162 |
163 | 164 |
165 | 166 |
167 | 168 | 169 |
170 |
171 | 172 | 180 | 181 | 182 |
183 | 184 |
185 |

186 | © Copyright 2019, Alvin MO. 187 |

188 |
189 | 190 | Built with Sphinx using a theme provided by Read the Docs. 191 | 192 |
193 |
194 |
195 | 196 |
197 | 198 |
199 | 200 | 201 | 202 | 203 | 204 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /Parser/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | equalState 17 | 18 | 19 | 20 | 22 | 23 | 30 | 31 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 62 | 63 | 64 | 65 | 66 | 85 | 86 | 87 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 1555668805809 118 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /doc/build/html/Grammar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Grammar module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | 88 | 89 |
90 | 91 | 92 | 96 | 97 | 98 | 99 |
100 |
101 |
102 | 114 |
115 |
116 |
117 | 118 |
119 |

Grammar module

120 |
121 |
122 | class Grammar.Grammar
123 |

Bases: object

124 |

LR(1)语法

125 |
126 |
127 | configure(path)
128 |
129 | 130 |
131 |
132 | first()
133 |
134 | 135 |
136 |
137 | follow()
138 |
139 | 140 |
141 |
142 | isNullable(symbol)
143 |
144 | 145 |
146 |
147 | load_grammar(path)
148 |
149 | 150 |
151 |
152 | setNonterminals()
153 |
154 | 155 |
156 |
157 | setTerminals()
158 |
159 | 160 |
161 |
162 | viewFirst()
163 |
164 | 165 |
166 |
167 | viewFollow()
168 |
169 | 170 |
171 |
172 | viewProductions()
173 |
174 | 175 |
176 | 177 |
178 | 179 | 180 |
181 |
182 | 183 | 191 | 192 | 193 |
194 | 195 |
196 |

197 | © Copyright 2019, Alvin MO. 198 |

199 |
200 | 201 | Built with Sphinx using a theme provided by Read the Docs. 202 | 203 |
204 |
205 |
206 | 207 |
208 | 209 |
210 | 211 | 212 | 213 | 214 | 215 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /doc/build/html/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Sphinx JavaScript utilities for all documentation. 6 | * 7 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | /** 13 | * select a different prefix for underscore 14 | */ 15 | $u = _.noConflict(); 16 | 17 | /** 18 | * make the code below compatible with browsers without 19 | * an installed firebug like debugger 20 | if (!window.console || !console.firebug) { 21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", 22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", 23 | "profile", "profileEnd"]; 24 | window.console = {}; 25 | for (var i = 0; i < names.length; ++i) 26 | window.console[names[i]] = function() {}; 27 | } 28 | */ 29 | 30 | /** 31 | * small helper function to urldecode strings 32 | */ 33 | jQuery.urldecode = function(x) { 34 | return decodeURIComponent(x).replace(/\+/g, ' '); 35 | }; 36 | 37 | /** 38 | * small helper function to urlencode strings 39 | */ 40 | jQuery.urlencode = encodeURIComponent; 41 | 42 | /** 43 | * This function returns the parsed url parameters of the 44 | * current request. Multiple values per key are supported, 45 | * it will always return arrays of strings for the value parts. 46 | */ 47 | jQuery.getQueryParameters = function(s) { 48 | if (typeof s === 'undefined') 49 | s = document.location.search; 50 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 51 | var result = {}; 52 | for (var i = 0; i < parts.length; i++) { 53 | var tmp = parts[i].split('=', 2); 54 | var key = jQuery.urldecode(tmp[0]); 55 | var value = jQuery.urldecode(tmp[1]); 56 | if (key in result) 57 | result[key].push(value); 58 | else 59 | result[key] = [value]; 60 | } 61 | return result; 62 | }; 63 | 64 | /** 65 | * highlight a given string on a jquery object by wrapping it in 66 | * span elements with the given class name. 67 | */ 68 | jQuery.fn.highlightText = function(text, className) { 69 | function highlight(node, addItems) { 70 | if (node.nodeType === 3) { 71 | var val = node.nodeValue; 72 | var pos = val.toLowerCase().indexOf(text); 73 | if (pos >= 0 && 74 | !jQuery(node.parentNode).hasClass(className) && 75 | !jQuery(node.parentNode).hasClass("nohighlight")) { 76 | var span; 77 | var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); 78 | if (isInSVG) { 79 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 80 | } else { 81 | span = document.createElement("span"); 82 | span.className = className; 83 | } 84 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 85 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 86 | document.createTextNode(val.substr(pos + text.length)), 87 | node.nextSibling)); 88 | node.nodeValue = val.substr(0, pos); 89 | if (isInSVG) { 90 | var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); 91 | var bbox = node.parentElement.getBBox(); 92 | rect.x.baseVal.value = bbox.x; 93 | rect.y.baseVal.value = bbox.y; 94 | rect.width.baseVal.value = bbox.width; 95 | rect.height.baseVal.value = bbox.height; 96 | rect.setAttribute('class', className); 97 | addItems.push({ 98 | "parent": node.parentNode, 99 | "target": rect}); 100 | } 101 | } 102 | } 103 | else if (!jQuery(node).is("button, select, textarea")) { 104 | jQuery.each(node.childNodes, function() { 105 | highlight(this, addItems); 106 | }); 107 | } 108 | } 109 | var addItems = []; 110 | var result = this.each(function() { 111 | highlight(this, addItems); 112 | }); 113 | for (var i = 0; i < addItems.length; ++i) { 114 | jQuery(addItems[i].parent).before(addItems[i].target); 115 | } 116 | return result; 117 | }; 118 | 119 | /* 120 | * backward compatibility for jQuery.browser 121 | * This will be supported until firefox bug is fixed. 122 | */ 123 | if (!jQuery.browser) { 124 | jQuery.uaMatch = function(ua) { 125 | ua = ua.toLowerCase(); 126 | 127 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 128 | /(webkit)[ \/]([\w.]+)/.exec(ua) || 129 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 130 | /(msie) ([\w.]+)/.exec(ua) || 131 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || 132 | []; 133 | 134 | return { 135 | browser: match[ 1 ] || "", 136 | version: match[ 2 ] || "0" 137 | }; 138 | }; 139 | jQuery.browser = {}; 140 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; 141 | } 142 | 143 | /** 144 | * Small JavaScript module for the documentation. 145 | */ 146 | var Documentation = { 147 | 148 | init : function() { 149 | this.fixFirefoxAnchorBug(); 150 | this.highlightSearchWords(); 151 | this.initIndexTable(); 152 | if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { 153 | this.initOnKeyListeners(); 154 | } 155 | }, 156 | 157 | /** 158 | * i18n support 159 | */ 160 | TRANSLATIONS : {}, 161 | PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, 162 | LOCALE : 'unknown', 163 | 164 | // gettext and ngettext don't access this so that the functions 165 | // can safely bound to a different name (_ = Documentation.gettext) 166 | gettext : function(string) { 167 | var translated = Documentation.TRANSLATIONS[string]; 168 | if (typeof translated === 'undefined') 169 | return string; 170 | return (typeof translated === 'string') ? translated : translated[0]; 171 | }, 172 | 173 | ngettext : function(singular, plural, n) { 174 | var translated = Documentation.TRANSLATIONS[singular]; 175 | if (typeof translated === 'undefined') 176 | return (n == 1) ? singular : plural; 177 | return translated[Documentation.PLURALEXPR(n)]; 178 | }, 179 | 180 | addTranslations : function(catalog) { 181 | for (var key in catalog.messages) 182 | this.TRANSLATIONS[key] = catalog.messages[key]; 183 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 184 | this.LOCALE = catalog.locale; 185 | }, 186 | 187 | /** 188 | * add context elements like header anchor links 189 | */ 190 | addContextElements : function() { 191 | $('div[id] > :header:first').each(function() { 192 | $('\u00B6'). 193 | attr('href', '#' + this.id). 194 | attr('title', _('Permalink to this headline')). 195 | appendTo(this); 196 | }); 197 | $('dt[id]').each(function() { 198 | $('\u00B6'). 199 | attr('href', '#' + this.id). 200 | attr('title', _('Permalink to this definition')). 201 | appendTo(this); 202 | }); 203 | }, 204 | 205 | /** 206 | * workaround a firefox stupidity 207 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 208 | */ 209 | fixFirefoxAnchorBug : function() { 210 | if (document.location.hash && $.browser.mozilla) 211 | window.setTimeout(function() { 212 | document.location.href += ''; 213 | }, 10); 214 | }, 215 | 216 | /** 217 | * highlight the search words provided in the url in the text 218 | */ 219 | highlightSearchWords : function() { 220 | var params = $.getQueryParameters(); 221 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 222 | if (terms.length) { 223 | var body = $('div.body'); 224 | if (!body.length) { 225 | body = $('body'); 226 | } 227 | window.setTimeout(function() { 228 | $.each(terms, function() { 229 | body.highlightText(this.toLowerCase(), 'highlighted'); 230 | }); 231 | }, 10); 232 | $('') 234 | .appendTo($('#searchbox')); 235 | } 236 | }, 237 | 238 | /** 239 | * init the domain index toggle buttons 240 | */ 241 | initIndexTable : function() { 242 | var togglers = $('img.toggler').click(function() { 243 | var src = $(this).attr('src'); 244 | var idnum = $(this).attr('id').substr(7); 245 | $('tr.cg-' + idnum).toggle(); 246 | if (src.substr(-9) === 'minus.png') 247 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 248 | else 249 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 250 | }).css('display', ''); 251 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 252 | togglers.click(); 253 | } 254 | }, 255 | 256 | /** 257 | * helper function to hide the search marks again 258 | */ 259 | hideSearchWords : function() { 260 | $('#searchbox .highlight-link').fadeOut(300); 261 | $('span.highlighted').removeClass('highlighted'); 262 | }, 263 | 264 | /** 265 | * make the url absolute 266 | */ 267 | makeURL : function(relativeURL) { 268 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 269 | }, 270 | 271 | /** 272 | * get the current relative url 273 | */ 274 | getCurrentURL : function() { 275 | var path = document.location.pathname; 276 | var parts = path.split(/\//); 277 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 278 | if (this === '..') 279 | parts.pop(); 280 | }); 281 | var url = parts.join('/'); 282 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 283 | }, 284 | 285 | initOnKeyListeners: function() { 286 | $(document).keyup(function(event) { 287 | var activeElementType = document.activeElement.tagName; 288 | // don't navigate when in search box or textarea 289 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { 290 | switch (event.keyCode) { 291 | case 37: // left 292 | var prevHref = $('link[rel="prev"]').prop('href'); 293 | if (prevHref) { 294 | window.location.href = prevHref; 295 | return false; 296 | } 297 | case 39: // right 298 | var nextHref = $('link[rel="next"]').prop('href'); 299 | if (nextHref) { 300 | window.location.href = nextHref; 301 | return false; 302 | } 303 | } 304 | } 305 | }); 306 | } 307 | }; 308 | 309 | // quick alias for translations 310 | _ = Documentation.gettext; 311 | 312 | $(document).ready(function() { 313 | Documentation.init(); 314 | }); 315 | -------------------------------------------------------------------------------- /doc/build/html/Parser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Parser module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | 88 | 89 |
90 | 91 | 92 | 96 | 97 | 98 | 99 |
100 |
101 |
102 | 114 |
115 |
116 |
117 | 118 |
119 |

Parser module

120 |
121 |
122 | class Parser.Parser
123 |

Bases: object

124 |

LR1 Parser

125 |
126 |
127 | build_automata()
128 |

Build the automata for recognizing the viable prefix.

129 |
130 |
Parameters:

self - a parser obejct

131 |
132 |
133 |
134 | 135 |
136 |
137 | closure(itemset)
138 |

Build the closure of the given state, or say item set.

139 |
140 |
Args:

itemset: a state of the automata, which holds some items

141 |
142 |
Returns:

itemset: an expanded item set, or say its closure

143 |
144 |
145 |
146 | 147 |
148 |
149 | configure(grammar)
150 |
151 | 152 |
153 |
154 | export_tables()
155 |

Export the action table and goto table to files and perform serialization.

156 |
157 |
Args:

self: a parser object

158 |
159 |
160 |
161 | 162 |
163 |
164 | fill_table()
165 |

Construct the action table and goto table.

166 |
167 |
Args:

self: a parser object

168 |
169 |
170 |
171 | 172 |
173 |
174 | goto(itemset, symbol)
175 |

Construct the transition state.

176 |
177 |
Args:

itemset: a state of the automata, which holds some items 178 | symbol: the transfer symbol

179 |
180 |
Returns:

itemset: a transition state

181 |
182 |
183 |
184 | 185 |
186 |
187 | parse(w)
188 |

Parse the input tokens and judge whether it is grammatically correct. 189 | Write the record to files 190 | Args:

191 |
192 |

w: a list of tokens

193 |
194 |
195 | 196 |
197 |
198 | production_index(left, right)
199 |
200 | 201 |
202 |
203 | read_tables()
204 |

Load the action table and goto table dictionaries to the object

205 |
206 |
Args:

self: a parser object

207 |
208 |
209 |
210 | 211 |
212 |
213 | update_parse(w)
214 |
215 | 216 |
217 |
218 | view_automata()
219 |
220 | 221 |
222 | 223 |
224 | 225 | 226 |
227 |
228 | 229 | 237 | 238 | 239 |
240 | 241 |
242 |

243 | © Copyright 2019, Alvin MO. 244 |

245 |
246 | 247 | Built with Sphinx using a theme provided by Read the Docs. 248 | 249 |
250 |
251 |
252 | 253 |
254 | 255 |
256 | 257 | 258 | 259 | 260 | 261 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 289 | 290 | 291 | 292 | -------------------------------------------------------------------------------- /doc/build/html/Analyzer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Analyzer module — Compliers documentation 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 | 50 | 51 | 88 | 89 |
90 | 91 | 92 | 96 | 97 | 98 | 99 |
100 |
101 |
102 | 114 |
115 |
116 |
117 | 118 |
119 |

Analyzer module

120 |
121 |
122 | class Analyzer.Analyzer(root, Dlist, Slist)
123 |

Bases: object

124 |
125 |
126 | check_convert()
127 |
128 | 129 |
130 |
131 | check_declaration()
132 |
133 | 134 |
135 |
136 | configure()
137 |
138 | 139 |
140 |
141 | find_type(var)
142 |
143 | 144 |
145 |
146 | generate(root)
147 |
148 | 149 |
150 |
151 | is_sub_tree_of(root1, root2)
152 |
153 | 154 |
155 |
156 | output_code()
157 |
158 | 159 |
160 |
161 | output_symbol()
162 |
163 | 164 |
165 |
166 | set_var()
167 |
168 | 169 |
170 |
171 | show_code()
172 |
173 | 174 |
175 |
176 | show_symbols()
177 |
178 | 179 |
180 | 181 |
182 |
183 | class Analyzer.Line(op, operand1, operand2, assign)
184 |

Bases: object

185 |
186 | 187 |
188 |
189 | class Analyzer.Symbol(name, type, addr)
190 |

Bases: object

191 |
192 | 193 |
194 |
195 | class Analyzer.TreeNode(name=None, production=<Helper.Production object>)
196 |

Bases: object

197 |
198 | 199 |
200 | 201 | 202 |
203 |
204 | 205 | 213 | 214 | 215 |
216 | 217 |
218 |

219 | © Copyright 2019, Alvin MO. 220 |

221 |
222 | 223 | Built with Sphinx using a theme provided by Read the Docs. 224 | 225 |
226 |
227 |
228 | 229 |
230 | 231 |
232 | 233 | 234 | 235 | 236 | 237 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 265 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /doc/build/html/_static/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.3.1 2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== 9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, 10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= 11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== 12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= 13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= 14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= 15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, 17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; 24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, 25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; 26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; 27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), 28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ 29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= 30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= 31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); 32 | -------------------------------------------------------------------------------- /doc/build/html/_static/language_data.js: -------------------------------------------------------------------------------- 1 | /* 2 | * language_data.js 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * This script contains the language-specific data used by searchtools.js, 6 | * namely the list of stopwords, stemmer, scorer and splitter. 7 | * 8 | * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. 9 | * :license: BSD, see LICENSE for details. 10 | * 11 | */ 12 | 13 | var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; 14 | 15 | 16 | /* Non-minified version JS is _stemmer.js if file is provided */ 17 | /** 18 | * Porter Stemmer 19 | */ 20 | var Stemmer = function() { 21 | 22 | var step2list = { 23 | ational: 'ate', 24 | tional: 'tion', 25 | enci: 'ence', 26 | anci: 'ance', 27 | izer: 'ize', 28 | bli: 'ble', 29 | alli: 'al', 30 | entli: 'ent', 31 | eli: 'e', 32 | ousli: 'ous', 33 | ization: 'ize', 34 | ation: 'ate', 35 | ator: 'ate', 36 | alism: 'al', 37 | iveness: 'ive', 38 | fulness: 'ful', 39 | ousness: 'ous', 40 | aliti: 'al', 41 | iviti: 'ive', 42 | biliti: 'ble', 43 | logi: 'log' 44 | }; 45 | 46 | var step3list = { 47 | icate: 'ic', 48 | ative: '', 49 | alize: 'al', 50 | iciti: 'ic', 51 | ical: 'ic', 52 | ful: '', 53 | ness: '' 54 | }; 55 | 56 | var c = "[^aeiou]"; // consonant 57 | var v = "[aeiouy]"; // vowel 58 | var C = c + "[^aeiouy]*"; // consonant sequence 59 | var V = v + "[aeiou]*"; // vowel sequence 60 | 61 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 62 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 63 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 64 | var s_v = "^(" + C + ")?" + v; // vowel in stem 65 | 66 | this.stemWord = function (w) { 67 | var stem; 68 | var suffix; 69 | var firstch; 70 | var origword = w; 71 | 72 | if (w.length < 3) 73 | return w; 74 | 75 | var re; 76 | var re2; 77 | var re3; 78 | var re4; 79 | 80 | firstch = w.substr(0,1); 81 | if (firstch == "y") 82 | w = firstch.toUpperCase() + w.substr(1); 83 | 84 | // Step 1a 85 | re = /^(.+?)(ss|i)es$/; 86 | re2 = /^(.+?)([^s])s$/; 87 | 88 | if (re.test(w)) 89 | w = w.replace(re,"$1$2"); 90 | else if (re2.test(w)) 91 | w = w.replace(re2,"$1$2"); 92 | 93 | // Step 1b 94 | re = /^(.+?)eed$/; 95 | re2 = /^(.+?)(ed|ing)$/; 96 | if (re.test(w)) { 97 | var fp = re.exec(w); 98 | re = new RegExp(mgr0); 99 | if (re.test(fp[1])) { 100 | re = /.$/; 101 | w = w.replace(re,""); 102 | } 103 | } 104 | else if (re2.test(w)) { 105 | var fp = re2.exec(w); 106 | stem = fp[1]; 107 | re2 = new RegExp(s_v); 108 | if (re2.test(stem)) { 109 | w = stem; 110 | re2 = /(at|bl|iz)$/; 111 | re3 = new RegExp("([^aeiouylsz])\\1$"); 112 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 113 | if (re2.test(w)) 114 | w = w + "e"; 115 | else if (re3.test(w)) { 116 | re = /.$/; 117 | w = w.replace(re,""); 118 | } 119 | else if (re4.test(w)) 120 | w = w + "e"; 121 | } 122 | } 123 | 124 | // Step 1c 125 | re = /^(.+?)y$/; 126 | if (re.test(w)) { 127 | var fp = re.exec(w); 128 | stem = fp[1]; 129 | re = new RegExp(s_v); 130 | if (re.test(stem)) 131 | w = stem + "i"; 132 | } 133 | 134 | // Step 2 135 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 136 | if (re.test(w)) { 137 | var fp = re.exec(w); 138 | stem = fp[1]; 139 | suffix = fp[2]; 140 | re = new RegExp(mgr0); 141 | if (re.test(stem)) 142 | w = stem + step2list[suffix]; 143 | } 144 | 145 | // Step 3 146 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 147 | if (re.test(w)) { 148 | var fp = re.exec(w); 149 | stem = fp[1]; 150 | suffix = fp[2]; 151 | re = new RegExp(mgr0); 152 | if (re.test(stem)) 153 | w = stem + step3list[suffix]; 154 | } 155 | 156 | // Step 4 157 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 158 | re2 = /^(.+?)(s|t)(ion)$/; 159 | if (re.test(w)) { 160 | var fp = re.exec(w); 161 | stem = fp[1]; 162 | re = new RegExp(mgr1); 163 | if (re.test(stem)) 164 | w = stem; 165 | } 166 | else if (re2.test(w)) { 167 | var fp = re2.exec(w); 168 | stem = fp[1] + fp[2]; 169 | re2 = new RegExp(mgr1); 170 | if (re2.test(stem)) 171 | w = stem; 172 | } 173 | 174 | // Step 5 175 | re = /^(.+?)e$/; 176 | if (re.test(w)) { 177 | var fp = re.exec(w); 178 | stem = fp[1]; 179 | re = new RegExp(mgr1); 180 | re2 = new RegExp(meq1); 181 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 182 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 183 | w = stem; 184 | } 185 | re = /ll$/; 186 | re2 = new RegExp(mgr1); 187 | if (re.test(w) && re2.test(w)) { 188 | re = /.$/; 189 | w = w.replace(re,""); 190 | } 191 | 192 | // and turn initial Y back to y 193 | if (firstch == "y") 194 | w = firstch.toLowerCase() + w.substr(1); 195 | return w; 196 | } 197 | } 198 | 199 | 200 | 201 | 202 | 203 | var splitChars = (function() { 204 | var result = {}; 205 | var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, 206 | 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, 207 | 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, 208 | 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, 209 | 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, 210 | 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, 211 | 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, 212 | 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, 213 | 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, 214 | 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; 215 | var i, j, start, end; 216 | for (i = 0; i < singles.length; i++) { 217 | result[singles[i]] = true; 218 | } 219 | var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], 220 | [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], 221 | [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], 222 | [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], 223 | [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], 224 | [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], 225 | [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], 226 | [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], 227 | [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], 228 | [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], 229 | [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], 230 | [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], 231 | [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], 232 | [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], 233 | [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], 234 | [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], 235 | [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], 236 | [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], 237 | [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], 238 | [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], 239 | [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], 240 | [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], 241 | [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], 242 | [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], 243 | [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], 244 | [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], 245 | [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], 246 | [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], 247 | [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], 248 | [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], 249 | [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], 250 | [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], 251 | [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], 252 | [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], 253 | [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], 254 | [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], 255 | [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], 256 | [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], 257 | [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], 258 | [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], 259 | [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], 260 | [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], 261 | [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], 262 | [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], 263 | [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], 264 | [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], 265 | [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], 266 | [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], 267 | [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; 268 | for (i = 0; i < ranges.length; i++) { 269 | start = ranges[i][0]; 270 | end = ranges[i][1]; 271 | for (j = start; j <= end; j++) { 272 | result[j] = true; 273 | } 274 | } 275 | return result; 276 | })(); 277 | 278 | function splitQuery(query) { 279 | var result = []; 280 | var start = -1; 281 | for (var i = 0; i < query.length; i++) { 282 | if (splitChars[query.charCodeAt(i)]) { 283 | if (start !== -1) { 284 | result.push(query.slice(start, i)); 285 | start = -1; 286 | } 287 | } else if (start === -1) { 288 | start = i; 289 | } 290 | } 291 | if (start !== -1) { 292 | result.push(query.slice(start)); 293 | } 294 | return result; 295 | } 296 | 297 | 298 | -------------------------------------------------------------------------------- /semantic_analyzer.py: -------------------------------------------------------------------------------- 1 | from helper import * 2 | 3 | 4 | class Line: 5 | def __init__(self, op, operand1, operand2, assign): 6 | self.op = op 7 | self.operand1 = operand1 8 | self.operand2 = operand2 9 | self.assign = assign 10 | 11 | def __str__(self): 12 | return '(' + self.op + ', ' + self.operand1 + ', ' + self.operand2 + ', ' + self.assign + ')' 13 | 14 | 15 | class Symbol: 16 | def __init__(self, name, type, addr): 17 | self.name = name 18 | self.type = type 19 | self.addr = addr 20 | self.val = 0 21 | 22 | def __eq__(self, other): 23 | if isinstance(other, self.__class__): 24 | return self.name == other.name and self.type == other.type 25 | else: 26 | return False 27 | 28 | def __str__(self): 29 | return self.name + ' ' + self.type + ' ' + str(self.val) + ' ' + str(self.addr) 30 | 31 | 32 | class TreeNode: 33 | def __init__(self, name=None, production=Production(None, None)): 34 | self.parent = None 35 | self.children = [] 36 | self.name = name 37 | self.production = production 38 | self.left = production.left 39 | self.right = production.right 40 | self.tuple = [] 41 | 42 | def __eq__(self, other): 43 | if isinstance(other, self.__class__): 44 | return self.tuple == other.tuple and self.name == other.name 45 | else: 46 | return False 47 | 48 | 49 | class Analyzer: 50 | def __init__(self, root, Dlist, Slist): 51 | self.root = root 52 | self.stack = [] 53 | self.code = [] 54 | self.Dlist = Dlist 55 | self.Slist = Slist 56 | self.count = 0 # 行号 57 | self.record = [] 58 | self.table = [] 59 | self.temp_var = [] 60 | 61 | def configure(self): 62 | # 把包含在其他语句块的语句块挑出来 63 | indices = [] 64 | for i in range(len(self.Slist)): 65 | for j in range(i, len(self.Slist)): 66 | if self.is_sub_tree_of(self.Slist[i], self.Slist[j]): 67 | if i not in indices: 68 | indices.append(i) 69 | 70 | # 只保留不包含在其他语句块的语句块 71 | Slist = [] 72 | for i in range(len(self.Slist)): 73 | if i not in indices: 74 | Slist.append(self.Slist[i]) 75 | self.Slist = Slist 76 | # 为每个独立语句块生成中间代码 77 | for node in self.Slist: 78 | if node.name not in self.record: 79 | self.generate(node) 80 | # 设置变量名 81 | self.set_var() 82 | # 显示中间代码 83 | self.show_code() 84 | # 检查变量是否已声明 85 | self.check_declaration() 86 | # 检查类型转换错误 87 | self.check_convert() 88 | # 显示符号表 89 | self.show_symbols() 90 | # 输出符号表到文件 91 | self.output_symbol() 92 | # 输出中间代码到文件 93 | self.output_code() 94 | 95 | def generate(self, root): 96 | flag1 = True # 表明该节点的孩纸不包含$,没有依赖关系 97 | for i in range(len(root.tuple) - 1, -1, -1): 98 | if root.tuple[i][0] == '$': 99 | flag1 = False 100 | break 101 | 102 | flag2 = True # 表明该节点全为$,完全依赖关系 103 | for item in root.tuple: 104 | if item[0] != '$': 105 | flag2 = False 106 | break 107 | 108 | if flag1 is True: # 可以直接生成代码,没有依赖关系 109 | op = root.tuple[1] 110 | if op == '=': 111 | operand1, operand2, assign = root.tuple[2], '-', root.tuple[0] 112 | else: 113 | operand1, operand2, assign = root.tuple[0], root.tuple[2], root.name 114 | line = Line(op, operand1, operand2, assign) 115 | self.count += 1 116 | self.code.append(line) 117 | elif flag2 is False: # 孩子既有终结符也有$ 118 | if 'if' in root.tuple: 119 | # 三个j语句的位置 120 | # 生成第一个跳转语句 121 | op, operand1, operand2, assign = 'j'+str(root.children[2].tuple[1]), \ 122 | root.children[2].tuple[0], \ 123 | root.children[2].tuple[2], '-' 124 | line = Line(op, operand1, operand2, assign) 125 | self.count += 1 126 | 127 | self.code.append(line) 128 | # 设置第一个跳转语句的位置,以及跳转的目的地 129 | j1 = self.count 130 | j2 = j1 + 1 131 | 132 | # 生成第二个跳转语句 133 | op, operand1, operand2, assign = 'j', '-', '-', '-' 134 | line = Line(op, operand1, operand2, assign) 135 | self.count += 1 136 | self.code.append(line) 137 | 138 | # 生成条件成立对应的语句块 139 | self.generate(root.children[4]) 140 | 141 | # 记录第三个跳转语句的位置(离开语句) 142 | j3 = self.count 143 | 144 | # 生成第三个跳转语句 145 | op, operand1, operand2, assign = 'j', '-', '-', '-' 146 | line = Line(op, operand1, operand2, assign) 147 | self.count += 1 148 | self.code.append(line) 149 | 150 | # 设置第二个跳转语句的目的地 151 | self.code[j2 - 1].assign = str(self.count) 152 | 153 | # if -> 生成条件不成立对应的语句块 154 | self.generate(root.children[6]) 155 | self.code[j1 - 1].assign = str(j2 + 1) 156 | self.code[j3].assign = str(self.count + 1) 157 | elif 'while' in root.tuple: 158 | # 记录三个跳转语句的位置 159 | # 生成第一个跳转语句 160 | op, operand1, operand2, assign = 'j' + str(root.children[2].tuple[1]), \ 161 | root.children[2].tuple[0], \ 162 | root.children[2].tuple[2], '-' 163 | line = Line(op, operand1, operand2, assign) 164 | self.count += 1 165 | j1 = self.count 166 | j2 = j1 + 1 167 | self.code.append(line) 168 | 169 | # 生成第二个跳转语句 170 | op, operand1, operand2, assign = 'j', '-', '-', '-' 171 | line = Line(op, operand1, operand2, assign) 172 | self.count += 1 173 | self.code.append(line) 174 | 175 | # 生成条件成立对应的语句块 176 | self.generate(root.children[4]) 177 | 178 | # 生成第三个跳转语句 179 | op, operand1, operand2, assign = 'j', '-', '-', str(j1) 180 | line = Line(op, operand1, operand2, assign) 181 | self.count += 1 182 | self.code.append(line) 183 | self.code[j1 - 1].assign = str(j1 + 2) 184 | self.code[j2 - 1].assign = str(self.count + 1) 185 | 186 | else: 187 | if root.name in self.record: 188 | return 189 | self.generate(root.children[i]) 190 | operand1, op, operand2, assign = root.children[2].name, root.tuple[1], \ 191 | '-', root.tuple[0] 192 | line = Line(op, operand1, operand2, assign) 193 | self.count += 1 194 | self.code.append(line) 195 | self.record.append(root.name) 196 | 197 | else: # 子节点全是依赖关系 198 | for i in range(len(root.children)): 199 | self.generate(root.children[i]) 200 | 201 | def set_var(self): # 把$符号改成t符号 202 | vars = [] 203 | for line in self.code: 204 | if line.operand1[0] == '$' and line.operand1 not in vars: 205 | vars.append(line.operand1) 206 | if line.operand2[0] == '$' and line.operand2 not in vars: 207 | vars.append(line.operand2) 208 | if line.assign[0] == '$' and line.assign not in vars: 209 | vars.append(line.assign) 210 | tCount = 1 211 | for var in vars: 212 | for line in self.code: 213 | if line.operand1 == var: 214 | line.operand1 = 't'+str(tCount) 215 | if line.operand2 == var: 216 | line.operand2 = 't'+str(tCount) 217 | if line.assign == var: 218 | line.assign = 't'+str(tCount) 219 | tCount += 1 220 | 221 | def show_code(self): 222 | count = 1 223 | for line in self.code: 224 | string = str(count) + ':\t' + '(' + line.op + ', ' + line.operand1 + ', ' \ 225 | + line.operand2 + ', ' + line.assign + ')' 226 | print(string) 227 | count += 1 228 | 229 | def is_sub_tree_of(self, root1, root2): 230 | # 判断root1是否为root2的子树 231 | if not root2.children: 232 | return False 233 | for item in root2.tuple: 234 | if item == root1.name: 235 | return True 236 | flag = False 237 | for child in root2.children: 238 | flag = flag or self.is_sub_tree_of(root1, child) 239 | return flag 240 | 241 | def check_declaration(self): # 检查变量声明错误 242 | addr, vars, duplicates = 0, [], [] 243 | for item in self.Dlist: # 遍历Dlist来填符号表 244 | name, type = item.tuple[1], item.tuple[0] 245 | symbol = Symbol(name, type, hex(addr)) 246 | if type == 'int': 247 | addr += 4 248 | else: 249 | addr += 8 250 | if name not in vars: 251 | self.table.append(symbol) 252 | vars.append(name) 253 | else: 254 | duplicates.append(name) 255 | # 检查变量未声明错误、类型转换错误(double -> int) 256 | unDeclared = [] 257 | for line in self.code: 258 | items = [line.operand1, line.operand2, line.assign] 259 | for item in items: 260 | if item not in vars and item[0] != 't' and item != '-' \ 261 | and item not in unDeclared and not item.isdigit(): 262 | unDeclared.append(item) 263 | var1, var2 = line.operand1, line.operand2 264 | type1, type2 = self.find_type(var1), self.find_type(var2) 265 | if type1 is None or type2 is None: 266 | continue 267 | if line.assign[0] == 't': 268 | types = [type1, type2] 269 | if 'double' in types: 270 | new_type = 'double' 271 | incr = 8 272 | else: 273 | new_type = 'int' 274 | incr = 4 275 | self.temp_var.append(Symbol(line.assign, new_type, hex(addr))) 276 | addr += incr 277 | 278 | print("\n*** Variable declaration error ***") 279 | for var in unDeclared: 280 | print("Undeclared variable: ", var) 281 | for var in duplicates: 282 | print("Repeated declaration: ", var) 283 | 284 | def find_type(self, var): 285 | for symbol in self.table: 286 | if symbol.name == var: 287 | return symbol.type 288 | for symbol in self.temp_var: 289 | if symbol.name == var: 290 | return symbol.type 291 | 292 | def show_symbols(self): 293 | print("\n*** Symbol table ***") 294 | for symbol in self.table: 295 | print(symbol) 296 | print("\n*** Temp vars table ***") 297 | for symbol in self.temp_var: 298 | print(symbol) 299 | 300 | def output_symbol(self): 301 | f = open('./output/Symbols.txt', 'w') 302 | for symbol in self.table: 303 | f.write(str(symbol)) 304 | f.write("\n") 305 | 306 | def output_code(self): 307 | f = open('./output/IntermediateCode.txt', 'w') 308 | for line in self.code: 309 | f.write(str(line)) 310 | f.write('\n') 311 | 312 | def check_convert(self): 313 | vars, count = [], 0 314 | for line in self.code: 315 | op, var1, var2 = line.op, line.operand1, line.assign 316 | count += 1 317 | if op != '=': 318 | continue 319 | type1, type2 = self.find_type(var1), self.find_type(var2) 320 | if type1 == 'double' and type2 == 'int': 321 | vars.append(count) 322 | print("\n*** Type convert error ***") 323 | for var in vars: 324 | print("Convert from double to int, at line", var) 325 | 326 | 327 | -------------------------------------------------------------------------------- /output/ActionTable.txt: -------------------------------------------------------------------------------- 1 | 0 int s {'shift_state': 4} 2 | 0 double s {'shift_state': 5} 3 | 1 # acc {} 4 | 2 IDN s {'shift_state': 8} 5 | 2 int s {'shift_state': 4} 6 | 2 double s {'shift_state': 5} 7 | 2 if s {'shift_state': 9} 8 | 2 while s {'shift_state': 10} 9 | 3 IDN s {'shift_state': 11} 10 | 4 IDN r {'left': 'type', 'right': ['int']} 11 | 5 IDN r {'left': 'type', 'right': ['double']} 12 | 6 IDN r {'left': 'D', 'right': ['D', 'D']} 13 | 6 int s {'shift_state': 4} 14 | 6 double s {'shift_state': 5} 15 | 6 if r {'left': 'D', 'right': ['D', 'D']} 16 | 6 while r {'left': 'D', 'right': ['D', 'D']} 17 | 7 IDN s {'shift_state': 8} 18 | 7 if s {'shift_state': 9} 19 | 7 while s {'shift_state': 10} 20 | 7 # r {'left': 'P', 'right': ['D', 'S']} 21 | 8 = s {'shift_state': 13} 22 | 9 ( s {'shift_state': 14} 23 | 10 ( s {'shift_state': 15} 24 | 11 IDN r {'left': 'D', 'right': ['type', 'IDN']} 25 | 11 int r {'left': 'D', 'right': ['type', 'IDN']} 26 | 11 double r {'left': 'D', 'right': ['type', 'IDN']} 27 | 11 if r {'left': 'D', 'right': ['type', 'IDN']} 28 | 11 while r {'left': 'D', 'right': ['type', 'IDN']} 29 | 12 IDN s {'shift_state': 8} 30 | 12 if s {'shift_state': 9} 31 | 12 while s {'shift_state': 10} 32 | 12 # r {'left': 'S', 'right': ['S', 'S']} 33 | 13 IDN s {'shift_state': 19} 34 | 13 ( s {'shift_state': 20} 35 | 13 digit s {'shift_state': 21} 36 | 14 IDN s {'shift_state': 26} 37 | 14 ( s {'shift_state': 27} 38 | 14 digit s {'shift_state': 28} 39 | 14 true s {'shift_state': 29} 40 | 14 false s {'shift_state': 30} 41 | 15 IDN s {'shift_state': 26} 42 | 15 ( s {'shift_state': 27} 43 | 15 digit s {'shift_state': 28} 44 | 15 true s {'shift_state': 29} 45 | 15 false s {'shift_state': 30} 46 | 16 IDN r {'left': 'S', 'right': ['IDN', '=', 'E']} 47 | 16 + s {'shift_state': 32} 48 | 16 if r {'left': 'S', 'right': ['IDN', '=', 'E']} 49 | 16 while r {'left': 'S', 'right': ['IDN', '=', 'E']} 50 | 16 # r {'left': 'S', 'right': ['IDN', '=', 'E']} 51 | 17 IDN r {'left': 'E', 'right': ['T']} 52 | 17 + r {'left': 'E', 'right': ['T']} 53 | 17 * s {'shift_state': 33} 54 | 17 if r {'left': 'E', 'right': ['T']} 55 | 17 while r {'left': 'E', 'right': ['T']} 56 | 17 # r {'left': 'E', 'right': ['T']} 57 | 18 IDN r {'left': 'T', 'right': ['F']} 58 | 18 + r {'left': 'T', 'right': ['F']} 59 | 18 * r {'left': 'T', 'right': ['F']} 60 | 18 if r {'left': 'T', 'right': ['F']} 61 | 18 while r {'left': 'T', 'right': ['F']} 62 | 18 # r {'left': 'T', 'right': ['F']} 63 | 19 IDN r {'left': 'F', 'right': ['IDN']} 64 | 19 + r {'left': 'F', 'right': ['IDN']} 65 | 19 * r {'left': 'F', 'right': ['IDN']} 66 | 19 if r {'left': 'F', 'right': ['IDN']} 67 | 19 while r {'left': 'F', 'right': ['IDN']} 68 | 19 # r {'left': 'F', 'right': ['IDN']} 69 | 20 IDN s {'shift_state': 37} 70 | 20 ( s {'shift_state': 38} 71 | 20 digit s {'shift_state': 39} 72 | 21 IDN r {'left': 'F', 'right': ['digit']} 73 | 21 + r {'left': 'F', 'right': ['digit']} 74 | 21 * r {'left': 'F', 'right': ['digit']} 75 | 21 if r {'left': 'F', 'right': ['digit']} 76 | 21 while r {'left': 'F', 'right': ['digit']} 77 | 21 # r {'left': 'F', 'right': ['digit']} 78 | 22 + s {'shift_state': 41} 79 | 22 > s {'shift_state': 42} 80 | 22 < s {'shift_state': 43} 81 | 23 + r {'left': 'E', 'right': ['T']} 82 | 23 * s {'shift_state': 44} 83 | 23 > r {'left': 'E', 'right': ['T']} 84 | 23 < r {'left': 'E', 'right': ['T']} 85 | 24 + r {'left': 'T', 'right': ['F']} 86 | 24 * r {'left': 'T', 'right': ['F']} 87 | 24 > r {'left': 'T', 'right': ['F']} 88 | 24 < r {'left': 'T', 'right': ['F']} 89 | 25 ) s {'shift_state': 45} 90 | 26 + r {'left': 'F', 'right': ['IDN']} 91 | 26 * r {'left': 'F', 'right': ['IDN']} 92 | 26 > r {'left': 'F', 'right': ['IDN']} 93 | 26 < r {'left': 'F', 'right': ['IDN']} 94 | 27 IDN s {'shift_state': 37} 95 | 27 ( s {'shift_state': 38} 96 | 27 digit s {'shift_state': 39} 97 | 28 + r {'left': 'F', 'right': ['digit']} 98 | 28 * r {'left': 'F', 'right': ['digit']} 99 | 28 > r {'left': 'F', 'right': ['digit']} 100 | 28 < r {'left': 'F', 'right': ['digit']} 101 | 29 ) r {'left': 'C', 'right': ['true']} 102 | 30 ) r {'left': 'C', 'right': ['false']} 103 | 31 ) s {'shift_state': 47} 104 | 32 IDN s {'shift_state': 19} 105 | 32 ( s {'shift_state': 20} 106 | 32 digit s {'shift_state': 21} 107 | 33 IDN s {'shift_state': 19} 108 | 33 ( s {'shift_state': 20} 109 | 33 digit s {'shift_state': 21} 110 | 34 + s {'shift_state': 50} 111 | 34 ) s {'shift_state': 51} 112 | 35 + r {'left': 'E', 'right': ['T']} 113 | 35 * s {'shift_state': 52} 114 | 35 ) r {'left': 'E', 'right': ['T']} 115 | 36 + r {'left': 'T', 'right': ['F']} 116 | 36 * r {'left': 'T', 'right': ['F']} 117 | 36 ) r {'left': 'T', 'right': ['F']} 118 | 37 + r {'left': 'F', 'right': ['IDN']} 119 | 37 * r {'left': 'F', 'right': ['IDN']} 120 | 37 ) r {'left': 'F', 'right': ['IDN']} 121 | 38 IDN s {'shift_state': 37} 122 | 38 ( s {'shift_state': 38} 123 | 38 digit s {'shift_state': 39} 124 | 39 + r {'left': 'F', 'right': ['digit']} 125 | 39 * r {'left': 'F', 'right': ['digit']} 126 | 39 ) r {'left': 'F', 'right': ['digit']} 127 | 40 IDN s {'shift_state': 37} 128 | 40 ( s {'shift_state': 38} 129 | 40 digit s {'shift_state': 39} 130 | 41 IDN s {'shift_state': 26} 131 | 41 ( s {'shift_state': 27} 132 | 41 digit s {'shift_state': 28} 133 | 42 IDN r {'left': 'relop', 'right': ['>']} 134 | 42 ( r {'left': 'relop', 'right': ['>']} 135 | 42 digit r {'left': 'relop', 'right': ['>']} 136 | 43 IDN r {'left': 'relop', 'right': ['<']} 137 | 43 ( r {'left': 'relop', 'right': ['<']} 138 | 43 digit r {'left': 'relop', 'right': ['<']} 139 | 44 IDN s {'shift_state': 26} 140 | 44 ( s {'shift_state': 27} 141 | 44 digit s {'shift_state': 28} 142 | 45 IDN s {'shift_state': 58} 143 | 45 if s {'shift_state': 59} 144 | 45 while s {'shift_state': 60} 145 | 46 + s {'shift_state': 50} 146 | 46 ) s {'shift_state': 61} 147 | 47 IDN s {'shift_state': 8} 148 | 47 if s {'shift_state': 9} 149 | 47 while s {'shift_state': 10} 150 | 48 IDN r {'left': 'E', 'right': ['E', '+', 'T']} 151 | 48 + r {'left': 'E', 'right': ['E', '+', 'T']} 152 | 48 * s {'shift_state': 33} 153 | 48 if r {'left': 'E', 'right': ['E', '+', 'T']} 154 | 48 while r {'left': 'E', 'right': ['E', '+', 'T']} 155 | 48 # r {'left': 'E', 'right': ['E', '+', 'T']} 156 | 49 IDN r {'left': 'T', 'right': ['T', '*', 'F']} 157 | 49 + r {'left': 'T', 'right': ['T', '*', 'F']} 158 | 49 * r {'left': 'T', 'right': ['T', '*', 'F']} 159 | 49 if r {'left': 'T', 'right': ['T', '*', 'F']} 160 | 49 while r {'left': 'T', 'right': ['T', '*', 'F']} 161 | 49 # r {'left': 'T', 'right': ['T', '*', 'F']} 162 | 50 IDN s {'shift_state': 37} 163 | 50 ( s {'shift_state': 38} 164 | 50 digit s {'shift_state': 39} 165 | 51 IDN r {'left': 'F', 'right': ['(', 'E', ')']} 166 | 51 + r {'left': 'F', 'right': ['(', 'E', ')']} 167 | 51 * r {'left': 'F', 'right': ['(', 'E', ')']} 168 | 51 if r {'left': 'F', 'right': ['(', 'E', ')']} 169 | 51 while r {'left': 'F', 'right': ['(', 'E', ')']} 170 | 51 # r {'left': 'F', 'right': ['(', 'E', ')']} 171 | 52 IDN s {'shift_state': 37} 172 | 52 ( s {'shift_state': 38} 173 | 52 digit s {'shift_state': 39} 174 | 53 + s {'shift_state': 50} 175 | 53 ) s {'shift_state': 65} 176 | 54 + s {'shift_state': 50} 177 | 54 ) r {'left': 'C', 'right': ['E', 'relop', 'E']} 178 | 55 + r {'left': 'E', 'right': ['E', '+', 'T']} 179 | 55 * s {'shift_state': 44} 180 | 55 > r {'left': 'E', 'right': ['E', '+', 'T']} 181 | 55 < r {'left': 'E', 'right': ['E', '+', 'T']} 182 | 56 + r {'left': 'T', 'right': ['T', '*', 'F']} 183 | 56 * r {'left': 'T', 'right': ['T', '*', 'F']} 184 | 56 > r {'left': 'T', 'right': ['T', '*', 'F']} 185 | 56 < r {'left': 'T', 'right': ['T', '*', 'F']} 186 | 57 IDN s {'shift_state': 58} 187 | 57 if s {'shift_state': 59} 188 | 57 else s {'shift_state': 67} 189 | 57 while s {'shift_state': 60} 190 | 58 = s {'shift_state': 68} 191 | 59 ( s {'shift_state': 69} 192 | 60 ( s {'shift_state': 70} 193 | 61 + r {'left': 'F', 'right': ['(', 'E', ')']} 194 | 61 * r {'left': 'F', 'right': ['(', 'E', ')']} 195 | 61 > r {'left': 'F', 'right': ['(', 'E', ')']} 196 | 61 < r {'left': 'F', 'right': ['(', 'E', ')']} 197 | 62 IDN s {'shift_state': 8} 198 | 62 if s {'shift_state': 9} 199 | 62 while s {'shift_state': 10} 200 | 62 # r {'left': 'S', 'right': ['while', '(', 'C', ')', 'S']} 201 | 63 + r {'left': 'E', 'right': ['E', '+', 'T']} 202 | 63 * s {'shift_state': 52} 203 | 63 ) r {'left': 'E', 'right': ['E', '+', 'T']} 204 | 64 + r {'left': 'T', 'right': ['T', '*', 'F']} 205 | 64 * r {'left': 'T', 'right': ['T', '*', 'F']} 206 | 64 ) r {'left': 'T', 'right': ['T', '*', 'F']} 207 | 65 + r {'left': 'F', 'right': ['(', 'E', ')']} 208 | 65 * r {'left': 'F', 'right': ['(', 'E', ')']} 209 | 65 ) r {'left': 'F', 'right': ['(', 'E', ')']} 210 | 66 IDN s {'shift_state': 58} 211 | 66 if s {'shift_state': 59} 212 | 66 else r {'left': 'S', 'right': ['S', 'S']} 213 | 66 while s {'shift_state': 60} 214 | 67 IDN s {'shift_state': 8} 215 | 67 if s {'shift_state': 9} 216 | 67 while s {'shift_state': 10} 217 | 68 IDN s {'shift_state': 75} 218 | 68 ( s {'shift_state': 76} 219 | 68 digit s {'shift_state': 77} 220 | 69 IDN s {'shift_state': 26} 221 | 69 ( s {'shift_state': 27} 222 | 69 digit s {'shift_state': 28} 223 | 69 true s {'shift_state': 29} 224 | 69 false s {'shift_state': 30} 225 | 70 IDN s {'shift_state': 26} 226 | 70 ( s {'shift_state': 27} 227 | 70 digit s {'shift_state': 28} 228 | 70 true s {'shift_state': 29} 229 | 70 false s {'shift_state': 30} 230 | 71 IDN s {'shift_state': 8} 231 | 71 if s {'shift_state': 9} 232 | 71 while s {'shift_state': 10} 233 | 71 # r {'left': 'S', 'right': ['if', '(', 'C', ')', 'S', 'else', 'S']} 234 | 72 IDN r {'left': 'S', 'right': ['IDN', '=', 'E']} 235 | 72 + s {'shift_state': 80} 236 | 72 if r {'left': 'S', 'right': ['IDN', '=', 'E']} 237 | 72 else r {'left': 'S', 'right': ['IDN', '=', 'E']} 238 | 72 while r {'left': 'S', 'right': ['IDN', '=', 'E']} 239 | 73 IDN r {'left': 'E', 'right': ['T']} 240 | 73 + r {'left': 'E', 'right': ['T']} 241 | 73 * s {'shift_state': 81} 242 | 73 if r {'left': 'E', 'right': ['T']} 243 | 73 else r {'left': 'E', 'right': ['T']} 244 | 73 while r {'left': 'E', 'right': ['T']} 245 | 74 IDN r {'left': 'T', 'right': ['F']} 246 | 74 + r {'left': 'T', 'right': ['F']} 247 | 74 * r {'left': 'T', 'right': ['F']} 248 | 74 if r {'left': 'T', 'right': ['F']} 249 | 74 else r {'left': 'T', 'right': ['F']} 250 | 74 while r {'left': 'T', 'right': ['F']} 251 | 75 IDN r {'left': 'F', 'right': ['IDN']} 252 | 75 + r {'left': 'F', 'right': ['IDN']} 253 | 75 * r {'left': 'F', 'right': ['IDN']} 254 | 75 if r {'left': 'F', 'right': ['IDN']} 255 | 75 else r {'left': 'F', 'right': ['IDN']} 256 | 75 while r {'left': 'F', 'right': ['IDN']} 257 | 76 IDN s {'shift_state': 37} 258 | 76 ( s {'shift_state': 38} 259 | 76 digit s {'shift_state': 39} 260 | 77 IDN r {'left': 'F', 'right': ['digit']} 261 | 77 + r {'left': 'F', 'right': ['digit']} 262 | 77 * r {'left': 'F', 'right': ['digit']} 263 | 77 if r {'left': 'F', 'right': ['digit']} 264 | 77 else r {'left': 'F', 'right': ['digit']} 265 | 77 while r {'left': 'F', 'right': ['digit']} 266 | 78 ) s {'shift_state': 83} 267 | 79 ) s {'shift_state': 84} 268 | 80 IDN s {'shift_state': 75} 269 | 80 ( s {'shift_state': 76} 270 | 80 digit s {'shift_state': 77} 271 | 81 IDN s {'shift_state': 75} 272 | 81 ( s {'shift_state': 76} 273 | 81 digit s {'shift_state': 77} 274 | 82 + s {'shift_state': 50} 275 | 82 ) s {'shift_state': 87} 276 | 83 IDN s {'shift_state': 58} 277 | 83 if s {'shift_state': 59} 278 | 83 while s {'shift_state': 60} 279 | 84 IDN s {'shift_state': 58} 280 | 84 if s {'shift_state': 59} 281 | 84 while s {'shift_state': 60} 282 | 85 IDN r {'left': 'E', 'right': ['E', '+', 'T']} 283 | 85 + r {'left': 'E', 'right': ['E', '+', 'T']} 284 | 85 * s {'shift_state': 81} 285 | 85 if r {'left': 'E', 'right': ['E', '+', 'T']} 286 | 85 else r {'left': 'E', 'right': ['E', '+', 'T']} 287 | 85 while r {'left': 'E', 'right': ['E', '+', 'T']} 288 | 86 IDN r {'left': 'T', 'right': ['T', '*', 'F']} 289 | 86 + r {'left': 'T', 'right': ['T', '*', 'F']} 290 | 86 * r {'left': 'T', 'right': ['T', '*', 'F']} 291 | 86 if r {'left': 'T', 'right': ['T', '*', 'F']} 292 | 86 else r {'left': 'T', 'right': ['T', '*', 'F']} 293 | 86 while r {'left': 'T', 'right': ['T', '*', 'F']} 294 | 87 IDN r {'left': 'F', 'right': ['(', 'E', ')']} 295 | 87 + r {'left': 'F', 'right': ['(', 'E', ')']} 296 | 87 * r {'left': 'F', 'right': ['(', 'E', ')']} 297 | 87 if r {'left': 'F', 'right': ['(', 'E', ')']} 298 | 87 else r {'left': 'F', 'right': ['(', 'E', ')']} 299 | 87 while r {'left': 'F', 'right': ['(', 'E', ')']} 300 | 88 IDN s {'shift_state': 58} 301 | 88 if s {'shift_state': 59} 302 | 88 else s {'shift_state': 90} 303 | 88 while s {'shift_state': 60} 304 | 89 IDN s {'shift_state': 58} 305 | 89 if s {'shift_state': 59} 306 | 89 else r {'left': 'S', 'right': ['while', '(', 'C', ')', 'S']} 307 | 89 while s {'shift_state': 60} 308 | 90 IDN s {'shift_state': 58} 309 | 90 if s {'shift_state': 59} 310 | 90 while s {'shift_state': 60} 311 | 91 IDN s {'shift_state': 58} 312 | 91 if s {'shift_state': 59} 313 | 91 else r {'left': 'S', 'right': ['if', '(', 'C', ')', 'S', 'else', 'S']} 314 | 91 while s {'shift_state': 60} 315 | -------------------------------------------------------------------------------- /doc/build/html/_static/alabaster.css: -------------------------------------------------------------------------------- 1 | @import url("basic.css"); 2 | 3 | /* -- page layout ----------------------------------------------------------- */ 4 | 5 | body { 6 | font-family: Georgia, serif; 7 | font-size: 17px; 8 | background-color: #fff; 9 | color: #000; 10 | margin: 0; 11 | padding: 0; 12 | } 13 | 14 | 15 | div.document { 16 | width: 940px; 17 | margin: 30px auto 0 auto; 18 | } 19 | 20 | div.documentwrapper { 21 | float: left; 22 | width: 100%; 23 | } 24 | 25 | div.bodywrapper { 26 | margin: 0 0 0 220px; 27 | } 28 | 29 | div.sphinxsidebar { 30 | width: 220px; 31 | font-size: 14px; 32 | line-height: 1.5; 33 | } 34 | 35 | hr { 36 | border: 1px solid #B1B4B6; 37 | } 38 | 39 | div.body { 40 | background-color: #fff; 41 | color: #3E4349; 42 | padding: 0 30px 0 30px; 43 | } 44 | 45 | div.body > .section { 46 | text-align: left; 47 | } 48 | 49 | div.footer { 50 | width: 940px; 51 | margin: 20px auto 30px auto; 52 | font-size: 14px; 53 | color: #888; 54 | text-align: right; 55 | } 56 | 57 | div.footer a { 58 | color: #888; 59 | } 60 | 61 | p.caption { 62 | font-family: inherit; 63 | font-size: inherit; 64 | } 65 | 66 | 67 | div.relations { 68 | display: none; 69 | } 70 | 71 | 72 | div.sphinxsidebar a { 73 | color: #444; 74 | text-decoration: none; 75 | border-bottom: 1px dotted #999; 76 | } 77 | 78 | div.sphinxsidebar a:hover { 79 | border-bottom: 1px solid #999; 80 | } 81 | 82 | div.sphinxsidebarwrapper { 83 | padding: 18px 10px; 84 | } 85 | 86 | div.sphinxsidebarwrapper p.logo { 87 | padding: 0; 88 | margin: -10px 0 0 0px; 89 | text-align: center; 90 | } 91 | 92 | div.sphinxsidebarwrapper h1.logo { 93 | margin-top: -10px; 94 | text-align: center; 95 | margin-bottom: 5px; 96 | text-align: left; 97 | } 98 | 99 | div.sphinxsidebarwrapper h1.logo-name { 100 | margin-top: 0px; 101 | } 102 | 103 | div.sphinxsidebarwrapper p.blurb { 104 | margin-top: 0; 105 | font-style: normal; 106 | } 107 | 108 | div.sphinxsidebar h3, 109 | div.sphinxsidebar h4 { 110 | font-family: Georgia, serif; 111 | color: #444; 112 | font-size: 24px; 113 | font-weight: normal; 114 | margin: 0 0 5px 0; 115 | padding: 0; 116 | } 117 | 118 | div.sphinxsidebar h4 { 119 | font-size: 20px; 120 | } 121 | 122 | div.sphinxsidebar h3 a { 123 | color: #444; 124 | } 125 | 126 | div.sphinxsidebar p.logo a, 127 | div.sphinxsidebar h3 a, 128 | div.sphinxsidebar p.logo a:hover, 129 | div.sphinxsidebar h3 a:hover { 130 | border: none; 131 | } 132 | 133 | div.sphinxsidebar p { 134 | color: #555; 135 | margin: 10px 0; 136 | } 137 | 138 | div.sphinxsidebar ul { 139 | margin: 10px 0; 140 | padding: 0; 141 | color: #000; 142 | } 143 | 144 | div.sphinxsidebar ul li.toctree-l1 > a { 145 | font-size: 120%; 146 | } 147 | 148 | div.sphinxsidebar ul li.toctree-l2 > a { 149 | font-size: 110%; 150 | } 151 | 152 | div.sphinxsidebar input { 153 | border: 1px solid #CCC; 154 | font-family: Georgia, serif; 155 | font-size: 1em; 156 | } 157 | 158 | div.sphinxsidebar hr { 159 | border: none; 160 | height: 1px; 161 | color: #AAA; 162 | background: #AAA; 163 | 164 | text-align: left; 165 | margin-left: 0; 166 | width: 50%; 167 | } 168 | 169 | div.sphinxsidebar .badge { 170 | border-bottom: none; 171 | } 172 | 173 | div.sphinxsidebar .badge:hover { 174 | border-bottom: none; 175 | } 176 | 177 | /* To address an issue with donation coming after search */ 178 | div.sphinxsidebar h3.donation { 179 | margin-top: 10px; 180 | } 181 | 182 | /* -- body styles ----------------------------------------------------------- */ 183 | 184 | a { 185 | color: #004B6B; 186 | text-decoration: underline; 187 | } 188 | 189 | a:hover { 190 | color: #6D4100; 191 | text-decoration: underline; 192 | } 193 | 194 | div.body h1, 195 | div.body h2, 196 | div.body h3, 197 | div.body h4, 198 | div.body h5, 199 | div.body h6 { 200 | font-family: Georgia, serif; 201 | font-weight: normal; 202 | margin: 30px 0px 10px 0px; 203 | padding: 0; 204 | } 205 | 206 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } 207 | div.body h2 { font-size: 180%; } 208 | div.body h3 { font-size: 150%; } 209 | div.body h4 { font-size: 130%; } 210 | div.body h5 { font-size: 100%; } 211 | div.body h6 { font-size: 100%; } 212 | 213 | a.headerlink { 214 | color: #DDD; 215 | padding: 0 4px; 216 | text-decoration: none; 217 | } 218 | 219 | a.headerlink:hover { 220 | color: #444; 221 | background: #EAEAEA; 222 | } 223 | 224 | div.body p, div.body dd, div.body li { 225 | line-height: 1.4em; 226 | } 227 | 228 | div.admonition { 229 | margin: 20px 0px; 230 | padding: 10px 30px; 231 | background-color: #EEE; 232 | border: 1px solid #CCC; 233 | } 234 | 235 | div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { 236 | background-color: #FBFBFB; 237 | border-bottom: 1px solid #fafafa; 238 | } 239 | 240 | div.admonition p.admonition-title { 241 | font-family: Georgia, serif; 242 | font-weight: normal; 243 | font-size: 24px; 244 | margin: 0 0 10px 0; 245 | padding: 0; 246 | line-height: 1; 247 | } 248 | 249 | div.admonition p.last { 250 | margin-bottom: 0; 251 | } 252 | 253 | div.highlight { 254 | background-color: #fff; 255 | } 256 | 257 | dt:target, .highlight { 258 | background: #FAF3E8; 259 | } 260 | 261 | div.warning { 262 | background-color: #FCC; 263 | border: 1px solid #FAA; 264 | } 265 | 266 | div.danger { 267 | background-color: #FCC; 268 | border: 1px solid #FAA; 269 | -moz-box-shadow: 2px 2px 4px #D52C2C; 270 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 271 | box-shadow: 2px 2px 4px #D52C2C; 272 | } 273 | 274 | div.error { 275 | background-color: #FCC; 276 | border: 1px solid #FAA; 277 | -moz-box-shadow: 2px 2px 4px #D52C2C; 278 | -webkit-box-shadow: 2px 2px 4px #D52C2C; 279 | box-shadow: 2px 2px 4px #D52C2C; 280 | } 281 | 282 | div.caution { 283 | background-color: #FCC; 284 | border: 1px solid #FAA; 285 | } 286 | 287 | div.attention { 288 | background-color: #FCC; 289 | border: 1px solid #FAA; 290 | } 291 | 292 | div.important { 293 | background-color: #EEE; 294 | border: 1px solid #CCC; 295 | } 296 | 297 | div.note { 298 | background-color: #EEE; 299 | border: 1px solid #CCC; 300 | } 301 | 302 | div.tip { 303 | background-color: #EEE; 304 | border: 1px solid #CCC; 305 | } 306 | 307 | div.hint { 308 | background-color: #EEE; 309 | border: 1px solid #CCC; 310 | } 311 | 312 | div.seealso { 313 | background-color: #EEE; 314 | border: 1px solid #CCC; 315 | } 316 | 317 | div.topic { 318 | background-color: #EEE; 319 | } 320 | 321 | p.admonition-title { 322 | display: inline; 323 | } 324 | 325 | p.admonition-title:after { 326 | content: ":"; 327 | } 328 | 329 | pre, tt, code { 330 | font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; 331 | font-size: 0.9em; 332 | } 333 | 334 | .hll { 335 | background-color: #FFC; 336 | margin: 0 -12px; 337 | padding: 0 12px; 338 | display: block; 339 | } 340 | 341 | img.screenshot { 342 | } 343 | 344 | tt.descname, tt.descclassname, code.descname, code.descclassname { 345 | font-size: 0.95em; 346 | } 347 | 348 | tt.descname, code.descname { 349 | padding-right: 0.08em; 350 | } 351 | 352 | img.screenshot { 353 | -moz-box-shadow: 2px 2px 4px #EEE; 354 | -webkit-box-shadow: 2px 2px 4px #EEE; 355 | box-shadow: 2px 2px 4px #EEE; 356 | } 357 | 358 | table.docutils { 359 | border: 1px solid #888; 360 | -moz-box-shadow: 2px 2px 4px #EEE; 361 | -webkit-box-shadow: 2px 2px 4px #EEE; 362 | box-shadow: 2px 2px 4px #EEE; 363 | } 364 | 365 | table.docutils td, table.docutils th { 366 | border: 1px solid #888; 367 | padding: 0.25em 0.7em; 368 | } 369 | 370 | table.field-list, table.footnote { 371 | border: none; 372 | -moz-box-shadow: none; 373 | -webkit-box-shadow: none; 374 | box-shadow: none; 375 | } 376 | 377 | table.footnote { 378 | margin: 15px 0; 379 | width: 100%; 380 | border: 1px solid #EEE; 381 | background: #FDFDFD; 382 | font-size: 0.9em; 383 | } 384 | 385 | table.footnote + table.footnote { 386 | margin-top: -15px; 387 | border-top: none; 388 | } 389 | 390 | table.field-list th { 391 | padding: 0 0.8em 0 0; 392 | } 393 | 394 | table.field-list td { 395 | padding: 0; 396 | } 397 | 398 | table.field-list p { 399 | margin-bottom: 0.8em; 400 | } 401 | 402 | /* Cloned from 403 | * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 404 | */ 405 | .field-name { 406 | -moz-hyphens: manual; 407 | -ms-hyphens: manual; 408 | -webkit-hyphens: manual; 409 | hyphens: manual; 410 | } 411 | 412 | table.footnote td.label { 413 | width: .1px; 414 | padding: 0.3em 0 0.3em 0.5em; 415 | } 416 | 417 | table.footnote td { 418 | padding: 0.3em 0.5em; 419 | } 420 | 421 | dl { 422 | margin: 0; 423 | padding: 0; 424 | } 425 | 426 | dl dd { 427 | margin-left: 30px; 428 | } 429 | 430 | blockquote { 431 | margin: 0 0 0 30px; 432 | padding: 0; 433 | } 434 | 435 | ul, ol { 436 | /* Matches the 30px from the narrow-screen "li > ul" selector below */ 437 | margin: 10px 0 10px 30px; 438 | padding: 0; 439 | } 440 | 441 | pre { 442 | background: #EEE; 443 | padding: 7px 30px; 444 | margin: 15px 0px; 445 | line-height: 1.3em; 446 | } 447 | 448 | div.viewcode-block:target { 449 | background: #ffd; 450 | } 451 | 452 | dl pre, blockquote pre, li pre { 453 | margin-left: 0; 454 | padding-left: 30px; 455 | } 456 | 457 | tt, code { 458 | background-color: #ecf0f3; 459 | color: #222; 460 | /* padding: 1px 2px; */ 461 | } 462 | 463 | tt.xref, code.xref, a tt { 464 | background-color: #FBFBFB; 465 | border-bottom: 1px solid #fff; 466 | } 467 | 468 | a.reference { 469 | text-decoration: none; 470 | border-bottom: 1px dotted #004B6B; 471 | } 472 | 473 | /* Don't put an underline on images */ 474 | a.image-reference, a.image-reference:hover { 475 | border-bottom: none; 476 | } 477 | 478 | a.reference:hover { 479 | border-bottom: 1px solid #6D4100; 480 | } 481 | 482 | a.footnote-reference { 483 | text-decoration: none; 484 | font-size: 0.7em; 485 | vertical-align: top; 486 | border-bottom: 1px dotted #004B6B; 487 | } 488 | 489 | a.footnote-reference:hover { 490 | border-bottom: 1px solid #6D4100; 491 | } 492 | 493 | a:hover tt, a:hover code { 494 | background: #EEE; 495 | } 496 | 497 | 498 | @media screen and (max-width: 870px) { 499 | 500 | div.sphinxsidebar { 501 | display: none; 502 | } 503 | 504 | div.document { 505 | width: 100%; 506 | 507 | } 508 | 509 | div.documentwrapper { 510 | margin-left: 0; 511 | margin-top: 0; 512 | margin-right: 0; 513 | margin-bottom: 0; 514 | } 515 | 516 | div.bodywrapper { 517 | margin-top: 0; 518 | margin-right: 0; 519 | margin-bottom: 0; 520 | margin-left: 0; 521 | } 522 | 523 | ul { 524 | margin-left: 0; 525 | } 526 | 527 | li > ul { 528 | /* Matches the 30px from the "ul, ol" selector above */ 529 | margin-left: 30px; 530 | } 531 | 532 | .document { 533 | width: auto; 534 | } 535 | 536 | .footer { 537 | width: auto; 538 | } 539 | 540 | .bodywrapper { 541 | margin: 0; 542 | } 543 | 544 | .footer { 545 | width: auto; 546 | } 547 | 548 | .github { 549 | display: none; 550 | } 551 | 552 | 553 | 554 | } 555 | 556 | 557 | 558 | @media screen and (max-width: 875px) { 559 | 560 | body { 561 | margin: 0; 562 | padding: 20px 30px; 563 | } 564 | 565 | div.documentwrapper { 566 | float: none; 567 | background: #fff; 568 | } 569 | 570 | div.sphinxsidebar { 571 | display: block; 572 | float: none; 573 | width: 102.5%; 574 | margin: 50px -30px -20px -30px; 575 | padding: 10px 20px; 576 | background: #333; 577 | color: #FFF; 578 | } 579 | 580 | div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, 581 | div.sphinxsidebar h3 a { 582 | color: #fff; 583 | } 584 | 585 | div.sphinxsidebar a { 586 | color: #AAA; 587 | } 588 | 589 | div.sphinxsidebar p.logo { 590 | display: none; 591 | } 592 | 593 | div.document { 594 | width: 100%; 595 | margin: 0; 596 | } 597 | 598 | div.footer { 599 | display: none; 600 | } 601 | 602 | div.bodywrapper { 603 | margin: 0; 604 | } 605 | 606 | div.body { 607 | min-height: 0; 608 | padding: 0; 609 | } 610 | 611 | .rtd_doc_footer { 612 | display: none; 613 | } 614 | 615 | .document { 616 | width: auto; 617 | } 618 | 619 | .footer { 620 | width: auto; 621 | } 622 | 623 | .footer { 624 | width: auto; 625 | } 626 | 627 | .github { 628 | display: none; 629 | } 630 | } 631 | 632 | 633 | /* misc. */ 634 | 635 | .revsys-inline { 636 | display: none!important; 637 | } 638 | 639 | /* Make nested-list/multi-paragraph items look better in Releases changelog 640 | * pages. Without this, docutils' magical list fuckery causes inconsistent 641 | * formatting between different release sub-lists. 642 | */ 643 | div#changelog > div.section > ul > li > p:only-child { 644 | margin-bottom: 0; 645 | } 646 | 647 | /* Hide fugly table cell borders in ..bibliography:: directive output */ 648 | table.docutils.citation, table.docutils.citation td, table.docutils.citation th { 649 | border: none; 650 | /* Below needed in some edge cases; if not applied, bottom shadows appear */ 651 | -moz-box-shadow: none; 652 | -webkit-box-shadow: none; 653 | box-shadow: none; 654 | } 655 | 656 | 657 | /* relbar */ 658 | 659 | .related { 660 | line-height: 30px; 661 | width: 100%; 662 | font-size: 0.9rem; 663 | } 664 | 665 | .related.top { 666 | border-bottom: 1px solid #EEE; 667 | margin-bottom: 20px; 668 | } 669 | 670 | .related.bottom { 671 | border-top: 1px solid #EEE; 672 | } 673 | 674 | .related ul { 675 | padding: 0; 676 | margin: 0; 677 | list-style: none; 678 | } 679 | 680 | .related li { 681 | display: inline; 682 | } 683 | 684 | nav#rellinks { 685 | float: right; 686 | } 687 | 688 | nav#rellinks li+li:before { 689 | content: "|"; 690 | } 691 | 692 | nav#breadcrumbs li+li:before { 693 | content: "\00BB"; 694 | } 695 | 696 | /* Hide certain items when printing */ 697 | @media print { 698 | div.related { 699 | display: none; 700 | } 701 | } --------------------------------------------------------------------------------