diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index c02bbd9..0c0f6f7 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,9 +5,9 @@ name: Qutes Build and Tests on: push: - branches: [ "main" ] + branches: [ "main", "development" ] pull_request: - branches: [ "main" ] + branches: [ "main", "development" ] permissions: contents: read @@ -29,6 +29,6 @@ jobs: - name: Test with pytest run: | cd src - python -m pytest tests/ + python -m pytest tests/ # Better CLI output than unittest # python -m unittest discover -s ./test -p 'test*.py' # python -m unittest tests.grammar_test diff --git a/playground/examples/grover_search.qut b/playground/examples/grover_search.qut new file mode 100644 index 0000000..b02c20e --- /dev/null +++ b/playground/examples/grover_search.qut @@ -0,0 +1,27 @@ +// qustring a = "0*00"; + +qustring c = "00000011"; +if("1" is c){ + print "Exact Match Found!"; +} +else{ + print "Exact Match Not Found"; +} + + + +// quint a = [0q, 0q, 0q, 0q, 0q, 0q, [0,1]q, [0,1]q]; +// qustring b = "1110111"; +// if("11" is a){ +// print "Exact Match Found!"; +// } +// else{ +// print "Exact Match Not Found"; +// } + +// if("01" in b){ +// print "Substring Match Found!"; +// } +// else{ +// print "Substring Match Not Found"; +// } \ No newline at end of file diff --git a/playground/examples/quantum_key_distribution_bb84.qut b/playground/examples/quantum_key_distribution_bb84.qut new file mode 100644 index 0000000..8cef717 --- /dev/null +++ b/playground/examples/quantum_key_distribution_bb84.qut @@ -0,0 +1,212 @@ +int n = 8; //number of qubits + +//Alice create a random binary sequence +string message_0 = "1"; +string message_1 = "0"; +string message_2 = "1"; +string message_3 = "0"; +string message_4 = "0"; +string message_5 = "1"; +string message_6 = "0"; +string message_7 = "1"; + +//Alice create a random binary sequence of basis +string alice_bases0 = "1"; +string alice_bases1 = "1"; +string alice_bases2 = "0"; +string alice_bases3 = "0"; +string alice_bases4 = "0"; +string alice_bases5 = "1"; +string alice_bases6 = "1"; +string alice_bases7 = "1"; + +//Alice encodes the message with the basis +//for each character in message, if the corresponding character in bases is 0, then encode the character in Z basis, otherwise in X basis +qubit alice_0 = 1q; +qubit alice_1 = 0q; +qubit alice_2 = 1q; +qubit alice_3 = 0q; +qubit alice_4 = 0q; +qubit alice_5 = 1q; +qubit alice_6 = 0q; +qubit alice_7 = 1q; + +//Bob create a random binary sequence of basis +string bob_bases0 = "1"; +string bob_bases1 = "0"; +string bob_bases2 = "1"; +string bob_bases3 = "0"; +string bob_bases4 = "1"; +string bob_bases5 = "0"; +string bob_bases6 = "1"; +string bob_bases7 = "0"; + + +if (alice_bases0 == "0"){ + //encode message_1 in Z basis + //do nothing. +} else { + //encode message_0 in X basis + hadamard alice_0; +} +if (alice_bases1 == "0"){ + //encode message_1 in Z basis + //do nothing. +} else { + //encode message_1 in X basis + hadamard alice_1; +} +if (alice_bases2 == "0"){ + //encode message_2 in Z basis + //do nothing. +} else { + //encode message_2 in X basis + hadamard alice_2; +} +if (alice_bases3 == "0"){ + //encode message_3 in Z basis + //do nothing. +} else { + //encode message_3 in X basis + hadamard alice_3; +} +if (alice_bases4 == "0"){ + //encode message_4 in Z basis + //do nothing. +} else { + //encode message_4 in X basis + hadamard alice_4; +} +if (alice_bases5 == "0"){ + //encode message_5 in Z basis + //do nothing. +} else { + //encode message_5 in X basis + hadamard alice_5; +} +if (alice_bases6 == "0"){ + //encode message_6 in Z basis + //do nothing. +} else { + //encode message_6 in X basis + hadamard alice_6; +} +if (alice_bases7 == "0"){ + //encode message_7 in Z basis + //do nothing. +} else { + //encode message_7 in X basis + hadamard alice_7; +} + + +//Alice sends the encoded message to Bob + + + + + +if (bob_bases0 == "0"){ + //encode message_1 in Z basis + //do nothing. +} else { + //encode message_0 in X basis + hadamard alice_0; +} + +if (bob_bases1 == "0"){ + //encode message_1 in Z basis + //do nothing. +} else { + //encode message_1 in X basis + hadamard alice_1; +} +if (bob_bases2 == "0"){ + //encode message_2 in Z basis + //do nothing. +} else { + //encode message_2 in X basis + hadamard alice_2; +} +if (bob_bases3 == "0"){ + //encode message_3 in Z basis + //do nothing. +} else { + //encode message_3 in X basis + hadamard alice_3; +} +if (bob_bases4 == "0"){ + //encode message_4 in Z basis + //do nothing. +} else { + //encode message_4 in X basis + hadamard alice_4; +} +if (bob_bases5 == "0"){ + //encode message_5 in Z basis + //do nothing. +} else { + //encode message_5 in X basis + hadamard alice_5; +} +if (bob_bases6 == "0"){ + //encode message_6 in Z basis + //do nothing. +} else { + //encode message_6 in X basis + hadamard alice_6; +} +if (bob_bases7 == "0"){ + //encode message_7 in Z basis + //do nothing. +} else { + //encode message_7 in X basis + hadamard alice_7; +} + + + + + +if(bob_bases0 == alice_bases0){ + print "Index 0 match so it can be used to create a key"; + print alice_0; + print message_0; +} +if(bob_bases1 == alice_bases1){ + print "Index 1 match so it can be used to create a key"; + print alice_1; + print message_1; +} +if(bob_bases2 == alice_bases2){ + print "Index 2 match so it can be used to create a key"; + print alice_2; + print message_2; +} +if(bob_bases3 == alice_bases3){ + print "Index 3 match so it can be used to create a key"; + print alice_3; + print message_3; +} +if(bob_bases4 == alice_bases4){ + print "Index 4 match so it can be used to create a key"; + print alice_4; + print message_4; +} +if(bob_bases5 == alice_bases5){ + print "Index 5 match so it can be used to create a key"; + print alice_5; + print message_5; +} +if(bob_bases6 == alice_bases6){ + print "Index 6 match so it can be used to create a key"; + print alice_6; + print message_6; +} +if(bob_bases7 == alice_bases7){ + print "Index 7 match so it can be used to create a key"; + print alice_7; + print message_7; +} + +print "If the above values matches, then no one is eyesdropping."; \ No newline at end of file diff --git a/playground/examples/quantum_teleportation.qut b/playground/examples/quantum_teleportation.qut new file mode 100644 index 0000000..57d8dc0 --- /dev/null +++ b/playground/examples/quantum_teleportation.qut @@ -0,0 +1,75 @@ +//qubit a = 0.7,0.3q; +qubit a = 0q; +//measure a; + +qubit bell1 = 0q; +qubit bell2 = 0q; + +//Provider +hadamard bell1; +mcx bell1, bell2; + +//Alice +mcx a, bell1; +hadamard a; +// measure a; +// measure bell1; + +//Bob +bool do_z = a; +bool do_x = bell1; +if(do_x){ + not bell2; +} +if(do_z){ + pauliz bell2; +} + +measure bell2; + + +print "Initial Message:"; +print a; +print "Teleported Message:"; +print bell2; + + + +//TODO: There is some error when multiple functions are declared +// qubit aliceMessage = 0q; + +// qubit bell1 = 0q; +// qubit bell2 = 0q; + +// initBellPairs(bell1, bell2); + +// //Alice +// aliceEncoding(bell1); + +// //Bob +// bool do_z = aliceMessage; +// bool do_x = bell1; +// bobDecoding(do_z, do_x); + + + +// void initBellPairs(qubit a, qubit b){ +// hadamard a; +// mcx a, b; +// } + +// void aliceEncoding(qubit alice_bell){ +// mcx aliceMessage, alice_bell; +// hadamard aliceMessage; +// } + +// void bobDecoding(bool do_z, bool do_x){ +// if(do_x){ +// not bell2; +// } +// if(do_z){ +// pauliz bell2; +// } + +// measure bell2; +// } \ No newline at end of file diff --git a/playground/examples/superdense_coding.qut b/playground/examples/superdense_coding.qut new file mode 100644 index 0000000..51fd275 --- /dev/null +++ b/playground/examples/superdense_coding.qut @@ -0,0 +1,44 @@ +//Provider +qubit bell1; +qubit bell2; + +hadamard bell2; +mcx bell2, bell1; +// - Send bell2 to Alice and Bell1 to Bob + +//Alice +qustring qu_message = "**"; +string message = qu_message; + +if(message == "00"){ + //do nothing +} +else if(message == "01"){ + pauliz bell2; +} +else if(message == "10"){ + not bell2; +} +else if(message == "11"){ + pauliz bell2; + not bell2; +} + +// - Send transformed bell2 to Bob + + +//Bob +mcx bell2, bell1; +hadamard bell2; + + +bool received_bit1 = bell1; +bool received_bit2 = bell2; + +print "Messaggio Inviato: "; +print message; +print "Messaggio Ricevuto: "; +//TODO: Here we print always the first message because the circuit is created upon that. +// We should run Qutes 'runs' times or create the circuit with Qiskit if statements upon classical registers. +print received_bit1; +print received_bit2; \ No newline at end of file diff --git a/playground/examples/test.qut b/playground/examples/test.qut new file mode 100644 index 0000000..a9eb854 --- /dev/null +++ b/playground/examples/test.qut @@ -0,0 +1,4 @@ +qubit a = 0q; +bool b = a; + +print b; \ No newline at end of file diff --git a/qutes-vscode/extension.js b/qutes-vscode/extension.js new file mode 100644 index 0000000..47a5dc3 --- /dev/null +++ b/qutes-vscode/extension.js @@ -0,0 +1,45 @@ +// The module 'vscode' contains the VS Code extensibility API +// Import the module and reference it with the alias vscode in your code below +const vscode = require('vscode'); + +// this method is called when your extension is activated +// your extension is activated the very first time the command is executed + +/** + * @param {vscode.ExtensionContext} context + */ +function activate(context) { + let disposable = vscode.commands.registerCommand('qutes.runQutesFile', function () { + let activeEditor = vscode.window.activeTextEditor; + if (!activeEditor || activeEditor.document.languageId !== 'qutes') { + return; // no active editor or the active file is not a Qutes file + } + + let filePath = activeEditor.document.uri.fsPath; + + // Define a debug configuration + let debugConfiguration = { + name: "Run Qutes File", + type: "debugpy", + request: "launch", + program: "src/qutes.py", + console: "integratedTerminal", + args: ["-image","-circuit","-iter","1",filePath], + justMyCode: true + + }; + + // Start debugging with the defined configuration + vscode.debug.startDebugging(undefined, debugConfiguration); + }); + context.subscriptions.push(disposable); +} + +// this method is called when your extension is deactivated +function deactivate() {} + +// eslint-disable-next-line no-undef +module.exports = { + activate, + deactivate +} \ No newline at end of file diff --git a/qutes-vscode/grammar_tests.qut b/qutes-vscode/grammar_tests.qut index 7a8d5a3..0d58425 100644 --- a/qutes-vscode/grammar_tests.qut +++ b/qutes-vscode/grammar_tests.qut @@ -119,11 +119,14 @@ //Grover { - qustring a = "1110111"; - if("0" in a){ - print "Trovato!"; + // qustring a = "0*00"; + // quint a = [0q, 0q, 0q, 0q, 0q, 0q, [0,1]q, [0,1]q]; + qustring b = "1110111"; + + if("01" in b){ + print "Substring Match Found!"; } else{ - print "Non Trovato"; + print "Substring Match Not Found"; } } \ No newline at end of file diff --git a/qutes-vscode/package.json b/qutes-vscode/package.json index 0c294fe..cfcd6bc 100644 --- a/qutes-vscode/package.json +++ b/qutes-vscode/package.json @@ -5,7 +5,7 @@ "author": "Gabriele Messina", "publisher": "GabrieleMessina", "license": "MIT", - "version": "1.0.6", + "version": "1.1.0", "engines": { "vscode": "^1.52.0" }, @@ -17,6 +17,7 @@ "categories": [ "Programming Languages" ], + "main": "./extension.js", "contributes": { "languages": [ { @@ -37,9 +38,26 @@ "scopeName": "source.qutes", "path": "./syntaxes/qutes.tmLanguage.json" } - ] + ], + "commands": [ + { + "command": "qutes.runQutesFile", + "title": "Run Qutes File" + } + ], + "menus": { + "editor/title": [ + { + "command": "qutes.runQutesFile", + "group": "navigation", + "when": "resourceLangId == qutes" + } + ] + } }, - "devDependencies": { + "scripts": {}, + "devDependencies": { + "@types/vscode": "^1.73.0", "@vscode/vsce": "^2.24.0" - } -} + } +} \ No newline at end of file diff --git a/qutes-vscode/syntaxes/qutes.tmLanguage.json b/qutes-vscode/syntaxes/qutes.tmLanguage.json index 1def310..5788184 100644 --- a/qutes-vscode/syntaxes/qutes.tmLanguage.json +++ b/qutes-vscode/syntaxes/qutes.tmLanguage.json @@ -9,7 +9,7 @@ }, { "name": "keyword.operator.qutes", - "match": "(\\+|\\-|==|>|>=|<|<=|=)|\\b(not|pauliy|pauliz|grover|mcz|hadamard|measure|print|barrier)\\b" + "match": "(\\+|\\-|==|>|>=|<|<=|=)|\\b(not|pauliy|pauliz|grover|mcz|mcx|hadamard|measure|print|barrier)\\b" }, { "name": "storage.type.qutes", diff --git a/qutes.code-workspace b/qutes.code-workspace index 0bf9096..04280d7 100644 --- a/qutes.code-workspace +++ b/qutes.code-workspace @@ -16,15 +16,14 @@ "Antlr" ], "pylint.importStrategy": "fromEnvironment", + "python.testing.cwd": "./src", "python.testing.unittestArgs": [ "-v", - "-s", - "./src", "-p", "test*.py" ], - "python.testing.pytestEnabled": false, - "python.testing.unittestEnabled": true, + "python.testing.pytestEnabled": false, + "python.testing.unittestEnabled": true, "python.testing.autoTestDiscoverOnSaveEnabled": true, }, "extensions": { @@ -39,14 +38,59 @@ "version": "0.2.0", "configurations": [ { - "name": "Python: Run Qutes with test source code", - "type": "python", + "name": "Qutes: Run test source code", + "type": "debugpy", "request": "launch", "program": "src/qutes.py", "console": "integratedTerminal", - "args": ["-image","-circuit","./specification/grammar/grammar_tests.qut"], + "args": ["-image","-circuit","-iter","1","./specification/grammar/grammar_tests.qut"], "justMyCode": true - } + }, + { + "name": "Qutes: Run Test example", + "type": "debugpy", + "request": "launch", + "program": "src/qutes.py", + "console": "integratedTerminal", + "args": ["-image","-circuit","-iter","100","./playground/examples/test.qut"], + "justMyCode": true + }, + { + "name": "Qutes: Run Superdense Coding example", + "type": "debugpy", + "request": "launch", + "program": "src/qutes.py", + "console": "integratedTerminal", + "args": ["-image","-circuit","-iter","100","./playground/examples/superdense_coding.qut"], + "justMyCode": true + }, + { + "name": "Qutes: Run Grover Search example", + "type": "debugpy", + "request": "launch", + "program": "src/qutes.py", + "console": "integratedTerminal", + "args": ["-image","-iter","1","./playground/examples/grover_search.qut"], + "justMyCode": true + }, + { + "name": "Qutes: Run Quantum Teleportation example [WIP]", + "type": "debugpy", + "request": "launch", + "program": "src/qutes.py", + "console": "integratedTerminal", + "args": ["-image","-circuit","-iter","1","./playground/examples/quantum_teleportation.qut"], + "justMyCode": true + }, + { + "name": "Qutes: Run Quantum key Distribution BB84 example", + "type": "debugpy", + "request": "launch", + "program": "src/qutes.py", + "console": "integratedTerminal", + "args": ["-image","-circuit","-iter","1","./playground/examples/quantum_key_distribution_bb84.qut"], + "justMyCode": true + }, ] } } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a1078a3..7b53506 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ qiskit<1.0 qiskit-aer anytree matplotlib -parameterized ipywidgets -pylatexenc \ No newline at end of file +pylatexenc +tabulate \ No newline at end of file diff --git a/specification/grammar/grammar_tests.qut b/specification/grammar/grammar_tests.qut index 5c27ea3..dfd39b1 100644 --- a/specification/grammar/grammar_tests.qut +++ b/specification/grammar/grammar_tests.qut @@ -374,22 +374,14 @@ //Grover III - SubArray Match { - //quint a = [[0,1]q, [0,1]q, [0,1]q, [0,1]q]; - //search 4 in a; - - //qustring a = "0100"; - //search "1" in a; + // qustring a = "0*00"; + quint a = [0q, 0q, 0q, 0q, 0q, 0q, [0,1]q, [0,1]q]; + // qustring b = "1110111"; - //qustring a = "0*00"; - //quint a = [0q, 0q, [0,1]q, [0,1]q, 0q, 0q, 0q, 0q]; - //search "1" in a; - - qustring a = "1110111"; - // qustring a = "0111110"; - if("0" in a){ - print "Trovato!"; + if("01" in b){ + print "Substring Match Found!"; } else{ - print "Non Trovato"; + print "Substring Match Not Found"; } } \ No newline at end of file diff --git a/specification/grammar/qutes_lexer.g4 b/specification/grammar/qutes_lexer.g4 index 93538c9..0d0e47b 100644 --- a/specification/grammar/qutes_lexer.g4 +++ b/specification/grammar/qutes_lexer.g4 @@ -21,6 +21,7 @@ PAULIY : 'pauliy' ; PAULIZ : 'pauliz' ; GROVER : 'grover' ; MCZ : 'mcz' ; +MCX : 'mcx' ; HADAMARD : 'hadamard' ; MEASURE : 'measure' ; PRINT : 'print' ; @@ -127,7 +128,7 @@ QUSTRING_LITERAL SYMBOL_LITERAL - : [a-z0-9]+ //TODO: [A-Za-z_][A-Za-z0-9_]* + : [a-z_][a-z0-9_]* ; STRING_LITERAL diff --git a/specification/grammar/qutes_parser.g4 b/specification/grammar/qutes_parser.g4 index 54089e4..68bcf48 100644 --- a/specification/grammar/qutes_parser.g4 +++ b/specification/grammar/qutes_parser.g4 @@ -70,7 +70,7 @@ test term : term op=(ADD | SUB) term #BinaryOperator | op=(PRINT | NOT | PAULIY | PAULIZ | HADAMARD | MEASURE | ADD | SUB) term #UnaryOperator - | op=MCZ termList #MultipleUnaryOperator + | op=(MCX | MCZ) termList #MultipleUnaryOperator | (boolean | integer | float diff --git a/src/grammar_frontend/qutes_grammar_visitor.py b/src/grammar_frontend/qutes_grammar_visitor.py index 947684b..3494af9 100644 --- a/src/grammar_frontend/qutes_grammar_visitor.py +++ b/src/grammar_frontend/qutes_grammar_visitor.py @@ -367,10 +367,12 @@ def visitMultipleUnaryOperator(self, ctx:qutesParser.MultipleUnaryOperatorContex return self.__visit("visitMultipleUnaryOperator", lambda : self.__visitMultipleUnaryOperator(ctx)) def __visitMultipleUnaryOperator(self, ctx:qutesParser.MultipleUnaryOperatorContext): + terms:list[Symbol] = self.visit(ctx.termList()) + registers = [register.quantum_register for register in terms] if(ctx.MCZ()): - terms:list[Symbol] = self.visit(ctx.termList()) - registers = [register.quantum_register for register in terms] self.quantum_circuit_handler.push_MCZ_operation(registers) + if(ctx.MCX()): + self.quantum_circuit_handler.push_MCX_operation(registers) # Visit a parse tree produced by qutes_parser#termList. def visitTermList(self, ctx:qutesParser.TermListContext): @@ -447,14 +449,13 @@ def __visitGroverOperator(self, ctx:qutesParser.GroverExprContext): oracle_result = self.quantum_circuit_handler.push_grover_operation(*oracle_registers, quantum_function=quantum_function, register_involved_indexes=qubits_involved_in_grover, dataset_size=array_size, n_results=n_results, verbose=self.log_grover_verbose) registers_to_measure.append(oracle_result) circuit_runs = 3 - results = self.quantum_circuit_handler.get_run_and_measure_results(registers_to_measure, repetition=circuit_runs) - - positive_results = [result for result in results if result[0].split(" ")[0] == "1"] - if (len(positive_results) > 0): - results_counts = sum([result[1] for result in positive_results]) - print(f"Solution found with probability {results_counts}/{circuit_runs}") - if(len(positive_results[0][0].split(" ")) > 1): - print(f"and rotation: {positive_results[0][0].split(' ')[1]} (for the first hit)") + self.quantum_circuit_handler.get_run_and_measure_results(registers_to_measure.copy(), repetition=circuit_runs) + + positive_results = [(index, result) for index, result in enumerate(oracle_result.measured_classical_register.measured_values) if "1" in result] + any_positive_results = len(positive_results) > 0 + if (any_positive_results): + if(self.log_grover_verbose and rotation_register.measured_classical_register is not None): + print(f"Solution found with rotation {rotation_register.measured_classical_register.measured_values[positive_results[0].index]} (for the first hit)") return True registers_to_measure.remove(oracle_result) return False diff --git a/src/grammar_frontend/qutes_syntax_error_listener.py b/src/grammar_frontend/qutes_syntax_error_listener.py new file mode 100644 index 0000000..2636970 --- /dev/null +++ b/src/grammar_frontend/qutes_syntax_error_listener.py @@ -0,0 +1,17 @@ +from antlr4.error.ErrorListener import ConsoleErrorListener as ErrorListenerToExtend + +class QutesErrorListener(ErrorListenerToExtend): + def __init__(self): + super().__init__() + + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + raise SyntaxError("Syntax error at" + " line: " + str(line) + ", column: " + str(column) + ((", unexpected symbol: " + offendingSymbol.text) if offendingSymbol is not None else "") + ". " + msg) from e + + def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs): + pass #Not an error, just a trace + + def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs): + pass #Not an error, just a trace + + def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs): + pass #Not an error, just a trace \ No newline at end of file diff --git a/src/quantum_circuit/quantum_circuit_handler.py b/src/quantum_circuit/quantum_circuit_handler.py index 9673be1..40a769e 100644 --- a/src/quantum_circuit/quantum_circuit_handler.py +++ b/src/quantum_circuit/quantum_circuit_handler.py @@ -41,7 +41,7 @@ def delete_classical_register(self, variable_name : str) -> None: def declare_quantum_register(self, variable_name : str, quantum_variable : any) -> QuantumRegister: new_register = None - new_register = QuantumRegister(quantum_variable.size, variable_name, quantum_variable) + new_register = QuantumRegister(quantum_variable.size, variable_name) if(new_register is None): raise SystemError("Error trying to declare a quantum variable of unsupported type") @@ -65,7 +65,7 @@ def replace_quantum_register(self, variable_name : str, quantum_variable : any) del self._registers_states[register_to_update] self._quantum_registers.remove(register_to_update) #Add new quantum register - register_to_update = self._varname_to_register[variable_name] = QuantumRegister(quantum_variable.size, variable_name, quantum_variable) + register_to_update = self._varname_to_register[variable_name] = QuantumRegister(quantum_variable.size, variable_name) self._quantum_registers.append(register_to_update) self._registers_states[register_to_update] = quantum_variable.get_quantum_state() @@ -139,7 +139,7 @@ def __revcounts__(self, vec): print(" - " + str(i)[::-1] +" : "+ str(vec[i])) # simulate the execution of a Quantum Circuit and get the results - def __run__(self, circuit, shots): + def __run__(self, circuit, shots, print_counts:bool = False): # Use Aer's qasm_simulator simulator = Aer.get_backend('aer_simulator') @@ -162,54 +162,50 @@ def __run__(self, circuit, shots): raise er if(cnt != None): - sorted(cnt.items(), key=lambda item: item[1], reverse=True) - measurement_for_runs = [res.split(" ") for res in cnt.keys()] - counts_for_runs = [res for res in cnt.items()] - + table = [] + for run in cnt: + count = cnt[run] + values = run.split(" ")[::-1] + values.append(count) + table.append(values) + + if(print_counts): + from tabulate import tabulate + print(tabulate(table, headers=[f"{creg[0]}[{creg[1]}]" for creg in cnt.creg_sizes] + ["count"])) + + measurement_for_runs = [res.split(" ")[::-1] for res in cnt.keys()] + counts_for_runs = [res[1] for res in cnt.items()] for index in range(len(cnt.creg_sizes)): measurement_for_variable = [a[index] for a in measurement_for_runs] - counts_for_variable = [a[1] for a in counts_for_runs] Classical_registers = [reg for reg in self._classic_registers if reg.name == cnt.creg_sizes[index][0]] Classical_registers[0].measured_values = measurement_for_variable - Classical_registers[0].measured_counts = counts_for_variable + Classical_registers[0].measured_counts = counts_for_runs return cnt - def run_circuit(self, circuit:QuantumCircuit, repetition:int = 1, max_results = 1) -> list[str]: - cnt:dict = self.__run__(circuit, repetition) - if(cnt == None): - return None - - self.__counts__(cnt) - - result_with_max_count = sorted(cnt.items(), key=lambda item: item[1], reverse=True) - return result_with_max_count[:max_results] - - def run_and_measure(self, quantum_registers : list[QuantumRegister] = None, classical_registers : list[ClassicalRegister] = None, repetition = 100, max_results = 2) -> list[ClassicalRegister]: - classical_registers = self.push_measure_operation(quantum_registers, classical_registers) - result = self.run_circuit(self.create_circuit(), repetition, max_results) - self._current_operation_stack.pop() - return classical_registers + def run_circuit(self, circuit:QuantumCircuit, repetition:int = 1, print_count:bool = False): + self.__run__(circuit, repetition, print_count) - def get_run_and_measure_results(self, quantum_registers : list[QuantumRegister] = None, classical_registers : list[ClassicalRegister] = None, repetition = 100, max_results = 2) -> list[ClassicalRegister]: + def get_run_and_measure_results(self, quantum_registers : list[QuantumRegister] = None, classical_registers : list[ClassicalRegister] = None, repetition = 1, max_results = None, print_count:bool = False) -> tuple[list[str], list[ClassicalRegister]]: + quantum_registers = quantum_registers or self._quantum_registers classical_registers = self.push_measure_operation(quantum_registers, classical_registers) - result = self.run_circuit(self.create_circuit(), repetition, max_results) - self._current_operation_stack.pop() - return result + self.run_circuit(self.create_circuit(), repetition, print_count) + # self._current_operation_stack.pop() - def run_circuit_result(self, circuit:QuantumCircuit, repetition:int = 1, max_results = 100) -> list[str]: - # Use Aer's qasm_simulator - simulator = Aer.get_backend('aer_simulator') + for creg in classical_registers: + [qreg for qreg in quantum_registers if qreg.name in creg.name][0].measured_classical_register = creg - # compile the circuit down to low-level QASM instructions - # supported by the backend (not needed for simple circuits) - compiled_circuit = transpile(circuit, simulator) + results = [reg.measured_values for reg in classical_registers] + if(max_results is not None): + results = results[:max_results] + return (results, classical_registers) - # Execute the circuit on the qasm simulator - job = Sampler().run(compiled_circuit, shots=repetition) - - # Grab results from the job - result = job.result() - return result + def run_and_measure(self, quantum_registers : list[QuantumRegister] = None, classical_registers : list[ClassicalRegister] = None, repetition = 1, max_results = 1, print_count:bool = False) -> list[ClassicalRegister]: + (_, classical_registers) = self.get_run_and_measure_results(quantum_registers, classical_registers, repetition, max_results, print_count) + return classical_registers + + def get_run_and_measure_result_for_quantum_var(self, quantum_register : QuantumRegister, classical_register : ClassicalRegister = None, repetition = 1, max_results = 1, print_count:bool = False) -> tuple[str, ClassicalRegister]: + (_, classical_register) = self.get_run_and_measure_results([quantum_register], [classical_register] if classical_register != None else None, repetition, max_results, print_count) + return (classical_register[0].measured_values[0], classical_register[0]) def push_not_operation(self, quantum_register : QuantumRegister) -> None: self._current_operation_stack.append(lambda circuit : cast(QuantumCircuit, circuit).x(quantum_register)) @@ -325,7 +321,8 @@ def push_grover_operation(self, *oracle_registers, quantum_function:QuantumCircu n_iteration = math.floor( (math.pi / 4) * math.sqrt(dataset_size / n_results) ) - print(f"Grover iterations: {n_iteration}") + if(verbose): + print(f"Grover iterations: {n_iteration}") self.push_compose_circuit_operation(grover_op.power(n_iteration), oracle_registers) @@ -342,41 +339,4 @@ def push_grover_operation(self, *oracle_registers, quantum_function:QuantumCircu # check if the grover result is actually a hit. oracle_result = self.declare_quantum_register(f"oracle_phase_ancilla_{current_grover_count}", Qubit()) self.push_compose_circuit_operation(boolean_quantum_function, [*oracle_registers[:-1],oracle_result]) - return oracle_result - - def phase_estimation(self, quantum_function:QuantumCircuit, input_preparation:QuantumCircuit = None, precision = 3) -> float: - m = precision # Number of control qubits - n = quantum_function.num_qubits # Number of qubits the oracle works on. - - control_register = QuantumRegister(m, "Control", None) - target_register = QuantumRegister(n, "|ψ>", None) - output_register = ClassicalRegister(m, "Result", None) - qc = QuantumCircuit(control_register, target_register, output_register) - - # Prepare the eigenvector |ψ> - # qc.compose(input_preparation, target_register, inplace=True) - qc.h(target_register) - qc.barrier() - - # Perform phase estimation - for index, qubit in enumerate(control_register): - qc.h(qubit) - for _ in range(2**index): - qc.compose(quantum_function.control(num_ctrl_qubits=1), [qubit, *target_register], inplace=True) - qc.barrier() - - # Do inverse quantum Fourier transform - qc.compose(QFT(m, inverse=True), control_register, inplace=True) - - # Measure everything - qc.measure(control_register, output_register) - #self.print_circuit(qc) - result:dict = self.run_circuit_result(qc, 1000, 200).quasi_dists[0] - - thetas = sorted([((2*_result)/2**m)*math.pi for _result in result.keys()]) - - most_probable = max(result, key=result.get) - print(f"Most probable output: {most_probable}") - print(f"output: {result}") - print(f"Estimated theta: {thetas}") - return thetas + return oracle_result \ No newline at end of file diff --git a/src/quantum_circuit/quantum_register.py b/src/quantum_circuit/quantum_register.py index 0ae0b15..ba31f43 100644 --- a/src/quantum_circuit/quantum_register.py +++ b/src/quantum_circuit/quantum_register.py @@ -1,9 +1,10 @@ from qiskit import QuantumRegister as qr +from quantum_circuit.classical_register import ClassicalRegister class QuantumRegister(qr): - def __init__(self, size, var_name, value, bits = None): + def __init__(self, size, var_name, bits = None): super().__init__(size, var_name, bits) - self.value = value + self.measured_classical_register:ClassicalRegister | None = None def __len__(self): return self.size diff --git a/src/quantum_circuit/qutes_gates.py b/src/quantum_circuit/qutes_gates.py index f13ea1e..7c1d829 100644 --- a/src/quantum_circuit/qutes_gates.py +++ b/src/quantum_circuit/qutes_gates.py @@ -73,144 +73,6 @@ def sum(self, var_a_symbol:'Symbol', var_b_symbol:'Symbol') -> 'Symbol': return result_symbol - - def ESM_Search(self,x,y): - n = len(y) - m = len(x) - logn = int(math.log2(n)) - - kr = QuantumRegister(logn, 'k', None) - xr = QuantumRegister(m, 'x', None) - yr = QuantumRegister(n, 'y', None) - out = QuantumRegister(1, 'out', None) - cr = ClassicalRegister(logn,'c') - # cr = ClassicalRegister(1,'c') - qc = QuantumCircuit(kr, xr,yr,out, cr) - - qc.h(kr) - qc.x(out) - qc.h(out) - - oracle = self.ESM_Oracle(x, y) - grover_op = GroverOperator(oracle) - - n_results = 1 - n_iteration = math.floor( - math.pi / (4 * math.asin(math.sqrt(n_results / 2**grover_op.num_qubits))) - ) - print(f"Grover iterations: {n_iteration}") - - qc.compose(grover_op.power(n_iteration), inplace=True) - - qc.measure(out,cr) - #qc.measure(kr,cr) - self.ciruit_handler.print_circuit(grover_op.decompose()) - self.ciruit_handler.print_circuit(qc) - res = self.ciruit_handler.__run__(qc,1000) - self.ciruit_handler.__revcounts__(res) - - def Create_ESM_Oracle(self,len_array, to_match:Qustring): - n = len_array - m = len(to_match.qubit_state) - logn = int(math.log2(n)) - - kr = QuantumRegister(logn, 'k', None) - xr = QuantumRegister(m, 'x', None) - yr = QuantumRegister(n, 'y', None) - out = QuantumRegister(1, 'out', None) - #cr = ClassicalRegister(1,'c') - qc = QuantumCircuit(kr,xr,yr,out) - - # initialize to_match - for i in range(m): - if (to_match.qubit_state[i].alpha == 0 and to_match.qubit_state[i].beta == 1): - qc.x(xr[i]) - - # rotate y - for i in range(logn): - qc = qc.compose(QutesGates.crot(n,2**i,1), [kr[i]]+yr[:] ) - # compare x and y[:m] - for i in range(m): - qc.cx(xr[i],yr[i]) - qc.x(yr[i]) - uncompute = qc.reverse_ops() - qc.mcx(yr[:m],out) - - #uncompute - # qc.compose(uncompute, inplace=True) - for i in range(m): - qc.x(yr[i]) - qc.cx(xr[i],yr[i]) - for i in range(logn): - qc = qc.compose(QutesGates.crot(n,2**i,1).inverse(), [kr[i]]+yr[:] ) - - #qc.measure(out,cr) - #self.ciruit_handler.print_circuit(qc) - #res = self.ciruit_handler.__run__(qc,1000) - #self.ciruit_handler.__revcounts__(res) - #qc = qc.to_gate(label='ESM') - return qc - - # performs exact string matching - # checkf if x (length m) rotated by k pos. is equal to y[0..m-1] - def ESM_Oracle(self,x,y): - n = len(y) - m = len(x) - logn = int(math.log2(n)) - - kr = QuantumRegister(logn, 'k', None) - xr = QuantumRegister(m, 'x', None) - yr = QuantumRegister(n, 'y', None) - out = QuantumRegister(1, 'out', None) - #cr = ClassicalRegister(1,'c') - qc = QuantumCircuit(kr, xr,yr,out) - - # qc.h(kr) - - #if(k>=0): - # kbin = bin(k)[2:][::-1] - # for i in range(len(kbin)): - # if kbin[i]=='1': - # qc.x(kr[i]) - - # initialize x - for i in range(m): - if x[i]=='1': - qc.x(xr[i]) - # initialize y - for i in range(n): - if y[i]=='1': - qc.x(yr[i]) - # rotate y - for i in range(logn): - qc = qc.compose(QutesGates.crot(n,2**i,1), [kr[i]]+yr[:] ) - # compare x and y[:m] - for i in range(m): - qc.cx(xr[i],yr[i]) - qc.x(yr[i]) - uncompute = qc.reverse_ops() - qc.mcx(yr[:m],out) - - #uncompute - # qc.compose(uncompute, inplace=True) - for i in range(m): - qc.x(yr[i]) - qc.cx(xr[i],yr[i]) - for i in range(logn): - qc = qc.compose(QutesGates.crot(n,2**i,1).inverse(), [kr[i]]+yr[:] ) - for i in range(m): - if x[i]=='1': - qc.x(xr[i]) - for i in range(n): - if y[i]=='1': - qc.x(yr[i]) - #qc.measure(out,cr) - #self.ciruit_handler.print_circuit(qc) - #res = self.ciruit_handler.__run__(qc,1000) - #self.ciruit_handler.__revcounts__(res) - #qc = qc.to_gate(label='ESM') - return qc - #Rotation gate (not controlled), k=2^p def rot(n, k, block_size=1): qc = QuantumCircuit(n, name=f'rot_k={k}') diff --git a/src/qutes.py b/src/qutes.py index 1e3317e..6cb7ff2 100644 --- a/src/qutes.py +++ b/src/qutes.py @@ -8,6 +8,7 @@ from grammar_frontend.qutes_parser import QutesParser from grammar_frontend.qutes_grammar_visitor import QutesGrammarVisitor from grammar_frontend.symbols_discovery_visitor import SymbolsDiscoveryVisitor +from grammar_frontend.qutes_syntax_error_listener import QutesErrorListener from symbols.scope_handler import ScopeHandlerForSymbolsUpdate from symbols.variables_handler import VariablesHandler from quantum_circuit import QuantumCircuitHandler @@ -27,49 +28,55 @@ def main(argv): input_stream = FileStream(args.file_path) lexer = QutesLexer(input_stream) + lexer.removeErrorListeners() + lexer.addErrorListener(QutesErrorListener()) + stream = CommonTokenStream(lexer) parser = QutesParser(stream) + parser.removeErrorListeners() + parser.addErrorListener(QutesErrorListener()) + tree = parser.program() if parser.getNumberOfSyntaxErrors() > 0: - print("syntax errors") - else: - quantum_circuit_handler = QuantumCircuitHandler() + raise SyntaxError() - grammar_listener = SymbolsDiscoveryVisitor(quantum_circuit_handler) - grammar_listener.visit(tree) + quantum_circuit_handler = QuantumCircuitHandler() - symbols_tree = grammar_listener.scope_handler.symbols_tree - - scope_handler = ScopeHandlerForSymbolsUpdate(symbols_tree) - variables_handler = VariablesHandler(scope_handler, quantum_circuit_handler) + grammar_listener = SymbolsDiscoveryVisitor(quantum_circuit_handler) + grammar_listener.visit(tree) - grammar_visitor = QutesGrammarVisitor(symbols_tree, quantum_circuit_handler, scope_handler, variables_handler, args.log_verbose) - result = str(grammar_visitor.visit(tree)) - - print() - print("----Result----") - print(result.replace("\n", "", 1)) - - if(args.log_symbols_scope): - print() - print("----Symbols Scope----") - for pre, _, node in RenderTree(symbols_tree): - print("%s%s(%s) Symbols: %s" % (pre, node.scope_class, node.scope_type_detail, node.symbols)) + symbols_tree = grammar_listener.scope_handler.symbols_tree + + scope_handler = ScopeHandlerForSymbolsUpdate(symbols_tree) + variables_handler = VariablesHandler(scope_handler, quantum_circuit_handler) - if(args.log_ast_tree): - print() - ast_tree_str = tree.toStringTree(recog=parser) - print("-------Abstract Syntax Tree--------") - print(ast_tree_str) - + grammar_visitor = QutesGrammarVisitor(symbols_tree, quantum_circuit_handler, scope_handler, variables_handler, args.log_verbose) + result = str(grammar_visitor.visit(tree)) + + print() + print("----Result----") + print(result.replace("\n", "", 1)) + + if(args.log_symbols_scope): print() - print("----Quantum Circuit----") - circuit = quantum_circuit_handler.create_circuit() - quantum_circuit_handler.print_circuit(circuit, args.save_circuit_as_image, args.log_quantum_circuit) - quantum_circuit_handler.run_circuit(circuit, args.number_of_iterations) + print("----Symbols Scope----") + for pre, _, node in RenderTree(symbols_tree): + print("%s%s(%s) Symbols: %s" % (pre, node.scope_class, node.scope_type_detail, node.symbols)) + if(args.log_ast_tree): print() + ast_tree_str = tree.toStringTree(recog=parser) + print("-------Abstract Syntax Tree--------") + print(ast_tree_str) + + print() + print("----Quantum Circuit----") + circuit = quantum_circuit_handler.create_circuit() + quantum_circuit_handler.print_circuit(circuit, args.save_circuit_as_image, args.log_quantum_circuit) + quantum_circuit_handler.run_circuit(circuit, args.number_of_iterations, print_count=True) + + print() if __name__ == '__main__': main(sys.argv) diff --git a/src/qutes_antlr/qutes_lexer.py b/src/qutes_antlr/qutes_lexer.py index 8bafd60..95b5f2c 100644 --- a/src/qutes_antlr/qutes_lexer.py +++ b/src/qutes_antlr/qutes_lexer.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,0,57,547,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,58,555,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, @@ -19,202 +19,205 @@ def serializedATN(): 39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7, 45,2,46,7,46,2,47,7,47,2,48,7,48,2,49,7,49,2,50,7,50,2,51,7,51,2, 52,7,52,2,53,7,53,2,54,7,54,2,55,7,55,2,56,7,56,2,57,7,57,2,58,7, - 58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,1,0,1,0,1,0,1,0,1,1,1, - 1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1, - 3,1,4,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1, - 6,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1, - 8,1,8,1,9,1,9,1,10,1,10,1,11,1,11,1,11,1,11,1,12,1,12,1,12,1,12, - 1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1,14, - 1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,16,1,16,1,16,1,16,1,16, - 1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,18, - 1,18,1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,19,1,19,1,19, - 1,20,1,20,1,20,1,21,1,21,1,22,1,22,1,22,1,23,1,23,1,24,1,24,1,24, - 1,25,1,25,1,26,1,26,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,29, - 1,29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,31,1,31,1,31,1,31, - 1,31,1,31,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1,34,1,34,1,34, - 1,34,1,34,1,34,1,35,1,35,1,35,1,36,1,36,1,37,1,37,1,38,1,38,1,39, - 1,39,1,40,1,40,1,41,1,41,1,42,1,42,1,43,1,43,1,44,1,44,1,45,1,45, - 1,45,1,45,5,45,327,8,45,10,45,12,45,330,9,45,1,45,1,45,1,45,1,45, - 1,45,1,45,5,45,338,8,45,10,45,12,45,341,9,45,3,45,343,8,45,1,46, - 1,46,1,46,1,46,1,46,1,47,1,47,1,47,1,47,1,47,1,47,1,48,1,48,1,49, - 1,49,1,50,1,50,1,50,1,50,1,50,1,50,1,50,1,50,1,50,1,50,1,50,1,50, - 3,50,372,8,50,1,51,1,51,1,51,3,51,377,8,51,1,52,4,52,380,8,52,11, - 52,12,52,381,1,53,3,53,385,8,53,1,53,4,53,388,8,53,11,53,12,53,389, - 1,53,1,53,5,53,394,8,53,10,53,12,53,397,9,53,1,53,3,53,400,8,53, - 1,53,1,53,4,53,404,8,53,11,53,12,53,405,3,53,408,8,53,1,54,1,54, - 1,54,1,54,4,54,414,8,54,11,54,12,54,415,1,55,1,55,1,55,4,55,421, - 8,55,11,55,12,55,422,1,56,1,56,1,56,3,56,428,8,56,1,56,1,56,5,56, - 432,8,56,10,56,12,56,435,9,56,1,56,1,56,3,56,439,8,56,3,56,441,8, - 56,1,56,1,56,1,56,1,56,1,56,1,56,1,56,1,56,1,56,1,56,3,56,453,8, - 56,1,56,1,56,3,56,457,8,56,1,56,3,56,460,8,56,1,57,1,57,1,57,1,57, - 1,57,5,57,467,8,57,10,57,12,57,470,9,57,1,57,1,57,5,57,474,8,57, - 10,57,12,57,477,9,57,1,57,1,57,1,57,1,57,1,57,1,57,5,57,485,8,57, - 10,57,12,57,488,9,57,1,57,1,57,5,57,492,8,57,10,57,12,57,495,9,57, - 1,57,1,57,1,57,1,57,3,57,501,8,57,1,57,4,57,504,8,57,11,57,12,57, - 505,1,57,1,57,3,57,510,8,57,1,58,1,58,1,58,1,59,4,59,516,8,59,11, - 59,12,59,517,1,60,1,60,1,60,1,60,1,60,1,60,5,60,526,8,60,10,60,12, - 60,529,9,60,1,60,1,60,1,61,4,61,534,8,61,11,61,12,61,535,1,61,3, - 61,539,8,61,1,61,1,61,1,62,3,62,544,8,62,1,62,1,62,1,328,0,63,1, - 1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27, - 14,29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49, - 25,51,26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71, - 36,73,37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,89,45,91,0,93, - 0,95,0,97,0,99,0,101,0,103,46,105,47,107,48,109,49,111,50,113,51, - 115,52,117,53,119,54,121,55,123,56,125,57,1,0,32,2,0,73,73,105,105, - 2,0,78,78,110,110,2,0,84,84,116,116,2,0,66,66,98,98,2,0,79,79,111, - 111,2,0,76,76,108,108,2,0,83,83,115,115,2,0,82,82,114,114,2,0,71, - 71,103,103,2,0,81,81,113,113,2,0,85,85,117,117,2,0,70,70,102,102, - 2,0,65,65,97,97,2,0,86,86,118,118,2,0,68,68,100,100,2,0,69,69,101, - 101,2,0,80,80,112,112,2,0,89,89,121,121,2,0,90,90,122,122,2,0,77, - 77,109,109,2,0,67,67,99,99,2,0,72,72,104,104,2,0,87,87,119,119,2, - 0,10,10,13,13,1,0,48,57,2,0,43,43,45,45,2,0,88,88,120,120,2,0,65, - 70,97,102,1,0,48,49,3,0,48,57,65,90,97,122,2,0,34,34,92,92,3,0,9, - 10,13,13,32,32,583,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0, - 0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0, - 0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0, - 0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0, - 0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0, - 0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0, - 0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0, - 0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0, - 0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0, - 0,0,89,1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1, - 0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0,0, - 119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,1,127,1,0, - 0,0,3,131,1,0,0,0,5,136,1,0,0,0,7,143,1,0,0,0,9,149,1,0,0,0,11,155, - 1,0,0,0,13,164,1,0,0,0,15,170,1,0,0,0,17,175,1,0,0,0,19,182,1,0, - 0,0,21,184,1,0,0,0,23,186,1,0,0,0,25,190,1,0,0,0,27,197,1,0,0,0, - 29,204,1,0,0,0,31,211,1,0,0,0,33,215,1,0,0,0,35,224,1,0,0,0,37,232, - 1,0,0,0,39,238,1,0,0,0,41,246,1,0,0,0,43,249,1,0,0,0,45,251,1,0, - 0,0,47,254,1,0,0,0,49,256,1,0,0,0,51,259,1,0,0,0,53,261,1,0,0,0, - 55,263,1,0,0,0,57,267,1,0,0,0,59,271,1,0,0,0,61,278,1,0,0,0,63,281, - 1,0,0,0,65,287,1,0,0,0,67,290,1,0,0,0,69,295,1,0,0,0,71,301,1,0, - 0,0,73,304,1,0,0,0,75,306,1,0,0,0,77,308,1,0,0,0,79,310,1,0,0,0, - 81,312,1,0,0,0,83,314,1,0,0,0,85,316,1,0,0,0,87,318,1,0,0,0,89,320, - 1,0,0,0,91,342,1,0,0,0,93,344,1,0,0,0,95,349,1,0,0,0,97,355,1,0, - 0,0,99,357,1,0,0,0,101,371,1,0,0,0,103,376,1,0,0,0,105,379,1,0,0, - 0,107,407,1,0,0,0,109,409,1,0,0,0,111,417,1,0,0,0,113,459,1,0,0, - 0,115,509,1,0,0,0,117,511,1,0,0,0,119,515,1,0,0,0,121,519,1,0,0, - 0,123,538,1,0,0,0,125,543,1,0,0,0,127,128,7,0,0,0,128,129,7,1,0, - 0,129,130,7,2,0,0,130,2,1,0,0,0,131,132,7,3,0,0,132,133,7,4,0,0, - 133,134,7,4,0,0,134,135,7,5,0,0,135,4,1,0,0,0,136,137,7,6,0,0,137, - 138,7,2,0,0,138,139,7,7,0,0,139,140,7,0,0,0,140,141,7,1,0,0,141, - 142,7,8,0,0,142,6,1,0,0,0,143,144,7,9,0,0,144,145,7,10,0,0,145,146, - 7,3,0,0,146,147,7,0,0,0,147,148,7,2,0,0,148,8,1,0,0,0,149,150,7, - 9,0,0,150,151,7,10,0,0,151,152,7,0,0,0,152,153,7,1,0,0,153,154,7, - 2,0,0,154,10,1,0,0,0,155,156,7,9,0,0,156,157,7,10,0,0,157,158,7, - 6,0,0,158,159,7,2,0,0,159,160,7,7,0,0,160,161,7,0,0,0,161,162,7, - 1,0,0,162,163,7,8,0,0,163,12,1,0,0,0,164,165,7,11,0,0,165,166,7, - 5,0,0,166,167,7,4,0,0,167,168,7,12,0,0,168,169,7,2,0,0,169,14,1, - 0,0,0,170,171,7,13,0,0,171,172,7,4,0,0,172,173,7,0,0,0,173,174,7, - 14,0,0,174,16,1,0,0,0,175,176,7,7,0,0,176,177,7,15,0,0,177,178,7, - 2,0,0,178,179,7,10,0,0,179,180,7,7,0,0,180,181,7,1,0,0,181,18,1, - 0,0,0,182,183,5,43,0,0,183,20,1,0,0,0,184,185,5,45,0,0,185,22,1, - 0,0,0,186,187,7,1,0,0,187,188,7,4,0,0,188,189,7,2,0,0,189,24,1,0, - 0,0,190,191,7,16,0,0,191,192,7,12,0,0,192,193,7,10,0,0,193,194,7, - 5,0,0,194,195,7,0,0,0,195,196,7,17,0,0,196,26,1,0,0,0,197,198,7, - 16,0,0,198,199,7,12,0,0,199,200,7,10,0,0,200,201,7,5,0,0,201,202, - 7,0,0,0,202,203,7,18,0,0,203,28,1,0,0,0,204,205,7,8,0,0,205,206, - 7,7,0,0,206,207,7,4,0,0,207,208,7,13,0,0,208,209,7,15,0,0,209,210, - 7,7,0,0,210,30,1,0,0,0,211,212,7,19,0,0,212,213,7,20,0,0,213,214, - 7,18,0,0,214,32,1,0,0,0,215,216,7,21,0,0,216,217,7,12,0,0,217,218, - 7,14,0,0,218,219,7,12,0,0,219,220,7,19,0,0,220,221,7,12,0,0,221, - 222,7,7,0,0,222,223,7,14,0,0,223,34,1,0,0,0,224,225,7,19,0,0,225, - 226,7,15,0,0,226,227,7,12,0,0,227,228,7,6,0,0,228,229,7,10,0,0,229, - 230,7,7,0,0,230,231,7,15,0,0,231,36,1,0,0,0,232,233,7,16,0,0,233, - 234,7,7,0,0,234,235,7,0,0,0,235,236,7,1,0,0,236,237,7,2,0,0,237, - 38,1,0,0,0,238,239,7,3,0,0,239,240,7,12,0,0,240,241,7,7,0,0,241, - 242,7,7,0,0,242,243,7,0,0,0,243,244,7,15,0,0,244,245,7,7,0,0,245, - 40,1,0,0,0,246,247,5,61,0,0,247,248,5,61,0,0,248,42,1,0,0,0,249, - 250,5,62,0,0,250,44,1,0,0,0,251,252,5,62,0,0,252,253,5,61,0,0,253, - 46,1,0,0,0,254,255,5,60,0,0,255,48,1,0,0,0,256,257,5,60,0,0,257, - 258,5,61,0,0,258,50,1,0,0,0,259,260,5,61,0,0,260,52,1,0,0,0,261, - 262,5,59,0,0,262,54,1,0,0,0,263,264,7,13,0,0,264,265,7,12,0,0,265, - 266,7,7,0,0,266,56,1,0,0,0,267,268,7,11,0,0,268,269,7,4,0,0,269, - 270,7,7,0,0,270,58,1,0,0,0,271,272,7,6,0,0,272,273,7,15,0,0,273, - 274,7,12,0,0,274,275,7,7,0,0,275,276,7,20,0,0,276,277,7,21,0,0,277, - 60,1,0,0,0,278,279,7,0,0,0,279,280,7,1,0,0,280,62,1,0,0,0,281,282, - 7,22,0,0,282,283,7,21,0,0,283,284,7,15,0,0,284,285,7,7,0,0,285,286, - 7,15,0,0,286,64,1,0,0,0,287,288,7,0,0,0,288,289,7,11,0,0,289,66, - 1,0,0,0,290,291,7,15,0,0,291,292,7,5,0,0,292,293,7,6,0,0,293,294, - 7,15,0,0,294,68,1,0,0,0,295,296,7,22,0,0,296,297,7,21,0,0,297,298, - 7,0,0,0,298,299,7,5,0,0,299,300,7,15,0,0,300,70,1,0,0,0,301,302, - 7,14,0,0,302,303,7,4,0,0,303,72,1,0,0,0,304,305,5,123,0,0,305,74, - 1,0,0,0,306,307,5,125,0,0,307,76,1,0,0,0,308,309,5,40,0,0,309,78, - 1,0,0,0,310,311,5,41,0,0,311,80,1,0,0,0,312,313,5,91,0,0,313,82, - 1,0,0,0,314,315,5,93,0,0,315,84,1,0,0,0,316,317,5,46,0,0,317,86, - 1,0,0,0,318,319,5,34,0,0,319,88,1,0,0,0,320,321,5,44,0,0,321,90, - 1,0,0,0,322,323,5,47,0,0,323,324,5,42,0,0,324,328,1,0,0,0,325,327, - 9,0,0,0,326,325,1,0,0,0,327,330,1,0,0,0,328,329,1,0,0,0,328,326, - 1,0,0,0,329,331,1,0,0,0,330,328,1,0,0,0,331,332,5,42,0,0,332,343, - 5,47,0,0,333,334,5,47,0,0,334,335,5,47,0,0,335,339,1,0,0,0,336,338, - 8,23,0,0,337,336,1,0,0,0,338,341,1,0,0,0,339,337,1,0,0,0,339,340, - 1,0,0,0,340,343,1,0,0,0,341,339,1,0,0,0,342,322,1,0,0,0,342,333, - 1,0,0,0,343,92,1,0,0,0,344,345,7,2,0,0,345,346,7,7,0,0,346,347,7, - 10,0,0,347,348,7,15,0,0,348,94,1,0,0,0,349,350,7,11,0,0,350,351, - 7,12,0,0,351,352,7,5,0,0,352,353,7,6,0,0,353,354,7,15,0,0,354,96, - 1,0,0,0,355,356,7,24,0,0,356,98,1,0,0,0,357,358,7,25,0,0,358,100, - 1,0,0,0,359,360,5,124,0,0,360,361,5,48,0,0,361,372,5,62,0,0,362, - 363,5,124,0,0,363,364,5,49,0,0,364,372,5,62,0,0,365,366,5,124,0, - 0,366,367,5,43,0,0,367,372,5,62,0,0,368,369,5,124,0,0,369,370,5, - 45,0,0,370,372,5,62,0,0,371,359,1,0,0,0,371,362,1,0,0,0,371,365, - 1,0,0,0,371,368,1,0,0,0,372,102,1,0,0,0,373,377,3,93,46,0,374,377, - 3,95,47,0,375,377,2,48,49,0,376,373,1,0,0,0,376,374,1,0,0,0,376, - 375,1,0,0,0,377,104,1,0,0,0,378,380,3,97,48,0,379,378,1,0,0,0,380, - 381,1,0,0,0,381,379,1,0,0,0,381,382,1,0,0,0,382,106,1,0,0,0,383, - 385,3,99,49,0,384,383,1,0,0,0,384,385,1,0,0,0,385,387,1,0,0,0,386, - 388,3,97,48,0,387,386,1,0,0,0,388,389,1,0,0,0,389,387,1,0,0,0,389, - 390,1,0,0,0,390,391,1,0,0,0,391,395,5,46,0,0,392,394,3,97,48,0,393, - 392,1,0,0,0,394,397,1,0,0,0,395,393,1,0,0,0,395,396,1,0,0,0,396, - 408,1,0,0,0,397,395,1,0,0,0,398,400,3,99,49,0,399,398,1,0,0,0,399, - 400,1,0,0,0,400,401,1,0,0,0,401,403,5,46,0,0,402,404,3,97,48,0,403, - 402,1,0,0,0,404,405,1,0,0,0,405,403,1,0,0,0,405,406,1,0,0,0,406, - 408,1,0,0,0,407,384,1,0,0,0,407,399,1,0,0,0,408,108,1,0,0,0,409, - 410,5,48,0,0,410,413,7,26,0,0,411,414,7,27,0,0,412,414,3,97,48,0, - 413,411,1,0,0,0,413,412,1,0,0,0,414,415,1,0,0,0,415,413,1,0,0,0, - 415,416,1,0,0,0,416,110,1,0,0,0,417,418,5,48,0,0,418,420,7,3,0,0, - 419,421,7,28,0,0,420,419,1,0,0,0,421,422,1,0,0,0,422,420,1,0,0,0, - 422,423,1,0,0,0,423,112,1,0,0,0,424,427,3,81,40,0,425,428,3,103, - 51,0,426,428,2,48,49,0,427,425,1,0,0,0,427,426,1,0,0,0,428,440,1, - 0,0,0,429,433,3,89,44,0,430,432,5,32,0,0,431,430,1,0,0,0,432,435, - 1,0,0,0,433,431,1,0,0,0,433,434,1,0,0,0,434,438,1,0,0,0,435,433, - 1,0,0,0,436,439,3,103,51,0,437,439,2,48,49,0,438,436,1,0,0,0,438, - 437,1,0,0,0,439,441,1,0,0,0,440,429,1,0,0,0,440,441,1,0,0,0,441, - 442,1,0,0,0,442,443,3,83,41,0,443,444,7,9,0,0,444,460,1,0,0,0,445, - 446,3,107,53,0,446,447,3,89,44,0,447,448,3,107,53,0,448,449,7,9, - 0,0,449,460,1,0,0,0,450,460,3,101,50,0,451,453,3,99,49,0,452,451, - 1,0,0,0,452,453,1,0,0,0,453,456,1,0,0,0,454,457,3,103,51,0,455,457, - 2,48,49,0,456,454,1,0,0,0,456,455,1,0,0,0,457,458,1,0,0,0,458,460, - 7,9,0,0,459,424,1,0,0,0,459,445,1,0,0,0,459,450,1,0,0,0,459,452, - 1,0,0,0,460,114,1,0,0,0,461,510,3,113,56,0,462,463,3,81,40,0,463, - 475,3,113,56,0,464,468,3,89,44,0,465,467,5,32,0,0,466,465,1,0,0, - 0,467,470,1,0,0,0,468,466,1,0,0,0,468,469,1,0,0,0,469,471,1,0,0, - 0,470,468,1,0,0,0,471,472,3,113,56,0,472,474,1,0,0,0,473,464,1,0, - 0,0,474,477,1,0,0,0,475,473,1,0,0,0,475,476,1,0,0,0,476,478,1,0, - 0,0,477,475,1,0,0,0,478,479,3,83,41,0,479,510,1,0,0,0,480,481,3, - 81,40,0,481,493,3,105,52,0,482,486,3,89,44,0,483,485,5,32,0,0,484, - 483,1,0,0,0,485,488,1,0,0,0,486,484,1,0,0,0,486,487,1,0,0,0,487, - 489,1,0,0,0,488,486,1,0,0,0,489,490,3,105,52,0,490,492,1,0,0,0,491, - 482,1,0,0,0,492,495,1,0,0,0,493,491,1,0,0,0,493,494,1,0,0,0,494, - 496,1,0,0,0,495,493,1,0,0,0,496,497,3,83,41,0,497,498,7,9,0,0,498, - 510,1,0,0,0,499,501,3,99,49,0,500,499,1,0,0,0,500,501,1,0,0,0,501, - 503,1,0,0,0,502,504,3,97,48,0,503,502,1,0,0,0,504,505,1,0,0,0,505, - 503,1,0,0,0,505,506,1,0,0,0,506,507,1,0,0,0,507,508,7,9,0,0,508, - 510,1,0,0,0,509,461,1,0,0,0,509,462,1,0,0,0,509,480,1,0,0,0,509, - 500,1,0,0,0,510,116,1,0,0,0,511,512,3,121,60,0,512,513,7,9,0,0,513, - 118,1,0,0,0,514,516,7,29,0,0,515,514,1,0,0,0,516,517,1,0,0,0,517, - 515,1,0,0,0,517,518,1,0,0,0,518,120,1,0,0,0,519,527,5,34,0,0,520, - 521,5,92,0,0,521,526,9,0,0,0,522,523,5,34,0,0,523,526,5,34,0,0,524, - 526,8,30,0,0,525,520,1,0,0,0,525,522,1,0,0,0,525,524,1,0,0,0,526, - 529,1,0,0,0,527,525,1,0,0,0,527,528,1,0,0,0,528,530,1,0,0,0,529, - 527,1,0,0,0,530,531,5,34,0,0,531,122,1,0,0,0,532,534,7,31,0,0,533, - 532,1,0,0,0,534,535,1,0,0,0,535,533,1,0,0,0,535,536,1,0,0,0,536, - 539,1,0,0,0,537,539,3,91,45,0,538,533,1,0,0,0,538,537,1,0,0,0,539, - 540,1,0,0,0,540,541,6,61,0,0,541,124,1,0,0,0,542,544,5,13,0,0,543, - 542,1,0,0,0,543,544,1,0,0,0,544,545,1,0,0,0,545,546,5,10,0,0,546, - 126,1,0,0,0,36,0,328,339,342,371,376,381,384,389,395,399,405,407, - 413,415,422,427,433,438,440,452,456,459,468,475,486,493,500,505, - 509,517,525,527,535,538,543,1,6,0,0 + 58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,1,0,1,0,1,0, + 1,0,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3, + 1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5,1,5, + 1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8, + 1,8,1,8,1,8,1,8,1,9,1,9,1,10,1,10,1,11,1,11,1,11,1,11,1,12,1,12, + 1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,13,1,14, + 1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,16,1,16,1,16, + 1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18, + 1,18,1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,19,1,20,1,20, + 1,20,1,20,1,20,1,20,1,20,1,20,1,21,1,21,1,21,1,22,1,22,1,23,1,23, + 1,23,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,27,1,27,1,28,1,28,1,28, + 1,28,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,30,1,30,1,31, + 1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,34,1,34, + 1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,37, + 1,37,1,38,1,38,1,39,1,39,1,40,1,40,1,41,1,41,1,42,1,42,1,43,1,43, + 1,44,1,44,1,45,1,45,1,46,1,46,1,46,1,46,5,46,333,8,46,10,46,12,46, + 336,9,46,1,46,1,46,1,46,1,46,1,46,1,46,5,46,344,8,46,10,46,12,46, + 347,9,46,3,46,349,8,46,1,47,1,47,1,47,1,47,1,47,1,48,1,48,1,48,1, + 48,1,48,1,48,1,49,1,49,1,50,1,50,1,51,1,51,1,51,1,51,1,51,1,51,1, + 51,1,51,1,51,1,51,1,51,1,51,3,51,378,8,51,1,52,1,52,1,52,3,52,383, + 8,52,1,53,4,53,386,8,53,11,53,12,53,387,1,54,3,54,391,8,54,1,54, + 4,54,394,8,54,11,54,12,54,395,1,54,1,54,5,54,400,8,54,10,54,12,54, + 403,9,54,1,54,3,54,406,8,54,1,54,1,54,4,54,410,8,54,11,54,12,54, + 411,3,54,414,8,54,1,55,1,55,1,55,1,55,4,55,420,8,55,11,55,12,55, + 421,1,56,1,56,1,56,4,56,427,8,56,11,56,12,56,428,1,57,1,57,1,57, + 3,57,434,8,57,1,57,1,57,5,57,438,8,57,10,57,12,57,441,9,57,1,57, + 1,57,3,57,445,8,57,3,57,447,8,57,1,57,1,57,1,57,1,57,1,57,1,57,1, + 57,1,57,1,57,1,57,3,57,459,8,57,1,57,1,57,3,57,463,8,57,1,57,3,57, + 466,8,57,1,58,1,58,1,58,1,58,1,58,5,58,473,8,58,10,58,12,58,476, + 9,58,1,58,1,58,5,58,480,8,58,10,58,12,58,483,9,58,1,58,1,58,1,58, + 1,58,1,58,1,58,5,58,491,8,58,10,58,12,58,494,9,58,1,58,1,58,5,58, + 498,8,58,10,58,12,58,501,9,58,1,58,1,58,1,58,1,58,3,58,507,8,58, + 1,58,4,58,510,8,58,11,58,12,58,511,1,58,1,58,3,58,516,8,58,1,59, + 1,59,1,59,1,60,1,60,5,60,523,8,60,10,60,12,60,526,9,60,1,61,1,61, + 1,61,1,61,1,61,1,61,5,61,534,8,61,10,61,12,61,537,9,61,1,61,1,61, + 1,62,4,62,542,8,62,11,62,12,62,543,1,62,3,62,547,8,62,1,62,1,62, + 1,63,3,63,552,8,63,1,63,1,63,1,334,0,64,1,1,3,2,5,3,7,4,9,5,11,6, + 13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,17,35, + 18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,26,53,27,55,28,57, + 29,59,30,61,31,63,32,65,33,67,34,69,35,71,36,73,37,75,38,77,39,79, + 40,81,41,83,42,85,43,87,44,89,45,91,46,93,0,95,0,97,0,99,0,101,0, + 103,0,105,47,107,48,109,49,111,50,113,51,115,52,117,53,119,54,121, + 55,123,56,125,57,127,58,1,0,33,2,0,73,73,105,105,2,0,78,78,110,110, + 2,0,84,84,116,116,2,0,66,66,98,98,2,0,79,79,111,111,2,0,76,76,108, + 108,2,0,83,83,115,115,2,0,82,82,114,114,2,0,71,71,103,103,2,0,81, + 81,113,113,2,0,85,85,117,117,2,0,70,70,102,102,2,0,65,65,97,97,2, + 0,86,86,118,118,2,0,68,68,100,100,2,0,69,69,101,101,2,0,80,80,112, + 112,2,0,89,89,121,121,2,0,90,90,122,122,2,0,77,77,109,109,2,0,67, + 67,99,99,2,0,88,88,120,120,2,0,72,72,104,104,2,0,87,87,119,119,2, + 0,10,10,13,13,1,0,48,57,2,0,43,43,45,45,2,0,65,70,97,102,1,0,48, + 49,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122,2,0,34,34, + 92,92,3,0,9,10,13,13,32,32,591,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0, + 0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0, + 0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0, + 0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0, + 0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0, + 0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0, + 0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0, + 0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0, + 0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0, + 0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0, + 0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117, + 1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0, + 0,127,1,0,0,0,1,129,1,0,0,0,3,133,1,0,0,0,5,138,1,0,0,0,7,145,1, + 0,0,0,9,151,1,0,0,0,11,157,1,0,0,0,13,166,1,0,0,0,15,172,1,0,0,0, + 17,177,1,0,0,0,19,184,1,0,0,0,21,186,1,0,0,0,23,188,1,0,0,0,25,192, + 1,0,0,0,27,199,1,0,0,0,29,206,1,0,0,0,31,213,1,0,0,0,33,217,1,0, + 0,0,35,221,1,0,0,0,37,230,1,0,0,0,39,238,1,0,0,0,41,244,1,0,0,0, + 43,252,1,0,0,0,45,255,1,0,0,0,47,257,1,0,0,0,49,260,1,0,0,0,51,262, + 1,0,0,0,53,265,1,0,0,0,55,267,1,0,0,0,57,269,1,0,0,0,59,273,1,0, + 0,0,61,277,1,0,0,0,63,284,1,0,0,0,65,287,1,0,0,0,67,293,1,0,0,0, + 69,296,1,0,0,0,71,301,1,0,0,0,73,307,1,0,0,0,75,310,1,0,0,0,77,312, + 1,0,0,0,79,314,1,0,0,0,81,316,1,0,0,0,83,318,1,0,0,0,85,320,1,0, + 0,0,87,322,1,0,0,0,89,324,1,0,0,0,91,326,1,0,0,0,93,348,1,0,0,0, + 95,350,1,0,0,0,97,355,1,0,0,0,99,361,1,0,0,0,101,363,1,0,0,0,103, + 377,1,0,0,0,105,382,1,0,0,0,107,385,1,0,0,0,109,413,1,0,0,0,111, + 415,1,0,0,0,113,423,1,0,0,0,115,465,1,0,0,0,117,515,1,0,0,0,119, + 517,1,0,0,0,121,520,1,0,0,0,123,527,1,0,0,0,125,546,1,0,0,0,127, + 551,1,0,0,0,129,130,7,0,0,0,130,131,7,1,0,0,131,132,7,2,0,0,132, + 2,1,0,0,0,133,134,7,3,0,0,134,135,7,4,0,0,135,136,7,4,0,0,136,137, + 7,5,0,0,137,4,1,0,0,0,138,139,7,6,0,0,139,140,7,2,0,0,140,141,7, + 7,0,0,141,142,7,0,0,0,142,143,7,1,0,0,143,144,7,8,0,0,144,6,1,0, + 0,0,145,146,7,9,0,0,146,147,7,10,0,0,147,148,7,3,0,0,148,149,7,0, + 0,0,149,150,7,2,0,0,150,8,1,0,0,0,151,152,7,9,0,0,152,153,7,10,0, + 0,153,154,7,0,0,0,154,155,7,1,0,0,155,156,7,2,0,0,156,10,1,0,0,0, + 157,158,7,9,0,0,158,159,7,10,0,0,159,160,7,6,0,0,160,161,7,2,0,0, + 161,162,7,7,0,0,162,163,7,0,0,0,163,164,7,1,0,0,164,165,7,8,0,0, + 165,12,1,0,0,0,166,167,7,11,0,0,167,168,7,5,0,0,168,169,7,4,0,0, + 169,170,7,12,0,0,170,171,7,2,0,0,171,14,1,0,0,0,172,173,7,13,0,0, + 173,174,7,4,0,0,174,175,7,0,0,0,175,176,7,14,0,0,176,16,1,0,0,0, + 177,178,7,7,0,0,178,179,7,15,0,0,179,180,7,2,0,0,180,181,7,10,0, + 0,181,182,7,7,0,0,182,183,7,1,0,0,183,18,1,0,0,0,184,185,5,43,0, + 0,185,20,1,0,0,0,186,187,5,45,0,0,187,22,1,0,0,0,188,189,7,1,0,0, + 189,190,7,4,0,0,190,191,7,2,0,0,191,24,1,0,0,0,192,193,7,16,0,0, + 193,194,7,12,0,0,194,195,7,10,0,0,195,196,7,5,0,0,196,197,7,0,0, + 0,197,198,7,17,0,0,198,26,1,0,0,0,199,200,7,16,0,0,200,201,7,12, + 0,0,201,202,7,10,0,0,202,203,7,5,0,0,203,204,7,0,0,0,204,205,7,18, + 0,0,205,28,1,0,0,0,206,207,7,8,0,0,207,208,7,7,0,0,208,209,7,4,0, + 0,209,210,7,13,0,0,210,211,7,15,0,0,211,212,7,7,0,0,212,30,1,0,0, + 0,213,214,7,19,0,0,214,215,7,20,0,0,215,216,7,18,0,0,216,32,1,0, + 0,0,217,218,7,19,0,0,218,219,7,20,0,0,219,220,7,21,0,0,220,34,1, + 0,0,0,221,222,7,22,0,0,222,223,7,12,0,0,223,224,7,14,0,0,224,225, + 7,12,0,0,225,226,7,19,0,0,226,227,7,12,0,0,227,228,7,7,0,0,228,229, + 7,14,0,0,229,36,1,0,0,0,230,231,7,19,0,0,231,232,7,15,0,0,232,233, + 7,12,0,0,233,234,7,6,0,0,234,235,7,10,0,0,235,236,7,7,0,0,236,237, + 7,15,0,0,237,38,1,0,0,0,238,239,7,16,0,0,239,240,7,7,0,0,240,241, + 7,0,0,0,241,242,7,1,0,0,242,243,7,2,0,0,243,40,1,0,0,0,244,245,7, + 3,0,0,245,246,7,12,0,0,246,247,7,7,0,0,247,248,7,7,0,0,248,249,7, + 0,0,0,249,250,7,15,0,0,250,251,7,7,0,0,251,42,1,0,0,0,252,253,5, + 61,0,0,253,254,5,61,0,0,254,44,1,0,0,0,255,256,5,62,0,0,256,46,1, + 0,0,0,257,258,5,62,0,0,258,259,5,61,0,0,259,48,1,0,0,0,260,261,5, + 60,0,0,261,50,1,0,0,0,262,263,5,60,0,0,263,264,5,61,0,0,264,52,1, + 0,0,0,265,266,5,61,0,0,266,54,1,0,0,0,267,268,5,59,0,0,268,56,1, + 0,0,0,269,270,7,13,0,0,270,271,7,12,0,0,271,272,7,7,0,0,272,58,1, + 0,0,0,273,274,7,11,0,0,274,275,7,4,0,0,275,276,7,7,0,0,276,60,1, + 0,0,0,277,278,7,6,0,0,278,279,7,15,0,0,279,280,7,12,0,0,280,281, + 7,7,0,0,281,282,7,20,0,0,282,283,7,22,0,0,283,62,1,0,0,0,284,285, + 7,0,0,0,285,286,7,1,0,0,286,64,1,0,0,0,287,288,7,23,0,0,288,289, + 7,22,0,0,289,290,7,15,0,0,290,291,7,7,0,0,291,292,7,15,0,0,292,66, + 1,0,0,0,293,294,7,0,0,0,294,295,7,11,0,0,295,68,1,0,0,0,296,297, + 7,15,0,0,297,298,7,5,0,0,298,299,7,6,0,0,299,300,7,15,0,0,300,70, + 1,0,0,0,301,302,7,23,0,0,302,303,7,22,0,0,303,304,7,0,0,0,304,305, + 7,5,0,0,305,306,7,15,0,0,306,72,1,0,0,0,307,308,7,14,0,0,308,309, + 7,4,0,0,309,74,1,0,0,0,310,311,5,123,0,0,311,76,1,0,0,0,312,313, + 5,125,0,0,313,78,1,0,0,0,314,315,5,40,0,0,315,80,1,0,0,0,316,317, + 5,41,0,0,317,82,1,0,0,0,318,319,5,91,0,0,319,84,1,0,0,0,320,321, + 5,93,0,0,321,86,1,0,0,0,322,323,5,46,0,0,323,88,1,0,0,0,324,325, + 5,34,0,0,325,90,1,0,0,0,326,327,5,44,0,0,327,92,1,0,0,0,328,329, + 5,47,0,0,329,330,5,42,0,0,330,334,1,0,0,0,331,333,9,0,0,0,332,331, + 1,0,0,0,333,336,1,0,0,0,334,335,1,0,0,0,334,332,1,0,0,0,335,337, + 1,0,0,0,336,334,1,0,0,0,337,338,5,42,0,0,338,349,5,47,0,0,339,340, + 5,47,0,0,340,341,5,47,0,0,341,345,1,0,0,0,342,344,8,24,0,0,343,342, + 1,0,0,0,344,347,1,0,0,0,345,343,1,0,0,0,345,346,1,0,0,0,346,349, + 1,0,0,0,347,345,1,0,0,0,348,328,1,0,0,0,348,339,1,0,0,0,349,94,1, + 0,0,0,350,351,7,2,0,0,351,352,7,7,0,0,352,353,7,10,0,0,353,354,7, + 15,0,0,354,96,1,0,0,0,355,356,7,11,0,0,356,357,7,12,0,0,357,358, + 7,5,0,0,358,359,7,6,0,0,359,360,7,15,0,0,360,98,1,0,0,0,361,362, + 7,25,0,0,362,100,1,0,0,0,363,364,7,26,0,0,364,102,1,0,0,0,365,366, + 5,124,0,0,366,367,5,48,0,0,367,378,5,62,0,0,368,369,5,124,0,0,369, + 370,5,49,0,0,370,378,5,62,0,0,371,372,5,124,0,0,372,373,5,43,0,0, + 373,378,5,62,0,0,374,375,5,124,0,0,375,376,5,45,0,0,376,378,5,62, + 0,0,377,365,1,0,0,0,377,368,1,0,0,0,377,371,1,0,0,0,377,374,1,0, + 0,0,378,104,1,0,0,0,379,383,3,95,47,0,380,383,3,97,48,0,381,383, + 2,48,49,0,382,379,1,0,0,0,382,380,1,0,0,0,382,381,1,0,0,0,383,106, + 1,0,0,0,384,386,3,99,49,0,385,384,1,0,0,0,386,387,1,0,0,0,387,385, + 1,0,0,0,387,388,1,0,0,0,388,108,1,0,0,0,389,391,3,101,50,0,390,389, + 1,0,0,0,390,391,1,0,0,0,391,393,1,0,0,0,392,394,3,99,49,0,393,392, + 1,0,0,0,394,395,1,0,0,0,395,393,1,0,0,0,395,396,1,0,0,0,396,397, + 1,0,0,0,397,401,5,46,0,0,398,400,3,99,49,0,399,398,1,0,0,0,400,403, + 1,0,0,0,401,399,1,0,0,0,401,402,1,0,0,0,402,414,1,0,0,0,403,401, + 1,0,0,0,404,406,3,101,50,0,405,404,1,0,0,0,405,406,1,0,0,0,406,407, + 1,0,0,0,407,409,5,46,0,0,408,410,3,99,49,0,409,408,1,0,0,0,410,411, + 1,0,0,0,411,409,1,0,0,0,411,412,1,0,0,0,412,414,1,0,0,0,413,390, + 1,0,0,0,413,405,1,0,0,0,414,110,1,0,0,0,415,416,5,48,0,0,416,419, + 7,21,0,0,417,420,7,27,0,0,418,420,3,99,49,0,419,417,1,0,0,0,419, + 418,1,0,0,0,420,421,1,0,0,0,421,419,1,0,0,0,421,422,1,0,0,0,422, + 112,1,0,0,0,423,424,5,48,0,0,424,426,7,3,0,0,425,427,7,28,0,0,426, + 425,1,0,0,0,427,428,1,0,0,0,428,426,1,0,0,0,428,429,1,0,0,0,429, + 114,1,0,0,0,430,433,3,83,41,0,431,434,3,105,52,0,432,434,2,48,49, + 0,433,431,1,0,0,0,433,432,1,0,0,0,434,446,1,0,0,0,435,439,3,91,45, + 0,436,438,5,32,0,0,437,436,1,0,0,0,438,441,1,0,0,0,439,437,1,0,0, + 0,439,440,1,0,0,0,440,444,1,0,0,0,441,439,1,0,0,0,442,445,3,105, + 52,0,443,445,2,48,49,0,444,442,1,0,0,0,444,443,1,0,0,0,445,447,1, + 0,0,0,446,435,1,0,0,0,446,447,1,0,0,0,447,448,1,0,0,0,448,449,3, + 85,42,0,449,450,7,9,0,0,450,466,1,0,0,0,451,452,3,109,54,0,452,453, + 3,91,45,0,453,454,3,109,54,0,454,455,7,9,0,0,455,466,1,0,0,0,456, + 466,3,103,51,0,457,459,3,101,50,0,458,457,1,0,0,0,458,459,1,0,0, + 0,459,462,1,0,0,0,460,463,3,105,52,0,461,463,2,48,49,0,462,460,1, + 0,0,0,462,461,1,0,0,0,463,464,1,0,0,0,464,466,7,9,0,0,465,430,1, + 0,0,0,465,451,1,0,0,0,465,456,1,0,0,0,465,458,1,0,0,0,466,116,1, + 0,0,0,467,516,3,115,57,0,468,469,3,83,41,0,469,481,3,115,57,0,470, + 474,3,91,45,0,471,473,5,32,0,0,472,471,1,0,0,0,473,476,1,0,0,0,474, + 472,1,0,0,0,474,475,1,0,0,0,475,477,1,0,0,0,476,474,1,0,0,0,477, + 478,3,115,57,0,478,480,1,0,0,0,479,470,1,0,0,0,480,483,1,0,0,0,481, + 479,1,0,0,0,481,482,1,0,0,0,482,484,1,0,0,0,483,481,1,0,0,0,484, + 485,3,85,42,0,485,516,1,0,0,0,486,487,3,83,41,0,487,499,3,107,53, + 0,488,492,3,91,45,0,489,491,5,32,0,0,490,489,1,0,0,0,491,494,1,0, + 0,0,492,490,1,0,0,0,492,493,1,0,0,0,493,495,1,0,0,0,494,492,1,0, + 0,0,495,496,3,107,53,0,496,498,1,0,0,0,497,488,1,0,0,0,498,501,1, + 0,0,0,499,497,1,0,0,0,499,500,1,0,0,0,500,502,1,0,0,0,501,499,1, + 0,0,0,502,503,3,85,42,0,503,504,7,9,0,0,504,516,1,0,0,0,505,507, + 3,101,50,0,506,505,1,0,0,0,506,507,1,0,0,0,507,509,1,0,0,0,508,510, + 3,99,49,0,509,508,1,0,0,0,510,511,1,0,0,0,511,509,1,0,0,0,511,512, + 1,0,0,0,512,513,1,0,0,0,513,514,7,9,0,0,514,516,1,0,0,0,515,467, + 1,0,0,0,515,468,1,0,0,0,515,486,1,0,0,0,515,506,1,0,0,0,516,118, + 1,0,0,0,517,518,3,123,61,0,518,519,7,9,0,0,519,120,1,0,0,0,520,524, + 7,29,0,0,521,523,7,30,0,0,522,521,1,0,0,0,523,526,1,0,0,0,524,522, + 1,0,0,0,524,525,1,0,0,0,525,122,1,0,0,0,526,524,1,0,0,0,527,535, + 5,34,0,0,528,529,5,92,0,0,529,534,9,0,0,0,530,531,5,34,0,0,531,534, + 5,34,0,0,532,534,8,31,0,0,533,528,1,0,0,0,533,530,1,0,0,0,533,532, + 1,0,0,0,534,537,1,0,0,0,535,533,1,0,0,0,535,536,1,0,0,0,536,538, + 1,0,0,0,537,535,1,0,0,0,538,539,5,34,0,0,539,124,1,0,0,0,540,542, + 7,32,0,0,541,540,1,0,0,0,542,543,1,0,0,0,543,541,1,0,0,0,543,544, + 1,0,0,0,544,547,1,0,0,0,545,547,3,93,46,0,546,541,1,0,0,0,546,545, + 1,0,0,0,547,548,1,0,0,0,548,549,6,62,0,0,549,126,1,0,0,0,550,552, + 5,13,0,0,551,550,1,0,0,0,551,552,1,0,0,0,552,553,1,0,0,0,553,554, + 5,10,0,0,554,128,1,0,0,0,36,0,334,345,348,377,382,387,390,395,401, + 405,411,413,419,421,428,433,439,444,446,458,462,465,474,481,492, + 499,506,511,515,524,533,535,543,546,551,1,6,0,0 ] class qutes_lexer(Lexer): @@ -239,47 +242,48 @@ class qutes_lexer(Lexer): PAULIZ = 14 GROVER = 15 MCZ = 16 - HADAMARD = 17 - MEASURE = 18 - PRINT = 19 - BARRIER = 20 - EQUAL = 21 - GREATER = 22 - GREATEREQUAL = 23 - LOWER = 24 - LOWEREQUAL = 25 - ASSIGN = 26 - END_OF_STATEMENT = 27 - VAR_STATEMENT = 28 - FOR_STATEMENT = 29 - SEARCH_STATEMENT = 30 - IN_STATEMENT = 31 - WHERE_STATEMENT = 32 - IF_STATEMENT = 33 - ELSE_STATEMENT = 34 - WHILE_STATEMENT = 35 - DO_STATEMENT = 36 - CURLY_PARENTHESIS_OPEN = 37 - CURLY_PARENTHESIS_CLOSE = 38 - ROUND_PARENTHESIS_OPEN = 39 - ROUND_PARENTHESIS_CLOSE = 40 - SQUARE_PARENTHESIS_OPEN = 41 - SQUARE_PARENTHESIS_CLOSE = 42 - DOT = 43 - STRING_ENCLOSURE = 44 - COMMA = 45 - BOOL_LITERAL = 46 - INT_LITERAL = 47 - FLOAT_LITERAL = 48 - HEX_LITERAL = 49 - BIN_LITERAL = 50 - QUBIT_LITERAL = 51 - QUINT_LITERAL = 52 - QUSTRING_LITERAL = 53 - SYMBOL_LITERAL = 54 - STRING_LITERAL = 55 - WS = 56 - NEWLINE = 57 + MCX = 17 + HADAMARD = 18 + MEASURE = 19 + PRINT = 20 + BARRIER = 21 + EQUAL = 22 + GREATER = 23 + GREATEREQUAL = 24 + LOWER = 25 + LOWEREQUAL = 26 + ASSIGN = 27 + END_OF_STATEMENT = 28 + VAR_STATEMENT = 29 + FOR_STATEMENT = 30 + SEARCH_STATEMENT = 31 + IN_STATEMENT = 32 + WHERE_STATEMENT = 33 + IF_STATEMENT = 34 + ELSE_STATEMENT = 35 + WHILE_STATEMENT = 36 + DO_STATEMENT = 37 + CURLY_PARENTHESIS_OPEN = 38 + CURLY_PARENTHESIS_CLOSE = 39 + ROUND_PARENTHESIS_OPEN = 40 + ROUND_PARENTHESIS_CLOSE = 41 + SQUARE_PARENTHESIS_OPEN = 42 + SQUARE_PARENTHESIS_CLOSE = 43 + DOT = 44 + STRING_ENCLOSURE = 45 + COMMA = 46 + BOOL_LITERAL = 47 + INT_LITERAL = 48 + FLOAT_LITERAL = 49 + HEX_LITERAL = 50 + BIN_LITERAL = 51 + QUBIT_LITERAL = 52 + QUINT_LITERAL = 53 + QUSTRING_LITERAL = 54 + SYMBOL_LITERAL = 55 + STRING_LITERAL = 56 + WS = 57 + NEWLINE = 58 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] @@ -288,7 +292,7 @@ class qutes_lexer(Lexer): literalNames = [ "", "'int'", "'bool'", "'string'", "'qubit'", "'quint'", "'qustring'", "'float'", "'void'", "'return'", "'+'", "'-'", "'not'", "'pauliy'", - "'pauliz'", "'grover'", "'mcz'", "'hadamard'", "'measure'", + "'pauliz'", "'grover'", "'mcz'", "'mcx'", "'hadamard'", "'measure'", "'print'", "'barrier'", "'=='", "'>'", "'>='", "'<'", "'<='", "'='", "';'", "'var'", "'for'", "'search'", "'in'", "'where'", "'if'", "'else'", "'while'", "'do'", "'{'", "'}'", "'('", "')'", @@ -297,7 +301,7 @@ class qutes_lexer(Lexer): symbolicNames = [ "", "INT_TYPE", "BOOL_TYPE", "STRING_TYPE", "QUBIT_TYPE", "QUINT_TYPE", "QUSTRING_TYPE", "FLOAT_TYPE", "VOID_TYPE", "RETURN", "ADD", - "SUB", "NOT", "PAULIY", "PAULIZ", "GROVER", "MCZ", "HADAMARD", + "SUB", "NOT", "PAULIY", "PAULIZ", "GROVER", "MCZ", "MCX", "HADAMARD", "MEASURE", "PRINT", "BARRIER", "EQUAL", "GREATER", "GREATEREQUAL", "LOWER", "LOWEREQUAL", "ASSIGN", "END_OF_STATEMENT", "VAR_STATEMENT", "FOR_STATEMENT", "SEARCH_STATEMENT", "IN_STATEMENT", "WHERE_STATEMENT", @@ -312,9 +316,9 @@ class qutes_lexer(Lexer): ruleNames = [ "INT_TYPE", "BOOL_TYPE", "STRING_TYPE", "QUBIT_TYPE", "QUINT_TYPE", "QUSTRING_TYPE", "FLOAT_TYPE", "VOID_TYPE", "RETURN", "ADD", "SUB", "NOT", "PAULIY", "PAULIZ", "GROVER", - "MCZ", "HADAMARD", "MEASURE", "PRINT", "BARRIER", "EQUAL", - "GREATER", "GREATEREQUAL", "LOWER", "LOWEREQUAL", "ASSIGN", - "END_OF_STATEMENT", "VAR_STATEMENT", "FOR_STATEMENT", + "MCZ", "MCX", "HADAMARD", "MEASURE", "PRINT", "BARRIER", + "EQUAL", "GREATER", "GREATEREQUAL", "LOWER", "LOWEREQUAL", + "ASSIGN", "END_OF_STATEMENT", "VAR_STATEMENT", "FOR_STATEMENT", "SEARCH_STATEMENT", "IN_STATEMENT", "WHERE_STATEMENT", "IF_STATEMENT", "ELSE_STATEMENT", "WHILE_STATEMENT", "DO_STATEMENT", "CURLY_PARENTHESIS_OPEN", "CURLY_PARENTHESIS_CLOSE", "ROUND_PARENTHESIS_OPEN", diff --git a/src/qutes_antlr/qutes_lexer.tokens b/src/qutes_antlr/qutes_lexer.tokens index af68929..c9df756 100644 --- a/src/qutes_antlr/qutes_lexer.tokens +++ b/src/qutes_antlr/qutes_lexer.tokens @@ -14,47 +14,48 @@ PAULIY=13 PAULIZ=14 GROVER=15 MCZ=16 -HADAMARD=17 -MEASURE=18 -PRINT=19 -BARRIER=20 -EQUAL=21 -GREATER=22 -GREATEREQUAL=23 -LOWER=24 -LOWEREQUAL=25 -ASSIGN=26 -END_OF_STATEMENT=27 -VAR_STATEMENT=28 -FOR_STATEMENT=29 -SEARCH_STATEMENT=30 -IN_STATEMENT=31 -WHERE_STATEMENT=32 -IF_STATEMENT=33 -ELSE_STATEMENT=34 -WHILE_STATEMENT=35 -DO_STATEMENT=36 -CURLY_PARENTHESIS_OPEN=37 -CURLY_PARENTHESIS_CLOSE=38 -ROUND_PARENTHESIS_OPEN=39 -ROUND_PARENTHESIS_CLOSE=40 -SQUARE_PARENTHESIS_OPEN=41 -SQUARE_PARENTHESIS_CLOSE=42 -DOT=43 -STRING_ENCLOSURE=44 -COMMA=45 -BOOL_LITERAL=46 -INT_LITERAL=47 -FLOAT_LITERAL=48 -HEX_LITERAL=49 -BIN_LITERAL=50 -QUBIT_LITERAL=51 -QUINT_LITERAL=52 -QUSTRING_LITERAL=53 -SYMBOL_LITERAL=54 -STRING_LITERAL=55 -WS=56 -NEWLINE=57 +MCX=17 +HADAMARD=18 +MEASURE=19 +PRINT=20 +BARRIER=21 +EQUAL=22 +GREATER=23 +GREATEREQUAL=24 +LOWER=25 +LOWEREQUAL=26 +ASSIGN=27 +END_OF_STATEMENT=28 +VAR_STATEMENT=29 +FOR_STATEMENT=30 +SEARCH_STATEMENT=31 +IN_STATEMENT=32 +WHERE_STATEMENT=33 +IF_STATEMENT=34 +ELSE_STATEMENT=35 +WHILE_STATEMENT=36 +DO_STATEMENT=37 +CURLY_PARENTHESIS_OPEN=38 +CURLY_PARENTHESIS_CLOSE=39 +ROUND_PARENTHESIS_OPEN=40 +ROUND_PARENTHESIS_CLOSE=41 +SQUARE_PARENTHESIS_OPEN=42 +SQUARE_PARENTHESIS_CLOSE=43 +DOT=44 +STRING_ENCLOSURE=45 +COMMA=46 +BOOL_LITERAL=47 +INT_LITERAL=48 +FLOAT_LITERAL=49 +HEX_LITERAL=50 +BIN_LITERAL=51 +QUBIT_LITERAL=52 +QUINT_LITERAL=53 +QUSTRING_LITERAL=54 +SYMBOL_LITERAL=55 +STRING_LITERAL=56 +WS=57 +NEWLINE=58 'int'=1 'bool'=2 'string'=3 @@ -71,32 +72,33 @@ NEWLINE=57 'pauliz'=14 'grover'=15 'mcz'=16 -'hadamard'=17 -'measure'=18 -'print'=19 -'barrier'=20 -'=='=21 -'>'=22 -'>='=23 -'<'=24 -'<='=25 -'='=26 -';'=27 -'var'=28 -'for'=29 -'search'=30 -'in'=31 -'where'=32 -'if'=33 -'else'=34 -'while'=35 -'do'=36 -'{'=37 -'}'=38 -'('=39 -')'=40 -'['=41 -']'=42 -'.'=43 -'"'=44 -','=45 +'mcx'=17 +'hadamard'=18 +'measure'=19 +'print'=20 +'barrier'=21 +'=='=22 +'>'=23 +'>='=24 +'<'=25 +'<='=26 +'='=27 +';'=28 +'var'=29 +'for'=30 +'search'=31 +'in'=32 +'where'=33 +'if'=34 +'else'=35 +'while'=36 +'do'=37 +'{'=38 +'}'=39 +'('=40 +')'=41 +'['=42 +']'=43 +'.'=44 +'"'=45 +','=46 diff --git a/src/qutes_antlr/qutes_parser.py b/src/qutes_antlr/qutes_parser.py index 9c692cb..22c5100 100644 --- a/src/qutes_antlr/qutes_parser.py +++ b/src/qutes_antlr/qutes_parser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,57,224,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,58,224,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,1,0,5,0,52,8,0,10,0, @@ -28,66 +28,66 @@ def serializedATN(): 8,15,10,15,12,15,204,9,15,1,16,1,16,1,17,1,17,1,18,1,18,1,19,1,19, 1,20,1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,24,0,1,22,25, 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44, - 46,48,0,5,1,0,21,25,2,0,10,14,17,19,1,0,10,11,1,0,1,8,2,0,47,47, - 49,50,235,0,53,1,0,0,0,2,103,1,0,0,0,4,105,1,0,0,0,6,114,1,0,0,0, - 8,119,1,0,0,0,10,125,1,0,0,0,12,135,1,0,0,0,14,137,1,0,0,0,16,141, - 1,0,0,0,18,148,1,0,0,0,20,157,1,0,0,0,22,176,1,0,0,0,24,186,1,0, - 0,0,26,191,1,0,0,0,28,195,1,0,0,0,30,197,1,0,0,0,32,205,1,0,0,0, - 34,207,1,0,0,0,36,209,1,0,0,0,38,211,1,0,0,0,40,213,1,0,0,0,42,215, - 1,0,0,0,44,217,1,0,0,0,46,219,1,0,0,0,48,221,1,0,0,0,50,52,3,2,1, - 0,51,50,1,0,0,0,52,55,1,0,0,0,53,51,1,0,0,0,53,54,1,0,0,0,54,56, - 1,0,0,0,55,53,1,0,0,0,56,57,5,0,0,1,57,1,1,0,0,0,58,59,5,33,0,0, - 59,60,3,12,6,0,60,61,3,2,1,0,61,104,1,0,0,0,62,63,5,33,0,0,63,64, - 3,12,6,0,64,65,3,2,1,0,65,66,5,34,0,0,66,67,3,2,1,0,67,104,1,0,0, - 0,68,69,5,35,0,0,69,70,3,12,6,0,70,71,3,2,1,0,71,104,1,0,0,0,72, - 73,5,36,0,0,73,74,3,2,1,0,74,75,5,35,0,0,75,76,3,12,6,0,76,104,1, - 0,0,0,77,104,3,4,2,0,78,79,3,28,14,0,79,80,3,34,17,0,80,82,5,39, - 0,0,81,83,3,6,3,0,82,81,1,0,0,0,82,83,1,0,0,0,83,84,1,0,0,0,84,85, - 5,40,0,0,85,86,3,2,1,0,86,104,1,0,0,0,87,88,3,8,4,0,88,89,5,27,0, - 0,89,104,1,0,0,0,90,91,3,30,15,0,91,92,5,26,0,0,92,93,3,12,6,0,93, - 94,5,27,0,0,94,104,1,0,0,0,95,96,5,9,0,0,96,97,3,12,6,0,97,98,5, - 27,0,0,98,104,1,0,0,0,99,100,3,12,6,0,100,101,5,27,0,0,101,104,1, - 0,0,0,102,104,5,27,0,0,103,58,1,0,0,0,103,62,1,0,0,0,103,68,1,0, - 0,0,103,72,1,0,0,0,103,77,1,0,0,0,103,78,1,0,0,0,103,87,1,0,0,0, - 103,90,1,0,0,0,103,95,1,0,0,0,103,99,1,0,0,0,103,102,1,0,0,0,104, - 3,1,0,0,0,105,109,5,37,0,0,106,108,3,2,1,0,107,106,1,0,0,0,108,111, - 1,0,0,0,109,107,1,0,0,0,109,110,1,0,0,0,110,112,1,0,0,0,111,109, - 1,0,0,0,112,113,5,38,0,0,113,5,1,0,0,0,114,117,3,8,4,0,115,116,5, - 45,0,0,116,118,3,6,3,0,117,115,1,0,0,0,117,118,1,0,0,0,118,7,1,0, - 0,0,119,120,3,28,14,0,120,123,3,32,16,0,121,122,5,26,0,0,122,124, - 3,12,6,0,123,121,1,0,0,0,123,124,1,0,0,0,124,9,1,0,0,0,125,128,3, - 30,15,0,126,127,5,45,0,0,127,129,3,10,5,0,128,126,1,0,0,0,128,129, - 1,0,0,0,129,11,1,0,0,0,130,136,3,22,11,0,131,136,3,16,8,0,132,136, - 3,20,10,0,133,136,3,18,9,0,134,136,3,14,7,0,135,130,1,0,0,0,135, - 131,1,0,0,0,135,132,1,0,0,0,135,133,1,0,0,0,135,134,1,0,0,0,136, - 13,1,0,0,0,137,138,3,24,12,0,138,139,5,31,0,0,139,140,3,30,15,0, - 140,15,1,0,0,0,141,142,3,34,17,0,142,144,5,39,0,0,143,145,3,10,5, - 0,144,143,1,0,0,0,144,145,1,0,0,0,145,146,1,0,0,0,146,147,5,40,0, - 0,147,17,1,0,0,0,148,149,5,39,0,0,149,150,3,12,6,0,150,151,5,40, - 0,0,151,19,1,0,0,0,152,158,3,22,11,0,153,154,3,22,11,0,154,155,7, - 0,0,0,155,156,3,22,11,0,156,158,1,0,0,0,157,152,1,0,0,0,157,153, - 1,0,0,0,158,21,1,0,0,0,159,160,6,11,-1,0,160,161,7,1,0,0,161,177, - 3,22,11,3,162,163,5,16,0,0,163,177,3,24,12,0,164,175,3,48,24,0,165, - 175,3,46,23,0,166,175,3,44,22,0,167,175,3,38,19,0,168,175,3,40,20, - 0,169,175,3,42,21,0,170,175,3,30,15,0,171,175,5,18,0,0,172,175,5, - 20,0,0,173,175,3,36,18,0,174,164,1,0,0,0,174,165,1,0,0,0,174,166, - 1,0,0,0,174,167,1,0,0,0,174,168,1,0,0,0,174,169,1,0,0,0,174,170, - 1,0,0,0,174,171,1,0,0,0,174,172,1,0,0,0,174,173,1,0,0,0,175,177, - 1,0,0,0,176,159,1,0,0,0,176,162,1,0,0,0,176,174,1,0,0,0,177,183, - 1,0,0,0,178,179,10,4,0,0,179,180,7,2,0,0,180,182,3,22,11,5,181,178, - 1,0,0,0,182,185,1,0,0,0,183,181,1,0,0,0,183,184,1,0,0,0,184,23,1, - 0,0,0,185,183,1,0,0,0,186,189,3,22,11,0,187,188,5,45,0,0,188,190, - 3,24,12,0,189,187,1,0,0,0,189,190,1,0,0,0,190,25,1,0,0,0,191,192, - 7,3,0,0,192,27,1,0,0,0,193,196,3,26,13,0,194,196,3,30,15,0,195,193, - 1,0,0,0,195,194,1,0,0,0,196,29,1,0,0,0,197,202,5,54,0,0,198,199, - 5,43,0,0,199,201,5,54,0,0,200,198,1,0,0,0,201,204,1,0,0,0,202,200, - 1,0,0,0,202,203,1,0,0,0,203,31,1,0,0,0,204,202,1,0,0,0,205,206,5, - 54,0,0,206,33,1,0,0,0,207,208,5,54,0,0,208,35,1,0,0,0,209,210,5, - 55,0,0,210,37,1,0,0,0,211,212,5,51,0,0,212,39,1,0,0,0,213,214,5, - 52,0,0,214,41,1,0,0,0,215,216,5,53,0,0,216,43,1,0,0,0,217,218,5, - 48,0,0,218,45,1,0,0,0,219,220,7,4,0,0,220,47,1,0,0,0,221,222,5,46, - 0,0,222,49,1,0,0,0,16,53,82,103,109,117,123,128,135,144,157,174, - 176,183,189,195,202 + 46,48,0,6,1,0,22,26,2,0,10,14,18,20,1,0,16,17,1,0,10,11,1,0,1,8, + 2,0,48,48,50,51,235,0,53,1,0,0,0,2,103,1,0,0,0,4,105,1,0,0,0,6,114, + 1,0,0,0,8,119,1,0,0,0,10,125,1,0,0,0,12,135,1,0,0,0,14,137,1,0,0, + 0,16,141,1,0,0,0,18,148,1,0,0,0,20,157,1,0,0,0,22,176,1,0,0,0,24, + 186,1,0,0,0,26,191,1,0,0,0,28,195,1,0,0,0,30,197,1,0,0,0,32,205, + 1,0,0,0,34,207,1,0,0,0,36,209,1,0,0,0,38,211,1,0,0,0,40,213,1,0, + 0,0,42,215,1,0,0,0,44,217,1,0,0,0,46,219,1,0,0,0,48,221,1,0,0,0, + 50,52,3,2,1,0,51,50,1,0,0,0,52,55,1,0,0,0,53,51,1,0,0,0,53,54,1, + 0,0,0,54,56,1,0,0,0,55,53,1,0,0,0,56,57,5,0,0,1,57,1,1,0,0,0,58, + 59,5,34,0,0,59,60,3,12,6,0,60,61,3,2,1,0,61,104,1,0,0,0,62,63,5, + 34,0,0,63,64,3,12,6,0,64,65,3,2,1,0,65,66,5,35,0,0,66,67,3,2,1,0, + 67,104,1,0,0,0,68,69,5,36,0,0,69,70,3,12,6,0,70,71,3,2,1,0,71,104, + 1,0,0,0,72,73,5,37,0,0,73,74,3,2,1,0,74,75,5,36,0,0,75,76,3,12,6, + 0,76,104,1,0,0,0,77,104,3,4,2,0,78,79,3,28,14,0,79,80,3,34,17,0, + 80,82,5,40,0,0,81,83,3,6,3,0,82,81,1,0,0,0,82,83,1,0,0,0,83,84,1, + 0,0,0,84,85,5,41,0,0,85,86,3,2,1,0,86,104,1,0,0,0,87,88,3,8,4,0, + 88,89,5,28,0,0,89,104,1,0,0,0,90,91,3,30,15,0,91,92,5,27,0,0,92, + 93,3,12,6,0,93,94,5,28,0,0,94,104,1,0,0,0,95,96,5,9,0,0,96,97,3, + 12,6,0,97,98,5,28,0,0,98,104,1,0,0,0,99,100,3,12,6,0,100,101,5,28, + 0,0,101,104,1,0,0,0,102,104,5,28,0,0,103,58,1,0,0,0,103,62,1,0,0, + 0,103,68,1,0,0,0,103,72,1,0,0,0,103,77,1,0,0,0,103,78,1,0,0,0,103, + 87,1,0,0,0,103,90,1,0,0,0,103,95,1,0,0,0,103,99,1,0,0,0,103,102, + 1,0,0,0,104,3,1,0,0,0,105,109,5,38,0,0,106,108,3,2,1,0,107,106,1, + 0,0,0,108,111,1,0,0,0,109,107,1,0,0,0,109,110,1,0,0,0,110,112,1, + 0,0,0,111,109,1,0,0,0,112,113,5,39,0,0,113,5,1,0,0,0,114,117,3,8, + 4,0,115,116,5,46,0,0,116,118,3,6,3,0,117,115,1,0,0,0,117,118,1,0, + 0,0,118,7,1,0,0,0,119,120,3,28,14,0,120,123,3,32,16,0,121,122,5, + 27,0,0,122,124,3,12,6,0,123,121,1,0,0,0,123,124,1,0,0,0,124,9,1, + 0,0,0,125,128,3,30,15,0,126,127,5,46,0,0,127,129,3,10,5,0,128,126, + 1,0,0,0,128,129,1,0,0,0,129,11,1,0,0,0,130,136,3,22,11,0,131,136, + 3,16,8,0,132,136,3,20,10,0,133,136,3,18,9,0,134,136,3,14,7,0,135, + 130,1,0,0,0,135,131,1,0,0,0,135,132,1,0,0,0,135,133,1,0,0,0,135, + 134,1,0,0,0,136,13,1,0,0,0,137,138,3,24,12,0,138,139,5,32,0,0,139, + 140,3,30,15,0,140,15,1,0,0,0,141,142,3,34,17,0,142,144,5,40,0,0, + 143,145,3,10,5,0,144,143,1,0,0,0,144,145,1,0,0,0,145,146,1,0,0,0, + 146,147,5,41,0,0,147,17,1,0,0,0,148,149,5,40,0,0,149,150,3,12,6, + 0,150,151,5,41,0,0,151,19,1,0,0,0,152,158,3,22,11,0,153,154,3,22, + 11,0,154,155,7,0,0,0,155,156,3,22,11,0,156,158,1,0,0,0,157,152,1, + 0,0,0,157,153,1,0,0,0,158,21,1,0,0,0,159,160,6,11,-1,0,160,161,7, + 1,0,0,161,177,3,22,11,3,162,163,7,2,0,0,163,177,3,24,12,0,164,175, + 3,48,24,0,165,175,3,46,23,0,166,175,3,44,22,0,167,175,3,38,19,0, + 168,175,3,40,20,0,169,175,3,42,21,0,170,175,3,30,15,0,171,175,5, + 19,0,0,172,175,5,21,0,0,173,175,3,36,18,0,174,164,1,0,0,0,174,165, + 1,0,0,0,174,166,1,0,0,0,174,167,1,0,0,0,174,168,1,0,0,0,174,169, + 1,0,0,0,174,170,1,0,0,0,174,171,1,0,0,0,174,172,1,0,0,0,174,173, + 1,0,0,0,175,177,1,0,0,0,176,159,1,0,0,0,176,162,1,0,0,0,176,174, + 1,0,0,0,177,183,1,0,0,0,178,179,10,4,0,0,179,180,7,3,0,0,180,182, + 3,22,11,5,181,178,1,0,0,0,182,185,1,0,0,0,183,181,1,0,0,0,183,184, + 1,0,0,0,184,23,1,0,0,0,185,183,1,0,0,0,186,189,3,22,11,0,187,188, + 5,46,0,0,188,190,3,24,12,0,189,187,1,0,0,0,189,190,1,0,0,0,190,25, + 1,0,0,0,191,192,7,4,0,0,192,27,1,0,0,0,193,196,3,26,13,0,194,196, + 3,30,15,0,195,193,1,0,0,0,195,194,1,0,0,0,196,29,1,0,0,0,197,202, + 5,55,0,0,198,199,5,44,0,0,199,201,5,55,0,0,200,198,1,0,0,0,201,204, + 1,0,0,0,202,200,1,0,0,0,202,203,1,0,0,0,203,31,1,0,0,0,204,202,1, + 0,0,0,205,206,5,55,0,0,206,33,1,0,0,0,207,208,5,55,0,0,208,35,1, + 0,0,0,209,210,5,56,0,0,210,37,1,0,0,0,211,212,5,52,0,0,212,39,1, + 0,0,0,213,214,5,53,0,0,214,41,1,0,0,0,215,216,5,54,0,0,216,43,1, + 0,0,0,217,218,5,49,0,0,218,45,1,0,0,0,219,220,7,5,0,0,220,47,1,0, + 0,0,221,222,5,47,0,0,222,49,1,0,0,0,16,53,82,103,109,117,123,128, + 135,144,157,174,176,183,189,195,202 ] class qutes_parser ( Parser ): @@ -103,16 +103,16 @@ class qutes_parser ( Parser ): literalNames = [ "", "'int'", "'bool'", "'string'", "'qubit'", "'quint'", "'qustring'", "'float'", "'void'", "'return'", "'+'", "'-'", "'not'", "'pauliy'", "'pauliz'", "'grover'", - "'mcz'", "'hadamard'", "'measure'", "'print'", "'barrier'", - "'=='", "'>'", "'>='", "'<'", "'<='", "'='", "';'", - "'var'", "'for'", "'search'", "'in'", "'where'", "'if'", - "'else'", "'while'", "'do'", "'{'", "'}'", "'('", "')'", - "'['", "']'", "'.'", "'\"'", "','" ] + "'mcz'", "'mcx'", "'hadamard'", "'measure'", "'print'", + "'barrier'", "'=='", "'>'", "'>='", "'<'", "'<='", + "'='", "';'", "'var'", "'for'", "'search'", "'in'", + "'where'", "'if'", "'else'", "'while'", "'do'", "'{'", + "'}'", "'('", "')'", "'['", "']'", "'.'", "'\"'", "','" ] symbolicNames = [ "", "INT_TYPE", "BOOL_TYPE", "STRING_TYPE", "QUBIT_TYPE", "QUINT_TYPE", "QUSTRING_TYPE", "FLOAT_TYPE", "VOID_TYPE", "RETURN", "ADD", "SUB", "NOT", "PAULIY", - "PAULIZ", "GROVER", "MCZ", "HADAMARD", "MEASURE", + "PAULIZ", "GROVER", "MCZ", "MCX", "HADAMARD", "MEASURE", "PRINT", "BARRIER", "EQUAL", "GREATER", "GREATEREQUAL", "LOWER", "LOWEREQUAL", "ASSIGN", "END_OF_STATEMENT", "VAR_STATEMENT", "FOR_STATEMENT", "SEARCH_STATEMENT", @@ -176,47 +176,48 @@ class qutes_parser ( Parser ): PAULIZ=14 GROVER=15 MCZ=16 - HADAMARD=17 - MEASURE=18 - PRINT=19 - BARRIER=20 - EQUAL=21 - GREATER=22 - GREATEREQUAL=23 - LOWER=24 - LOWEREQUAL=25 - ASSIGN=26 - END_OF_STATEMENT=27 - VAR_STATEMENT=28 - FOR_STATEMENT=29 - SEARCH_STATEMENT=30 - IN_STATEMENT=31 - WHERE_STATEMENT=32 - IF_STATEMENT=33 - ELSE_STATEMENT=34 - WHILE_STATEMENT=35 - DO_STATEMENT=36 - CURLY_PARENTHESIS_OPEN=37 - CURLY_PARENTHESIS_CLOSE=38 - ROUND_PARENTHESIS_OPEN=39 - ROUND_PARENTHESIS_CLOSE=40 - SQUARE_PARENTHESIS_OPEN=41 - SQUARE_PARENTHESIS_CLOSE=42 - DOT=43 - STRING_ENCLOSURE=44 - COMMA=45 - BOOL_LITERAL=46 - INT_LITERAL=47 - FLOAT_LITERAL=48 - HEX_LITERAL=49 - BIN_LITERAL=50 - QUBIT_LITERAL=51 - QUINT_LITERAL=52 - QUSTRING_LITERAL=53 - SYMBOL_LITERAL=54 - STRING_LITERAL=55 - WS=56 - NEWLINE=57 + MCX=17 + HADAMARD=18 + MEASURE=19 + PRINT=20 + BARRIER=21 + EQUAL=22 + GREATER=23 + GREATEREQUAL=24 + LOWER=25 + LOWEREQUAL=26 + ASSIGN=27 + END_OF_STATEMENT=28 + VAR_STATEMENT=29 + FOR_STATEMENT=30 + SEARCH_STATEMENT=31 + IN_STATEMENT=32 + WHERE_STATEMENT=33 + IF_STATEMENT=34 + ELSE_STATEMENT=35 + WHILE_STATEMENT=36 + DO_STATEMENT=37 + CURLY_PARENTHESIS_OPEN=38 + CURLY_PARENTHESIS_CLOSE=39 + ROUND_PARENTHESIS_OPEN=40 + ROUND_PARENTHESIS_CLOSE=41 + SQUARE_PARENTHESIS_OPEN=42 + SQUARE_PARENTHESIS_CLOSE=43 + DOT=44 + STRING_ENCLOSURE=45 + COMMA=46 + BOOL_LITERAL=47 + INT_LITERAL=48 + FLOAT_LITERAL=49 + HEX_LITERAL=50 + BIN_LITERAL=51 + QUBIT_LITERAL=52 + QUINT_LITERAL=53 + QUSTRING_LITERAL=54 + SYMBOL_LITERAL=55 + STRING_LITERAL=56 + WS=57 + NEWLINE=58 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) @@ -274,7 +275,7 @@ def program(self): self.state = 53 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 71988024293949438) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 143976048587931646) != 0): self.state = 50 self.statement() self.state = 55 @@ -717,7 +718,7 @@ def statement(self): self.state = 82 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 18014398509482494) != 0): + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 36028797018964478) != 0): self.state = 81 self.functionDeclarationParams() @@ -839,7 +840,7 @@ def block(self): self.state = 109 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 71988024293949438) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 143976048587931646) != 0): self.state = 106 self.statement() self.state = 111 @@ -907,7 +908,7 @@ def functionDeclarationParams(self): self.state = 117 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==45: + if _la==46: self.state = 115 self.match(qutes_parser.COMMA) self.state = 116 @@ -979,7 +980,7 @@ def variableDeclaration(self): self.state = 123 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==26: + if _la==27: self.state = 121 self.match(qutes_parser.ASSIGN) self.state = 122 @@ -1045,7 +1046,7 @@ def functionCallParams(self): self.state = 128 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==45: + if _la==46: self.state = 126 self.match(qutes_parser.COMMA) self.state = 127 @@ -1271,7 +1272,7 @@ def functionCall(self): self.state = 144 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==54: + if _la==55: self.state = 143 self.functionCallParams() @@ -1417,7 +1418,7 @@ def test(self): self.state = 154 localctx.op = self._input.LT(1) _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 65011712) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 130023424) != 0)): localctx.op = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1462,6 +1463,8 @@ def __init__(self, parser, ctx:ParserRuleContext): # actually a qutes_parser.Ter def termList(self): return self.getTypedRuleContext(qutes_parser.TermListContext,0) + def MCX(self): + return self.getToken(qutes_parser.MCX, 0) def MCZ(self): return self.getToken(qutes_parser.MCZ, 0) @@ -1627,7 +1630,7 @@ def term(self, _p:int=0): self.state = 160 localctx.op = self._input.LT(1) _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 949248) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 1866752) != 0)): localctx.op = self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1641,7 +1644,13 @@ def term(self, _p:int=0): self._ctx = localctx _prevctx = localctx self.state = 162 - localctx.op = self.match(qutes_parser.MCZ) + localctx.op = self._input.LT(1) + _la = self._input.LA(1) + if not(_la==16 or _la==17): + localctx.op = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() self.state = 163 self.termList() pass @@ -1653,43 +1662,43 @@ def term(self, _p:int=0): self.state = 174 self._errHandler.sync(self) token = self._input.LA(1) - if token in [46]: + if token in [47]: self.state = 164 self.boolean() pass - elif token in [47, 49, 50]: + elif token in [48, 50, 51]: self.state = 165 self.integer() pass - elif token in [48]: + elif token in [49]: self.state = 166 self.float_() pass - elif token in [51]: + elif token in [52]: self.state = 167 self.qubit() pass - elif token in [52]: + elif token in [53]: self.state = 168 self.quint() pass - elif token in [53]: + elif token in [54]: self.state = 169 self.qustring() pass - elif token in [54]: + elif token in [55]: self.state = 170 self.qualifiedName() pass - elif token in [18]: + elif token in [19]: self.state = 171 self.match(qutes_parser.MEASURE) pass - elif token in [20]: + elif token in [21]: self.state = 172 self.match(qutes_parser.BARRIER) pass - elif token in [55]: + elif token in [56]: self.state = 173 self.string() pass @@ -1924,7 +1933,7 @@ def variableType(self): self.state = 193 self.type_() pass - elif token in [54]: + elif token in [55]: self.enterOuterAlt(localctx, 2) self.state = 194 self.qualifiedName() @@ -2384,7 +2393,7 @@ def integer(self): self.enterOuterAlt(localctx, 1) self.state = 219 _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 1829587348619264) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 3659174697238528) != 0)): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) diff --git a/src/qutes_antlr/qutes_parser.tokens b/src/qutes_antlr/qutes_parser.tokens index af68929..c9df756 100644 --- a/src/qutes_antlr/qutes_parser.tokens +++ b/src/qutes_antlr/qutes_parser.tokens @@ -14,47 +14,48 @@ PAULIY=13 PAULIZ=14 GROVER=15 MCZ=16 -HADAMARD=17 -MEASURE=18 -PRINT=19 -BARRIER=20 -EQUAL=21 -GREATER=22 -GREATEREQUAL=23 -LOWER=24 -LOWEREQUAL=25 -ASSIGN=26 -END_OF_STATEMENT=27 -VAR_STATEMENT=28 -FOR_STATEMENT=29 -SEARCH_STATEMENT=30 -IN_STATEMENT=31 -WHERE_STATEMENT=32 -IF_STATEMENT=33 -ELSE_STATEMENT=34 -WHILE_STATEMENT=35 -DO_STATEMENT=36 -CURLY_PARENTHESIS_OPEN=37 -CURLY_PARENTHESIS_CLOSE=38 -ROUND_PARENTHESIS_OPEN=39 -ROUND_PARENTHESIS_CLOSE=40 -SQUARE_PARENTHESIS_OPEN=41 -SQUARE_PARENTHESIS_CLOSE=42 -DOT=43 -STRING_ENCLOSURE=44 -COMMA=45 -BOOL_LITERAL=46 -INT_LITERAL=47 -FLOAT_LITERAL=48 -HEX_LITERAL=49 -BIN_LITERAL=50 -QUBIT_LITERAL=51 -QUINT_LITERAL=52 -QUSTRING_LITERAL=53 -SYMBOL_LITERAL=54 -STRING_LITERAL=55 -WS=56 -NEWLINE=57 +MCX=17 +HADAMARD=18 +MEASURE=19 +PRINT=20 +BARRIER=21 +EQUAL=22 +GREATER=23 +GREATEREQUAL=24 +LOWER=25 +LOWEREQUAL=26 +ASSIGN=27 +END_OF_STATEMENT=28 +VAR_STATEMENT=29 +FOR_STATEMENT=30 +SEARCH_STATEMENT=31 +IN_STATEMENT=32 +WHERE_STATEMENT=33 +IF_STATEMENT=34 +ELSE_STATEMENT=35 +WHILE_STATEMENT=36 +DO_STATEMENT=37 +CURLY_PARENTHESIS_OPEN=38 +CURLY_PARENTHESIS_CLOSE=39 +ROUND_PARENTHESIS_OPEN=40 +ROUND_PARENTHESIS_CLOSE=41 +SQUARE_PARENTHESIS_OPEN=42 +SQUARE_PARENTHESIS_CLOSE=43 +DOT=44 +STRING_ENCLOSURE=45 +COMMA=46 +BOOL_LITERAL=47 +INT_LITERAL=48 +FLOAT_LITERAL=49 +HEX_LITERAL=50 +BIN_LITERAL=51 +QUBIT_LITERAL=52 +QUINT_LITERAL=53 +QUSTRING_LITERAL=54 +SYMBOL_LITERAL=55 +STRING_LITERAL=56 +WS=57 +NEWLINE=58 'int'=1 'bool'=2 'string'=3 @@ -71,32 +72,33 @@ NEWLINE=57 'pauliz'=14 'grover'=15 'mcz'=16 -'hadamard'=17 -'measure'=18 -'print'=19 -'barrier'=20 -'=='=21 -'>'=22 -'>='=23 -'<'=24 -'<='=25 -'='=26 -';'=27 -'var'=28 -'for'=29 -'search'=30 -'in'=31 -'where'=32 -'if'=33 -'else'=34 -'while'=35 -'do'=36 -'{'=37 -'}'=38 -'('=39 -')'=40 -'['=41 -']'=42 -'.'=43 -'"'=44 -','=45 +'mcx'=17 +'hadamard'=18 +'measure'=19 +'print'=20 +'barrier'=21 +'=='=22 +'>'=23 +'>='=24 +'<'=25 +'<='=26 +'='=27 +';'=28 +'var'=29 +'for'=30 +'search'=31 +'in'=32 +'where'=33 +'if'=34 +'else'=35 +'while'=36 +'do'=37 +'{'=38 +'}'=39 +'('=40 +')'=41 +'['=42 +']'=43 +'.'=44 +'"'=45 +','=46 diff --git a/src/symbols/types/qutes_data_type.py b/src/symbols/types/qutes_data_type.py index a956b1c..11999be 100644 --- a/src/symbols/types/qutes_data_type.py +++ b/src/symbols/types/qutes_data_type.py @@ -33,7 +33,7 @@ def get_array_word_bit(type:str): return QutesDataType.get_array_word_bit(QutesDataType.from_string_type(type)) def is_array_type(type:'QutesDataType'): - return type in [QutesDataType.qustring] + return type in [QutesDataType.qustring, QutesDataType.quint] def get_array_word_bit(type:'QutesDataType'): match type: @@ -163,7 +163,7 @@ def __init__(self, quantum_cirtcuit_handler : 'QuantumCircuitHandler'): QutesDataType.bool: [QutesDataType.qubit, QutesDataType.bool], QutesDataType.int: [QutesDataType.quint, QutesDataType.qubit, QutesDataType.int], QutesDataType.float: [QutesDataType.quint, QutesDataType.qubit, QutesDataType.float, QutesDataType.int], - QutesDataType.string: [QutesDataType.string], + QutesDataType.string: [QutesDataType.qustring, QutesDataType.string], QutesDataType.qubit: [QutesDataType.qubit], QutesDataType.quint: [QutesDataType.quint], QutesDataType.qustring: [QutesDataType.qustring], @@ -173,7 +173,7 @@ def __init__(self, quantum_cirtcuit_handler : 'QuantumCircuitHandler'): def promote_value_to_type(self, var_value : any, from_type:'QutesDataType', to_type : 'QutesDataType', symbol_or_literal) -> any: match to_type: case QutesDataType.bool: - return bool(var_value) + return bool(int(var_value)) case QutesDataType.int: return int(var_value) case QutesDataType.float: @@ -193,7 +193,11 @@ def down_cast_value_to_type(self, var_value : any, from_type:'QutesDataType', to from symbols import Symbol from_type_value = None if QutesDataType.is_quantum_type(from_type): - from_type_value = self.quantum_cirtcuit_handler.get_run_and_measure_results(symbol_or_literal.quantum_register) + if(isinstance(symbol_or_literal, Symbol) and symbol_or_literal.is_anonymous): + from_type_value = symbol_or_literal.value.to_classical_type() + else: + from_type_value, _ = self.quantum_cirtcuit_handler.get_run_and_measure_result_for_quantum_var(symbol_or_literal.quantum_register) + if from_type_value == None and isinstance(symbol_or_literal, Symbol): from_type_value = symbol_or_literal.value.to_classical_type() @@ -202,7 +206,7 @@ def down_cast_value_to_type(self, var_value : any, from_type:'QutesDataType', to match to_type: case QutesDataType.bool: - return bool(from_type_value) + return bool(int(from_type_value)) case QutesDataType.int: return int(from_type_value) case QutesDataType.float: diff --git a/src/tests/qutes_base_test.py b/src/tests/qutes_base_test.py new file mode 100644 index 0000000..d667895 --- /dev/null +++ b/src/tests/qutes_base_test.py @@ -0,0 +1,48 @@ +import unittest +from antlr4 import CommonTokenStream, InputStream +from grammar_frontend.qutes_lexer import QutesLexer +from grammar_frontend.qutes_parser import QutesParser +from grammar_frontend.qutes_grammar_visitor import QutesGrammarVisitor +from grammar_frontend.symbols_discovery_visitor import SymbolsDiscoveryVisitor +from grammar_frontend.qutes_syntax_error_listener import QutesErrorListener +from symbols.scope_handler import ScopeHandlerForSymbolsUpdate +from symbols.variables_handler import VariablesHandler +from quantum_circuit import QuantumCircuitHandler + +class QutesTestResult: + def __init__(self, result, scope_handler:ScopeHandlerForSymbolsUpdate, variables_handler:VariablesHandler, quantum_circuit_handler:QuantumCircuitHandler): + self.result = result + self.scope_handler:ScopeHandlerForSymbolsUpdate = scope_handler + self.variables_handler:VariablesHandler = variables_handler + self.quantum_circuit_handler:QuantumCircuitHandler = quantum_circuit_handler + +class QutesBaseTest(unittest.TestCase): + TOKEN_AST_INDEX_FOR_TESTS = 100000 + + def parse_qutes_code(self, code:str) -> QutesTestResult: + input_stream = InputStream(code) + lexer = QutesLexer(input_stream) + lexer.removeErrorListeners() + lexer.addErrorListener(QutesErrorListener()) + + stream = CommonTokenStream(lexer) + parser = QutesParser(stream) + parser.removeErrorListeners() + parser.addErrorListener(QutesErrorListener()) + tree = parser.program() + + quantum_circuit_handler = QuantumCircuitHandler() + grammar_listener = SymbolsDiscoveryVisitor(quantum_circuit_handler) + grammar_listener.visit(tree) + symbols_tree = grammar_listener.scope_handler.symbols_tree + + scope_handler = ScopeHandlerForSymbolsUpdate(symbols_tree) + variables_handler = VariablesHandler(scope_handler, quantum_circuit_handler) + + grammar_visitor = QutesGrammarVisitor(symbols_tree, quantum_circuit_handler, scope_handler, variables_handler) + result = grammar_visitor.visit(tree) + + return QutesTestResult(result, scope_handler, variables_handler, quantum_circuit_handler) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/src/tests/test_grammar.py b/src/tests/test_grammar.py index 2b87e0c..55befc3 100644 --- a/src/tests/test_grammar.py +++ b/src/tests/test_grammar.py @@ -1,133 +1,167 @@ -import unittest -from parameterized import parameterized -from antlr4 import CommonTokenStream, InputStream -from grammar_frontend.qutes_lexer import QutesLexer -from grammar_frontend.qutes_parser import QutesParser -from grammar_frontend.qutes_grammar_visitor import QutesGrammarVisitor -from grammar_frontend.symbols_discovery_visitor import SymbolsDiscoveryVisitor -from symbols.scope_handler import ScopeHandlerForSymbolsUpdate -from symbols.variables_handler import VariablesHandler from symbols.types import Qubit, Quint, Qustring -from quantum_circuit import QuantumCircuitHandler - -class TestGrammarResult: - def __init__(self, result, scope_handler:ScopeHandlerForSymbolsUpdate, variables_handler:VariablesHandler, quantum_circuit_handler:QuantumCircuitHandler): - self.result = result - self.scope_handler:ScopeHandlerForSymbolsUpdate = scope_handler - self.variables_handler:VariablesHandler = variables_handler - self.quantum_circuit_handler:QuantumCircuitHandler = quantum_circuit_handler - -class TestGrammar(unittest.TestCase): - TOKEN_AST_INDEX_FOR_TESTS = 100000 - - def run_qutes_code(self, code:str) -> TestGrammarResult: - input_stream = InputStream(code) - lexer = QutesLexer(input_stream) - stream = CommonTokenStream(lexer) - parser = QutesParser(stream) - tree = parser.program() - - quantum_circuit_handler = QuantumCircuitHandler() - grammar_listener = SymbolsDiscoveryVisitor(quantum_circuit_handler) - grammar_listener.visit(tree) - symbols_tree = grammar_listener.scope_handler.symbols_tree - - scope_handler = ScopeHandlerForSymbolsUpdate(symbols_tree) - variables_handler = VariablesHandler(scope_handler, quantum_circuit_handler) - - grammar_visitor = QutesGrammarVisitor(symbols_tree, quantum_circuit_handler, scope_handler, variables_handler) - result = grammar_visitor.visit(tree) - - return TestGrammarResult(result, scope_handler, variables_handler, quantum_circuit_handler) - - @parameterized.expand([ - ["bool", "foo", "false", False], - ["bool", "foo", "0", False], - ["bool", "foo", "TRUE", True], - ["bool", "foo", "1", True], - ["bool", "foo", "1q", True], - ["bool", "foo", "0q", False], - ["int", "foo", "10", 10], - ["int", "foo", "false+false", 0], - ["int", "foo", "true+true", 2], - ["int", "foo", "10q", 10], - ["string", "foo", "\"test\"", "test"], - ["string", "foo", "\"test\" + \"sum\"", "testsum"], - ["string", "foo", "1", "True"], #TODO: We should expect "1" not "True" - ["string", "foo", "2", "2"], - ]) - def test_classic_type_declaration_succeed(self, var_type, var_name, declaration_value, expected_value_of_var): - code = f""" - {var_type} {var_name} = {declaration_value}; - """ - result = self.run_qutes_code(code) - actual_value_of_var = result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value - self.assertEquals(actual_value_of_var, expected_value_of_var, f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") +from .qutes_base_test import QutesBaseTest + +def sanitizeForVariableDeclarationUsage(value:any) -> str: + value = str(value) + return value.replace("\"", "").replace(" ", "") + +class TestGrammar(QutesBaseTest): + def test_var_declaration_with_allowed_char_succeed(self): + params = [ + ("a"), + ("A"), + ("z"), + ("Z"), + ("_"), + ("_1234"), + ("_1234asd"), + ("_1234asASASd"), + ("_sdas1234"), + ("_sdaASDASs1234"), + ("__sdas1234"), + ("__sdASaSas1234"), + ("asdf__23w"), + ("aASASdf__23wASSA"), + ("asdf1234r_"), + ("asdfASAS1234r_"), + ("asdf1234r__"), + ("asASSASdf1234r__"), + ] + for var_name in params: + with self.subTest(var_name=var_name): + code = f""" + bool {var_name}; + """ + self.parse_qutes_code(code) + + def test_var_declaration_with_unexpected_char_throws(self): + params = [ + ("1"), + ("121212"), + ("1221___"), + ("1221___1212"), + ("1221___asasa"), + ("1221asasa___"), + ("1221as___asa___"), + ("1221asassa_Asas"), + ("ass=asas"), + ("ass-asas"), + ("ass=-asas"), + ("ass(asas"), + ("ass*asas"), + ("ass&asas"), + ("&assasas"), + ("___&assasas"), + ("___assasas&"), + ] + for var_name in params: + with self.subTest(var_name=var_name): + code = f""" + bool {var_name}; + """ + with self.assertRaises(SyntaxError): + self.parse_qutes_code(code) + + def test_classic_type_declaration_succeed(self): + params = [ + ("bool", "false", False), + ("bool", "0", False), + ("bool", "TRUE", True), + ("bool", "1", True), + ("bool", "1q", True), #TODO: handle, the quantum var should be declared even when anonymous, so we can measure and assign the value to bool. + ("bool", "0q", False), + ("int", "10", 10), + ("int", "false+false", 0), + ("int", "true+true", 2), + ("int", "10q", 10), + ("string", "\"test\"", "test"), + ("string", "\"test\" + \"sum\"", "testsum"), + ("string", "1", "True"), #TODO: We should expect "1" not "True" + ("string", "2", "2"), + ] + var_name:str = "foo" + for var_type, declaration_value, expected_value_of_var in params: + with self.subTest(var_type=var_type, declaration_value=declaration_value, expected_value_of_var=expected_value_of_var): + code = f""" + {var_type} {var_name} = {declaration_value}; + """ + result = self.parse_qutes_code(code) + actual_value_of_var = result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value + self.assertEquals(actual_value_of_var, expected_value_of_var, f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - @parameterized.expand([ - ["bool", "foo", "10"], - ["bool", "foo", "\"test\""], - ["bool", "foo", "10q"], - ["int", "foo", "\"test\""], - ["string", "foo", "0q"], - ["string", "foo", "2q"], - ]) - def test_classic_type_declaration_fail(self, var_type, var_name, declaration_value): - code = f""" - {var_type} {var_name} = {declaration_value}; - """ - # with self.assertRaises(SyntaxError): - with self.assertRaises(TypeError): - result = self.run_qutes_code(code) - - - @parameterized.expand([ - ["qubit", "foo", "0q", Qubit()], - ["qubit", "foo", "0", Qubit()], - ["qubit", "foo", "true", Qubit(0,1)], - ["qubit", "foo", "|+>", Qubit(0.5, 0.5)], - ["qubit", "foo", "|->", Qubit(0.5, -0.5)], - ["quint", "foo", "10q", Quint.fromValue(10)], - ["quint", "foo", "false", Quint.fromValue(0)], - ["quint", "foo", "[[0,1]q, 1q]", Quint([Qubit(0.5, 0.5), Qubit(0, 1)])], - ["qustring", "foo", "\"test\"", Qustring.fromValue("test")], - ["qustring", "foo", "\"t*st\"", Qustring.fromValue("t*st")], - ["qustring", "foo", "1q", Qustring.fromValue(Qubit(0,1))], - ["qustring", "foo", "|+>", Qustring.fromValue(Qubit(0.5, 0.5))], - ]) - def test_quantum_type_declaration_succeed(self, var_type, var_name, declaration_value, expected_value_of_var): - code = f""" - {var_type} {var_name} = {declaration_value}; - """ - result = self.run_qutes_code(code) + def test_classic_type_declaration_throws(self): + params = [ + ("bool", "10"), + ("bool", "\"test\""), + ("bool", "10q"), + ("int", "\"test\""), + ("string", "0q"), + ("string", "2q"), + ] + var_name:str = "foo" + for var_type, declaration_value in params: + with self.subTest(var_type=var_type, declaration_value=declaration_value): + code = f""" + {var_type} {var_name} = {declaration_value}; + """ + with self.assertRaises(TypeError): + self.parse_qutes_code(code) + + + def test_quantum_type_declaration_succeed(self): + params = [ + ("qubit", "0q", Qubit()), + ("qubit", "0", Qubit()), + ("qubit", "true", Qubit(0,1)), + ("qubit", "|+>", Qubit(0.5, 0.5)), + ("qubit", "|->", Qubit(0.5, -0.5)), + ("quint", "10q", Quint.fromValue(10)), + ("quint", "false", Quint.fromValue(0)), + ("quint", "[[0,1]q, 1q]", Quint([Qubit(0.5, 0.5), Qubit(0, 1)])), + ("qustring", "\"test\"", Qustring.fromValue("test")), + ("qustring", "\"t*st\"", Qustring.fromValue("t*st")), + ("qustring", "1q", Qustring.fromValue(Qubit(0,1))), + ("qustring", "|+>", Qustring.fromValue(Qubit(0.5, 0.5))), + ] + var_name:str = "foo" + for var_type, declaration_value, expected_value_of_var in params: + with self.subTest(var_type=var_type, declaration_value=declaration_value, expected_value_of_var=expected_value_of_var): + code = f""" + {var_type} {var_name} = {declaration_value}; + """ + result = self.parse_qutes_code(code) + + actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) + self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) - self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - - @parameterized.expand([ - ["qubit", "foo", "10"], - ["qubit", "foo", "10q"], - ["qubit", "foo", "\"test\""], - ["quint", "foo", "\"test\""], - ["qustring", "foo", "10q"], - ["qustring", "foo", "[[0,1]q, 1q]"], - ["qustring", "foo", "false"], - ]) - def test_quantum_type_declaration_fail(self, var_type, var_name, declaration_value): - code = f""" - {var_type} {var_name} = {declaration_value}; - """ - with self.assertRaises(TypeError): - result = self.run_qutes_code(code) - - def test_double_variable_declaration_fail(self): + + def test_quantum_type_declaration_throws(self): + params = [ + ("qubit", "10"), + ("qubit", "10q"), + ("qubit", "\"test\""), + ("quint", "\"test\""), + ("qustring", "10q"), + ("qustring", "[[0,1]q, 1q]"), + ("qustring", "false"), + ] + for var_type, declaration_value in params: + with self.subTest("var_type, declaration_value", var_type=var_type, declaration_value=declaration_value): + var_name:str = "foo" + code = f""" + {var_type} {var_name} = {declaration_value}; + """ + with self.assertRaises(TypeError): + self.parse_qutes_code(code) + + def test_double_variable_declaration_throws(self): code = f""" quint a = 5q; string a = ""; """ with self.assertRaises(SyntaxError): - result = self.run_qutes_code(code) + self.parse_qutes_code(code) def test_variable_shadowing_succeed(self): var_name = "a" @@ -137,56 +171,7 @@ def test_variable_shadowing_succeed(self): quint {var_name} = 5q; {{ string {var_name} = {declaration_value_of_var}; }} """ - result = self.run_qutes_code(code) + result = self.parse_qutes_code(code) result.scope_handler.push_scope() actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) - self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - - @parameterized.expand([ - ["\"00111111\"", "\"01\""], - # ["\"001111\"", "\"01\""], #TODO: handle array not being power of size_char - ["\"0011\"", "\"01\""], - ["\"0011\"", "\"0\""], - ["\"0011\"", "\"1\""], - ["\"1\"", "\"1\""], - ["\"0\"", "\"0\""], - ["\"0111110\"", "\"01\", \"10\""], - ["\"1110111\"", "\"0\""], - ["\"0001000\"", "\"1\""], - ]) - def test_grover_search_succeed(self, array, pattern_to_match): - var_name = "found" - expected_value_of_var = True - code = f""" - bool {var_name} = false; - qustring a = {array}; - if({pattern_to_match} in a){{ - {var_name} = true; - }} - """ - result = self.run_qutes_code(code) - actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) - self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - - @parameterized.expand([ - ["\"01111111\"", "\"00\""], - ["\"001111\"", "\"000\""], - ["\"0011\"", "\"111\""], - ["\"0011\"", "\"11111\""], - ]) - def test_grover_search_fail(self, array, pattern_to_match): - var_name = "found" - expected_value_of_var = False - code = f""" - bool {var_name} = false; - qustring a = {array}; - if({pattern_to_match} in a){{ - {var_name} = true; - }} - """ - result = self.run_qutes_code(code) - actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) - self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") - -if __name__ == '__main__': - unittest.main() \ No newline at end of file + self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") \ No newline at end of file diff --git a/src/tests/test_grover.py b/src/tests/test_grover.py new file mode 100644 index 0000000..8daddad --- /dev/null +++ b/src/tests/test_grover.py @@ -0,0 +1,63 @@ +from .qutes_base_test import QutesBaseTest + +class TestGrover(QutesBaseTest): + TOKEN_AST_INDEX_FOR_TESTS = 100000 + + # Grover search is probabilistic, there is a little chance no solution is found even if there should be one, and vice versa. + # So if we fail the first time, we try again + def assert_grover_test(self, code, var_name, expected_value_of_var): + try: + result = self.parse_qutes_code(code) + actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) + self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") + except: + result = self.parse_qutes_code(code) + actual_value_of_var = str(result.variables_handler.get_variable_symbol(var_name, self.TOKEN_AST_INDEX_FOR_TESTS).value) + self.assertEquals(actual_value_of_var, str(expected_value_of_var), f"Expected value: {expected_value_of_var}, actual value: {actual_value_of_var}") + + def test_grover_substring_search_return_true(self): + params = [ + ("\"00111111\"", "\"01\""), + # ["\"001111\"", "\"01\""), #TODO: handle array not being power of size_char + ("\"0011\"", "\"01\""), + ("\"0011\"", "\"0\""), + ("\"0011\"", "\"1\""), + ("\"1\"", "\"1\""), + ("\"0\"", "\"0\""), + ("\"0111110\"", "\"01\", \"10\""), + ("\"1110111\"", "\"0\""), + ("\"0001000\"", "\"1\""), + ] + var_name = "found" + expected_value_of_var = True + for array, pattern_to_match in params: + with self.subTest(array=array, pattern_to_match=pattern_to_match): + code = f""" + bool {var_name} = false; + qustring a = {array}; + if({pattern_to_match} in a){{ + {var_name} = true; + }} + """ + self.assert_grover_test(code, var_name, expected_value_of_var) + + def test_grover_substring_search_return_false(self): + params = [ + ("\"01111111\"", "\"00\""), + ("\"001111\"", "\"000\""), + ("\"0011\"", "\"111\""), + ("\"0011\"", "\"11111\""), + ] + var_name = "found" + expected_value_of_var = False + + for array, pattern_to_match in params: + with self.subTest(array=array, pattern_to_match=pattern_to_match): + code = f""" + bool {var_name} = false; + qustring a = {array}; + if({pattern_to_match} in a){{ + {var_name} = true; + }} + """ + self.assert_grover_test(code, var_name, expected_value_of_var) \ No newline at end of file