diff --git a/poetry.lock b/poetry.lock index 5842ba01f..1887d4879 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +[[package]] +name = "antlr4-python3-runtime" +version = "4.13.1" +description = "ANTLR 4.13.1 runtime for Python 3" +optional = false +python-versions = "*" +files = [ + {file = "antlr4-python3-runtime-4.13.1.tar.gz", hash = "sha256:3cd282f5ea7cfb841537fe01f143350fdb1c0b1ce7981443a2fa8513fddb6d1a"}, + {file = "antlr4_python3_runtime-4.13.1-py3-none-any.whl", hash = "sha256:78ec57aad12c97ac039ca27403ad61cb98aaec8a3f9bb8144f889aa0fa28b943"}, +] + [[package]] name = "attrs" version = "24.2.0" @@ -1403,4 +1414,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "124d159dae01a069ae8ee16a6672499e64dc134139f6ec106ea499aa0569fd32" +content-hash = "6d461806e698aefb6d76062b939d3bd6ce0565136fc9436f243331a03fee5597" diff --git a/pyproject.toml b/pyproject.toml index 315d60885..53018560a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ python = "^3.10" kevm-pyk = { git = "https://github.com/runtimeverification/evm-semantics.git", tag = "v1.0.680", subdirectory = "kevm-pyk" } eth-utils = "^4.1.1" pycryptodome = "^3.20.0" +antlr4-python3-runtime = "^4.13.1" [tool.poetry.group.dev.dependencies] autoflake = "*" @@ -51,12 +52,21 @@ remove-all-unused-imports = true ignore-init-module-imports = true remove-duplicate-keys = true remove-unused-variables = true -exclude = "src/tests/integration/test-data" +exclude = [ + "src/tests/integration/test-data", + "src/kontrol/solidity", +] [tool.black] line-length = 120 skip-string-normalization = true +[tool.flake8] +exclude = "src/kontrol/solidity" + [tool.mypy] disallow_untyped_defs = true -exclude = "src/tests/integration/test-data" +exclude = [ + "src/tests/integration/test-data", + "src/kontrol/solidity", +] \ No newline at end of file diff --git a/src/kontrol/prove.py b/src/kontrol/prove.py index a963cb828..d6536ffc3 100644 --- a/src/kontrol/prove.py +++ b/src/kontrol/prove.py @@ -9,6 +9,7 @@ from subprocess import CalledProcessError from typing import TYPE_CHECKING, Any, ContextManager, NamedTuple +from antlr4 import CommonTokenStream, InputStream # type: ignore from kevm_pyk.kevm import KEVM, KEVMSemantics, _process_jumpdests from kevm_pyk.utils import KDefinition__expand_macros, abstract_cell_vars, run_prover from multiprocess.pool import Pool # type: ignore @@ -34,6 +35,9 @@ from .hevm import Hevm from .options import ConfigType, TraceOptions from .solc_to_k import Contract, hex_string_to_int +from .solidity.AnnotationVisitor import AnnotationVisitor +from .solidity.SolidityLexer import SolidityLexer +from .solidity.SolidityParser import SolidityParser from .state_record import StateDiffEntry, StateDumpEntry from .utils import console, parse_test_version_tuple @@ -1034,7 +1038,12 @@ def _init_cterm( else: # Symbolic accounts of all relevant contracts accounts, storage_constraints = _create_cse_accounts( - foundry, storage_fields, contract_account_name, contract_code + foundry, storage_fields, contract_account_name, contract_code, method + ) + + # Add precondition constraints + storage_constraints.extend( + _create_precondition_constraints(foundry, storage_fields, contract_account_name, method) ) accounts.append(KVariable('ACCOUNTS_REST', sort=KSort('AccountCellMap'))) @@ -1078,6 +1087,11 @@ def _init_cterm( for constraint in storage_constraints: init_cterm = init_cterm.add_constraint(constraint) + # TODO(palina): we don't need that as long as we're doing it in _cse_... + # if method.preconditions is not None: + # for precondition in method.preconditions: + # init_cterm = init_cterm.add_constraint(mlEqualsTrue(precondition.to_kapply)) + # The calling contract is assumed to be in the present accounts for non-tests if not (config_type == ConfigType.TEST_CONFIG or active_symbolik): init_cterm.add_constraint( @@ -1120,11 +1134,52 @@ def _create_initial_account_list( return init_account_list +def _create_precondition_constraints( + foundry: Foundry, + storage_fields: tuple[StorageField, ...], + contract_name: str, + method: Contract.Method, +) -> list[KApply]: + + precondition_constraints: list[KApply] = [] + + def precondition_to_kapply(precondition: str) -> KApply: + """ + Converts the precondition to a KApply term. + + - Constants are translated into `intToken` terms + - Variables should be searched in method's inputs or in the contract's storage fields + - Operators are translated into the corresponding KLabel application, e.g., `leInt`, `eqInt`, etc. + TBD + """ + + # Parse the input expression + input_stream = InputStream(precondition) + lexer = SolidityLexer(input_stream) + + stream = CommonTokenStream(lexer) + parser = SolidityParser(stream) + tree = parser.expression() + + # Evaluate the expression + evaluator = AnnotationVisitor(method, foundry, storage_fields, contract_name) + result = evaluator.visit(tree) + + return result + + if method.preconditions is not None: + for p in method.preconditions: + precondition_constraints.append(mlEqualsTrue(precondition_to_kapply(p.precondition))) + + return precondition_constraints + + def _create_cse_accounts( foundry: Foundry, storage_fields: tuple[StorageField, ...], contract_name: str, contract_code: KInner, + method: Contract.Method, ) -> tuple[list[KInner], list[KApply]]: """ Recursively generates a list of new accounts corresponding to `contract` fields, each having and cell (partially) set up. @@ -1293,7 +1348,7 @@ def extend_storage(map: KInner, slot: int, value: KInner) -> KInner: ) contract_accounts, contract_constraints = _create_cse_accounts( - foundry, contract_obj.fields, field_name, contract_account_code + foundry, contract_obj.fields, field_name, contract_account_code, method ) new_accounts.extend(contract_accounts) new_account_constraints.extend(contract_constraints) diff --git a/src/kontrol/solc_to_k.py b/src/kontrol/solc_to_k.py index f2296fab1..0fb86642b 100644 --- a/src/kontrol/solc_to_k.py +++ b/src/kontrol/solc_to_k.py @@ -337,6 +337,32 @@ def parse_devdoc(tag: str, devdoc: dict | None) -> dict: return natspecs +def parse_annotations( + devdoc: str | None, method: Contract.Method | Contract.Constructor +) -> tuple[Precondition, ...] | None: + """ + Parse developer documentation (devdoc) to extract user-provided preconditions. + + Returns a tuple of Precondition objects, each representing a single precondition and a method to which it belongs. + """ + + if devdoc is None: + return None + + preconditions: list[Precondition] = [] + for precondition in devdoc.split(','): + # Trim whitespace and skip if empty + precondition = precondition.strip() + if not precondition: + continue + + # Create a Precondition object and add it to the list + new_precondition = Precondition(precondition, method) + preconditions.append(new_precondition) + + return tuple(preconditions) + + class StorageField(NamedTuple): label: str data_type: str @@ -345,6 +371,19 @@ class StorageField(NamedTuple): linked_interface: str | None +@dataclass +class Precondition: + precondition: str + method: Contract.Method | Contract.Constructor + + def __init__(self, precondition: str, method: Contract.Method | Contract.Constructor): + """ + Initializes a new instance of the Precondition class. + """ + self.precondition = precondition + self.method = method + + @dataclass class Contract: @dataclass @@ -356,6 +395,7 @@ class Constructor: contract_storage_digest: str payable: bool signature: str + preconditions: tuple[Precondition, ...] | None def __init__( self, @@ -369,7 +409,7 @@ def __init__( self.contract_name = contract_name self.contract_digest = contract_digest self.contract_storage_digest = contract_storage_digest - # TODO: support NatSpec comments for dynamic types + # TODO: support NatSpec comments for dynamic types, including preconditions self.inputs = tuple(inputs_from_abi(abi['inputs'], None)) self.sort = sort # TODO: Check that we're handling all state mutability cases @@ -487,6 +527,7 @@ class Method: ast: dict | None natspec_values: dict | None function_calls: tuple[str, ...] | None + preconditions: tuple[Precondition, ...] | None def __init__( self, @@ -517,6 +558,9 @@ def __init__( natspec_tags = ['custom:kontrol-array-length-equals', 'custom:kontrol-bytes-length-equals'] self.natspec_values = {tag.split(':')[1]: parse_devdoc(tag, devdoc) for tag in natspec_tags} self.inputs = tuple(inputs_from_abi(abi['inputs'], self.natspec_values)) + self.preconditions = ( + parse_annotations(devdoc.get('custom:kontrol-precondition', None), self) if devdoc is not None else None + ) self.function_calls = tuple(function_calls) if function_calls is not None else None @property diff --git a/src/kontrol/solidity/AnnotationVisitor.py b/src/kontrol/solidity/AnnotationVisitor.py new file mode 100644 index 000000000..8baddb31e --- /dev/null +++ b/src/kontrol/solidity/AnnotationVisitor.py @@ -0,0 +1,148 @@ +from kevm_pyk.kevm import KEVM +from pyk.kast import KInner +from pyk.kast.inner import KApply, KSort, KVariable +from pyk.kast.manip import abstract_term_safely +from pyk.prelude.kbool import FALSE, TRUE +from pyk.prelude.kint import intToken + +from ..foundry import Foundry +from ..solc_to_k import Contract, StorageField +from .SolidityParser import SolidityParser +from .SolidityVisitor import SolidityVisitor + + +class AnnotationVisitor(SolidityVisitor): + def __init__( + self, + method: Contract.Method | Contract.Constructor, + foundry: Foundry, + storage_fields: tuple[StorageField, ...], + contract_name: str, + ): + self.method = method + self.foundry = foundry + self.storage_fields = storage_fields + self.contract_name = contract_name + + # def visitAndExpression(self, ctx: SolidityParser.AndExpressionContext): + # left = self.visit(ctx.booleanExpression(0)) + # right = self.visit(ctx.booleanExpression(1)) + # return left and right + + # def visitOrExpression(self, ctx: SolidityParser.OrExpressionContext): + # left = self.visit(ctx.booleanExpression(0)) + # right = self.visit(ctx.booleanExpression(1)) + # return left or right + + # def visitNotExpression(self, ctx: SolidityParser.NotExpressionContext): + # value = self.visit(ctx.booleanExpression()) + # return not value + + def visitRelationalExpression(self, ctx: SolidityParser.RelationalExpressionContext) -> KApply: + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + + op = ctx.RelOp().getText() + + # Map operators to KLabel applications + operator_mapping = { + '<=': '_<=Int_', + '>=': '_>=Int_', + '==': '_==Int_', + '!=': '_=/=Int_', + '<': '_': '_>Int_', + } + + if op in operator_mapping: + operator_label = operator_mapping[op] + else: + raise ValueError(f'Unsupported operator in a precondition: {op}') + + return KApply(operator_label, left, right) + + def visitBooleanLiteral(self, ctx: SolidityParser.BooleanLiteralContext) -> KInner: + return TRUE if ctx.getText() == 'true' else FALSE + + def visitVariable(self, ctx: SolidityParser.VariableContext) -> KInner: + var_name = ctx.getText() + # Search for matches in function inputs + for input in self.method.inputs: + if input.name == var_name: + # TODO: add support for complex types + return abstract_term_safely(KVariable('_###SOLIDITY_ARG_VAR###_'), base_name=f'V{input.arg_name}') + + # Search for matches in contract storage fields + for field in self.storage_fields: + if field.label == var_name: + storage_map: KInner = KVariable(self.contract_name + '_STORAGE', sort=KSort('Map')) + return KEVM.lookup(storage_map, intToken(field.slot)) + + raise ValueError(f'Variable {var_name} not found in function inputs or storage fields of {self.method.name}.') + + def visitContractVariableAccess(self, ctx: SolidityParser.ContractVariableAccessContext): + contract_field_name: str = ctx.contractVariableAccessExpr().VariableName(0).getText() + var_name: str = ctx.contractVariableAccessExpr().VariableName(1).getText() + + for field in self.storage_fields: + if field.data_type.startswith('contract ') and field.label == contract_field_name: + contract_type = field.data_type.split(' ')[1] + + # TODO: it is possible for a contact to have an interface annotation, `linked_interface` + for full_contract_name, contract_obj in self.foundry.contracts.items(): + # TODO: this is not enough, it is possible that the same contract comes with + # src% and test%, in which case we don't know automatically which one to choose + if full_contract_name.split('%')[-1] == contract_type: + for field in contract_obj.fields: + if field.label == var_name: + storage_map: KInner = KVariable( + self.contract_name + '_' + contract_field_name.upper() + '_STORAGE', sort=KSort('Map') + ) + return KEVM.lookup(storage_map, intToken(field.slot)) + + raise ValueError(f'Variable {contract_field_name}.{var_name} not found.') + + def visitIntegerLiteral(self, ctx: SolidityParser.IntegerLiteralContext) -> KInner: + return intToken(ctx.getText()) + + def visitAddExpression(self, ctx: SolidityParser.AddExpressionContext): + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + return KApply('_+Int_', left, right) + + def visitSubtractExpression(self, ctx: SolidityParser.SubtractExpressionContext): + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + return KApply('_-Int_', left, right) + + def visitMultiplyExpression(self, ctx: SolidityParser.MultiplyExpressionContext): + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + return KApply('_*Int_', left, right) + + def visitDivideExpression(self, ctx: SolidityParser.DivideExpressionContext): + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + return KApply('_/Int_', left, right) + + def visitPowExpression(self, ctx: SolidityParser.PowExpressionContext): + left = self.visit(ctx.arithmeticExpression(0)) + right = self.visit(ctx.arithmeticExpression(1)) + return KApply('_^Int_', left, right) + + # def visitLengthAccess(self, ctx: SolidityParser.LengthAccessContext): + # var_name = ctx.variableName().getText() + # return len(self.context.get(var_name, "")) + + # def visitArrayElement(self, ctx: SolidityParser.ArrayElementContext): + # var_name = ctx.variableName().getText() + # index = int(ctx.INTEGER().getText()) + # return self.context.get(var_name, [])[index] + + # def visitMappingElement(self, ctx: SolidityParser.MappingElementContext): + # var_name = ctx.variableName().getText() + # key = ctx.variableName().getText() + # return self.context.get(var_name, {}).get(key, 0) + + # def visitAddressLiteral(self, ctx: SolidityParser.AddressLiteralContext): + # return ctx.getText() diff --git a/src/kontrol/solidity/Solidity.g4 b/src/kontrol/solidity/Solidity.g4 new file mode 100644 index 000000000..bf5a8302a --- /dev/null +++ b/src/kontrol/solidity/Solidity.g4 @@ -0,0 +1,64 @@ +grammar Solidity; + +// Parser rules +expression + : booleanExpression + ; + +booleanExpression + : booleanExpression '&&' booleanExpression # AndExpression + | booleanExpression '||' booleanExpression # OrExpression + | '!' booleanExpression # NotExpression + | arithmeticExpression RelOp arithmeticExpression # RelationalExpression + | BOOLEAN_LITERAL # BooleanLiteral + | '(' booleanExpression ')' # ParenthesizedBooleanExpression + ; + +arithmeticExpression + : arithmeticExpression '+' arithmeticExpression # AddExpression + | arithmeticExpression '-' arithmeticExpression # SubtractExpression + | arithmeticExpression '*' arithmeticExpression # MultiplyExpression + | arithmeticExpression '/' arithmeticExpression # DivideExpression + | arithmeticExpression '**' arithmeticExpression # PowExpression + | atom # AtomExpression + ; + +atom + : VariableName # Variable + | LengthAccess # LengthAccess + | ArrayElement # ArrayElement + | MappingElement # MappingElement + | AddressLiteral # AddressLiteral + | INTEGER # IntegerLiteral + | '(' arithmeticExpression ')' # ParenthesizedArithmeticExpression + | BlockAccess # BlockAccess + | MsgAccess # MsgAccess + | contractVariableAccessExpr # ContractVariableAccess + | contractVariableArrayElemExpr # ContractVariableArrayElement + ; + +contractVariableAccessExpr + : VariableName '.' VariableName + ; + +contractVariableArrayElemExpr + : VariableName '.' VariableName '[' (VariableName | INTEGER | ADDRESS) ']' + ; + +// Lexer rules +BOOLEAN_LITERAL: 'true' | 'false'; +INTEGER: [0-9]+; +ADDRESS: '0x' [0-9a-fA-F]+; + +VariableName: [a-zA-Z_][a-zA-Z0-9_]*; +LengthAccess: VariableName '.length'; +ArrayElement: VariableName '[' INTEGER ']'; +MappingElement: VariableName '[' VariableName ']'; +AddressLiteral: ADDRESS; +BlockAccess: 'block.' ('timestamp' | 'number'); +MsgAccess: 'msg.' ('sender'); + +RelOp: '<' | '<=' | '>' | '>=' | '==' | '!='; + +// Whitespace and comments +WS: [ \t\r\n]+ -> skip; diff --git a/src/kontrol/solidity/Solidity.interp b/src/kontrol/solidity/Solidity.interp new file mode 100644 index 000000000..a9fe426f0 --- /dev/null +++ b/src/kontrol/solidity/Solidity.interp @@ -0,0 +1,67 @@ +token literal names: +null +'&&' +'||' +'!' +'(' +')' +'+' +'-' +'*' +'/' +'**' +'.' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +BOOLEAN_LITERAL +INTEGER +ADDRESS +VariableName +LengthAccess +ArrayElement +MappingElement +AddressLiteral +BlockAccess +MsgAccess +RelOp +WS + +rule names: +expression +booleanExpression +arithmeticExpression +atom +contractVariableAccessExpr +contractVariableArrayElemExpr + + +atn: +[4, 1, 25, 90, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 27, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 35, 8, 1, 10, 1, 12, 1, 38, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 5, 2, 58, 8, 2, 10, 2, 12, 2, 61, 9, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 77, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 0, 2, 2, 4, 6, 0, 2, 4, 6, 8, 10, 0, 1, 1, 0, 15, 17, 103, 0, 12, 1, 0, 0, 0, 2, 26, 1, 0, 0, 0, 4, 39, 1, 0, 0, 0, 6, 76, 1, 0, 0, 0, 8, 78, 1, 0, 0, 0, 10, 82, 1, 0, 0, 0, 12, 13, 3, 2, 1, 0, 13, 1, 1, 0, 0, 0, 14, 15, 6, 1, -1, 0, 15, 16, 5, 3, 0, 0, 16, 27, 3, 2, 1, 4, 17, 18, 3, 4, 2, 0, 18, 19, 5, 24, 0, 0, 19, 20, 3, 4, 2, 0, 20, 27, 1, 0, 0, 0, 21, 27, 5, 14, 0, 0, 22, 23, 5, 4, 0, 0, 23, 24, 3, 2, 1, 0, 24, 25, 5, 5, 0, 0, 25, 27, 1, 0, 0, 0, 26, 14, 1, 0, 0, 0, 26, 17, 1, 0, 0, 0, 26, 21, 1, 0, 0, 0, 26, 22, 1, 0, 0, 0, 27, 36, 1, 0, 0, 0, 28, 29, 10, 6, 0, 0, 29, 30, 5, 1, 0, 0, 30, 35, 3, 2, 1, 7, 31, 32, 10, 5, 0, 0, 32, 33, 5, 2, 0, 0, 33, 35, 3, 2, 1, 6, 34, 28, 1, 0, 0, 0, 34, 31, 1, 0, 0, 0, 35, 38, 1, 0, 0, 0, 36, 34, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 3, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 39, 40, 6, 2, -1, 0, 40, 41, 3, 6, 3, 0, 41, 59, 1, 0, 0, 0, 42, 43, 10, 6, 0, 0, 43, 44, 5, 6, 0, 0, 44, 58, 3, 4, 2, 7, 45, 46, 10, 5, 0, 0, 46, 47, 5, 7, 0, 0, 47, 58, 3, 4, 2, 6, 48, 49, 10, 4, 0, 0, 49, 50, 5, 8, 0, 0, 50, 58, 3, 4, 2, 5, 51, 52, 10, 3, 0, 0, 52, 53, 5, 9, 0, 0, 53, 58, 3, 4, 2, 4, 54, 55, 10, 2, 0, 0, 55, 56, 5, 10, 0, 0, 56, 58, 3, 4, 2, 3, 57, 42, 1, 0, 0, 0, 57, 45, 1, 0, 0, 0, 57, 48, 1, 0, 0, 0, 57, 51, 1, 0, 0, 0, 57, 54, 1, 0, 0, 0, 58, 61, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 60, 1, 0, 0, 0, 60, 5, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 62, 77, 5, 17, 0, 0, 63, 77, 5, 18, 0, 0, 64, 77, 5, 19, 0, 0, 65, 77, 5, 20, 0, 0, 66, 77, 5, 21, 0, 0, 67, 77, 5, 15, 0, 0, 68, 69, 5, 4, 0, 0, 69, 70, 3, 4, 2, 0, 70, 71, 5, 5, 0, 0, 71, 77, 1, 0, 0, 0, 72, 77, 5, 22, 0, 0, 73, 77, 5, 23, 0, 0, 74, 77, 3, 8, 4, 0, 75, 77, 3, 10, 5, 0, 76, 62, 1, 0, 0, 0, 76, 63, 1, 0, 0, 0, 76, 64, 1, 0, 0, 0, 76, 65, 1, 0, 0, 0, 76, 66, 1, 0, 0, 0, 76, 67, 1, 0, 0, 0, 76, 68, 1, 0, 0, 0, 76, 72, 1, 0, 0, 0, 76, 73, 1, 0, 0, 0, 76, 74, 1, 0, 0, 0, 76, 75, 1, 0, 0, 0, 77, 7, 1, 0, 0, 0, 78, 79, 5, 17, 0, 0, 79, 80, 5, 11, 0, 0, 80, 81, 5, 17, 0, 0, 81, 9, 1, 0, 0, 0, 82, 83, 5, 17, 0, 0, 83, 84, 5, 11, 0, 0, 84, 85, 5, 17, 0, 0, 85, 86, 5, 12, 0, 0, 86, 87, 7, 0, 0, 0, 87, 88, 5, 13, 0, 0, 88, 11, 1, 0, 0, 0, 6, 26, 34, 36, 57, 59, 76] \ No newline at end of file diff --git a/src/kontrol/solidity/Solidity.tokens b/src/kontrol/solidity/Solidity.tokens new file mode 100644 index 000000000..a5bc42fd8 --- /dev/null +++ b/src/kontrol/solidity/Solidity.tokens @@ -0,0 +1,38 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +BOOLEAN_LITERAL=14 +INTEGER=15 +ADDRESS=16 +VariableName=17 +LengthAccess=18 +ArrayElement=19 +MappingElement=20 +AddressLiteral=21 +BlockAccess=22 +MsgAccess=23 +RelOp=24 +WS=25 +'&&'=1 +'||'=2 +'!'=3 +'('=4 +')'=5 +'+'=6 +'-'=7 +'*'=8 +'/'=9 +'**'=10 +'.'=11 +'['=12 +']'=13 diff --git a/src/kontrol/solidity/SolidityLexer.interp b/src/kontrol/solidity/SolidityLexer.interp new file mode 100644 index 000000000..dd76882fa --- /dev/null +++ b/src/kontrol/solidity/SolidityLexer.interp @@ -0,0 +1,92 @@ +token literal names: +null +'&&' +'||' +'!' +'(' +')' +'+' +'-' +'*' +'/' +'**' +'.' +'[' +']' +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +BOOLEAN_LITERAL +INTEGER +ADDRESS +VariableName +LengthAccess +ArrayElement +MappingElement +AddressLiteral +BlockAccess +MsgAccess +RelOp +WS + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +BOOLEAN_LITERAL +INTEGER +ADDRESS +VariableName +LengthAccess +ArrayElement +MappingElement +AddressLiteral +BlockAccess +MsgAccess +RelOp +WS + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 25, 187, 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 90, 8, 13, 1, 14, 4, 14, 93, 8, 14, 11, 14, 12, 14, 94, 1, 15, 1, 15, 1, 15, 1, 15, 4, 15, 101, 8, 15, 11, 15, 12, 15, 102, 1, 16, 1, 16, 5, 16, 107, 8, 16, 10, 16, 12, 16, 110, 9, 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, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 3, 21, 155, 8, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 179, 8, 23, 1, 24, 4, 24, 182, 8, 24, 11, 24, 12, 24, 183, 1, 24, 1, 24, 0, 0, 25, 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, 1, 0, 5, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 197, 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, 1, 51, 1, 0, 0, 0, 3, 54, 1, 0, 0, 0, 5, 57, 1, 0, 0, 0, 7, 59, 1, 0, 0, 0, 9, 61, 1, 0, 0, 0, 11, 63, 1, 0, 0, 0, 13, 65, 1, 0, 0, 0, 15, 67, 1, 0, 0, 0, 17, 69, 1, 0, 0, 0, 19, 71, 1, 0, 0, 0, 21, 74, 1, 0, 0, 0, 23, 76, 1, 0, 0, 0, 25, 78, 1, 0, 0, 0, 27, 89, 1, 0, 0, 0, 29, 92, 1, 0, 0, 0, 31, 96, 1, 0, 0, 0, 33, 104, 1, 0, 0, 0, 35, 111, 1, 0, 0, 0, 37, 120, 1, 0, 0, 0, 39, 125, 1, 0, 0, 0, 41, 130, 1, 0, 0, 0, 43, 132, 1, 0, 0, 0, 45, 156, 1, 0, 0, 0, 47, 178, 1, 0, 0, 0, 49, 181, 1, 0, 0, 0, 51, 52, 5, 38, 0, 0, 52, 53, 5, 38, 0, 0, 53, 2, 1, 0, 0, 0, 54, 55, 5, 124, 0, 0, 55, 56, 5, 124, 0, 0, 56, 4, 1, 0, 0, 0, 57, 58, 5, 33, 0, 0, 58, 6, 1, 0, 0, 0, 59, 60, 5, 40, 0, 0, 60, 8, 1, 0, 0, 0, 61, 62, 5, 41, 0, 0, 62, 10, 1, 0, 0, 0, 63, 64, 5, 43, 0, 0, 64, 12, 1, 0, 0, 0, 65, 66, 5, 45, 0, 0, 66, 14, 1, 0, 0, 0, 67, 68, 5, 42, 0, 0, 68, 16, 1, 0, 0, 0, 69, 70, 5, 47, 0, 0, 70, 18, 1, 0, 0, 0, 71, 72, 5, 42, 0, 0, 72, 73, 5, 42, 0, 0, 73, 20, 1, 0, 0, 0, 74, 75, 5, 46, 0, 0, 75, 22, 1, 0, 0, 0, 76, 77, 5, 91, 0, 0, 77, 24, 1, 0, 0, 0, 78, 79, 5, 93, 0, 0, 79, 26, 1, 0, 0, 0, 80, 81, 5, 116, 0, 0, 81, 82, 5, 114, 0, 0, 82, 83, 5, 117, 0, 0, 83, 90, 5, 101, 0, 0, 84, 85, 5, 102, 0, 0, 85, 86, 5, 97, 0, 0, 86, 87, 5, 108, 0, 0, 87, 88, 5, 115, 0, 0, 88, 90, 5, 101, 0, 0, 89, 80, 1, 0, 0, 0, 89, 84, 1, 0, 0, 0, 90, 28, 1, 0, 0, 0, 91, 93, 7, 0, 0, 0, 92, 91, 1, 0, 0, 0, 93, 94, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 30, 1, 0, 0, 0, 96, 97, 5, 48, 0, 0, 97, 98, 5, 120, 0, 0, 98, 100, 1, 0, 0, 0, 99, 101, 7, 1, 0, 0, 100, 99, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 100, 1, 0, 0, 0, 102, 103, 1, 0, 0, 0, 103, 32, 1, 0, 0, 0, 104, 108, 7, 2, 0, 0, 105, 107, 7, 3, 0, 0, 106, 105, 1, 0, 0, 0, 107, 110, 1, 0, 0, 0, 108, 106, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 34, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 111, 112, 3, 33, 16, 0, 112, 113, 5, 46, 0, 0, 113, 114, 5, 108, 0, 0, 114, 115, 5, 101, 0, 0, 115, 116, 5, 110, 0, 0, 116, 117, 5, 103, 0, 0, 117, 118, 5, 116, 0, 0, 118, 119, 5, 104, 0, 0, 119, 36, 1, 0, 0, 0, 120, 121, 3, 33, 16, 0, 121, 122, 5, 91, 0, 0, 122, 123, 3, 29, 14, 0, 123, 124, 5, 93, 0, 0, 124, 38, 1, 0, 0, 0, 125, 126, 3, 33, 16, 0, 126, 127, 5, 91, 0, 0, 127, 128, 3, 33, 16, 0, 128, 129, 5, 93, 0, 0, 129, 40, 1, 0, 0, 0, 130, 131, 3, 31, 15, 0, 131, 42, 1, 0, 0, 0, 132, 133, 5, 98, 0, 0, 133, 134, 5, 108, 0, 0, 134, 135, 5, 111, 0, 0, 135, 136, 5, 99, 0, 0, 136, 137, 5, 107, 0, 0, 137, 138, 5, 46, 0, 0, 138, 154, 1, 0, 0, 0, 139, 140, 5, 116, 0, 0, 140, 141, 5, 105, 0, 0, 141, 142, 5, 109, 0, 0, 142, 143, 5, 101, 0, 0, 143, 144, 5, 115, 0, 0, 144, 145, 5, 116, 0, 0, 145, 146, 5, 97, 0, 0, 146, 147, 5, 109, 0, 0, 147, 155, 5, 112, 0, 0, 148, 149, 5, 110, 0, 0, 149, 150, 5, 117, 0, 0, 150, 151, 5, 109, 0, 0, 151, 152, 5, 98, 0, 0, 152, 153, 5, 101, 0, 0, 153, 155, 5, 114, 0, 0, 154, 139, 1, 0, 0, 0, 154, 148, 1, 0, 0, 0, 155, 44, 1, 0, 0, 0, 156, 157, 5, 109, 0, 0, 157, 158, 5, 115, 0, 0, 158, 159, 5, 103, 0, 0, 159, 160, 5, 46, 0, 0, 160, 161, 1, 0, 0, 0, 161, 162, 5, 115, 0, 0, 162, 163, 5, 101, 0, 0, 163, 164, 5, 110, 0, 0, 164, 165, 5, 100, 0, 0, 165, 166, 5, 101, 0, 0, 166, 167, 5, 114, 0, 0, 167, 46, 1, 0, 0, 0, 168, 179, 5, 60, 0, 0, 169, 170, 5, 60, 0, 0, 170, 179, 5, 61, 0, 0, 171, 179, 5, 62, 0, 0, 172, 173, 5, 62, 0, 0, 173, 179, 5, 61, 0, 0, 174, 175, 5, 61, 0, 0, 175, 179, 5, 61, 0, 0, 176, 177, 5, 33, 0, 0, 177, 179, 5, 61, 0, 0, 178, 168, 1, 0, 0, 0, 178, 169, 1, 0, 0, 0, 178, 171, 1, 0, 0, 0, 178, 172, 1, 0, 0, 0, 178, 174, 1, 0, 0, 0, 178, 176, 1, 0, 0, 0, 179, 48, 1, 0, 0, 0, 180, 182, 7, 4, 0, 0, 181, 180, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 183, 184, 1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 186, 6, 24, 0, 0, 186, 50, 1, 0, 0, 0, 8, 0, 89, 94, 102, 108, 154, 178, 183, 1, 6, 0, 0] \ No newline at end of file diff --git a/src/kontrol/solidity/SolidityLexer.py b/src/kontrol/solidity/SolidityLexer.py new file mode 100644 index 000000000..c6af1dd58 --- /dev/null +++ b/src/kontrol/solidity/SolidityLexer.py @@ -0,0 +1,142 @@ +# Generated from src/kontrol/solidity/Solidity.g4 by ANTLR 4.13.2 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + + +def serializedATN(): + return [ + 4,0,25,187,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,1,0,1,0,1,0, + 1,1,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8, + 1,8,1,9,1,9,1,9,1,10,1,10,1,11,1,11,1,12,1,12,1,13,1,13,1,13,1,13, + 1,13,1,13,1,13,1,13,1,13,3,13,90,8,13,1,14,4,14,93,8,14,11,14,12, + 14,94,1,15,1,15,1,15,1,15,4,15,101,8,15,11,15,12,15,102,1,16,1,16, + 5,16,107,8,16,10,16,12,16,110,9,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,19,1,19,1,19,1,19,1,19, + 1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21, + 1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,1,21,3,21,155, + 8,21,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22, + 1,23,1,23,1,23,1,23,1,23,1,23,1,23,1,23,1,23,1,23,3,23,179,8,23, + 1,24,4,24,182,8,24,11,24,12,24,183,1,24,1,24,0,0,25,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,1,0, + 5,1,0,48,57,3,0,48,57,65,70,97,102,3,0,65,90,95,95,97,122,4,0,48, + 57,65,90,95,95,97,122,3,0,9,10,13,13,32,32,197,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,1,51,1,0,0,0,3,54,1,0, + 0,0,5,57,1,0,0,0,7,59,1,0,0,0,9,61,1,0,0,0,11,63,1,0,0,0,13,65,1, + 0,0,0,15,67,1,0,0,0,17,69,1,0,0,0,19,71,1,0,0,0,21,74,1,0,0,0,23, + 76,1,0,0,0,25,78,1,0,0,0,27,89,1,0,0,0,29,92,1,0,0,0,31,96,1,0,0, + 0,33,104,1,0,0,0,35,111,1,0,0,0,37,120,1,0,0,0,39,125,1,0,0,0,41, + 130,1,0,0,0,43,132,1,0,0,0,45,156,1,0,0,0,47,178,1,0,0,0,49,181, + 1,0,0,0,51,52,5,38,0,0,52,53,5,38,0,0,53,2,1,0,0,0,54,55,5,124,0, + 0,55,56,5,124,0,0,56,4,1,0,0,0,57,58,5,33,0,0,58,6,1,0,0,0,59,60, + 5,40,0,0,60,8,1,0,0,0,61,62,5,41,0,0,62,10,1,0,0,0,63,64,5,43,0, + 0,64,12,1,0,0,0,65,66,5,45,0,0,66,14,1,0,0,0,67,68,5,42,0,0,68,16, + 1,0,0,0,69,70,5,47,0,0,70,18,1,0,0,0,71,72,5,42,0,0,72,73,5,42,0, + 0,73,20,1,0,0,0,74,75,5,46,0,0,75,22,1,0,0,0,76,77,5,91,0,0,77,24, + 1,0,0,0,78,79,5,93,0,0,79,26,1,0,0,0,80,81,5,116,0,0,81,82,5,114, + 0,0,82,83,5,117,0,0,83,90,5,101,0,0,84,85,5,102,0,0,85,86,5,97,0, + 0,86,87,5,108,0,0,87,88,5,115,0,0,88,90,5,101,0,0,89,80,1,0,0,0, + 89,84,1,0,0,0,90,28,1,0,0,0,91,93,7,0,0,0,92,91,1,0,0,0,93,94,1, + 0,0,0,94,92,1,0,0,0,94,95,1,0,0,0,95,30,1,0,0,0,96,97,5,48,0,0,97, + 98,5,120,0,0,98,100,1,0,0,0,99,101,7,1,0,0,100,99,1,0,0,0,101,102, + 1,0,0,0,102,100,1,0,0,0,102,103,1,0,0,0,103,32,1,0,0,0,104,108,7, + 2,0,0,105,107,7,3,0,0,106,105,1,0,0,0,107,110,1,0,0,0,108,106,1, + 0,0,0,108,109,1,0,0,0,109,34,1,0,0,0,110,108,1,0,0,0,111,112,3,33, + 16,0,112,113,5,46,0,0,113,114,5,108,0,0,114,115,5,101,0,0,115,116, + 5,110,0,0,116,117,5,103,0,0,117,118,5,116,0,0,118,119,5,104,0,0, + 119,36,1,0,0,0,120,121,3,33,16,0,121,122,5,91,0,0,122,123,3,29,14, + 0,123,124,5,93,0,0,124,38,1,0,0,0,125,126,3,33,16,0,126,127,5,91, + 0,0,127,128,3,33,16,0,128,129,5,93,0,0,129,40,1,0,0,0,130,131,3, + 31,15,0,131,42,1,0,0,0,132,133,5,98,0,0,133,134,5,108,0,0,134,135, + 5,111,0,0,135,136,5,99,0,0,136,137,5,107,0,0,137,138,5,46,0,0,138, + 154,1,0,0,0,139,140,5,116,0,0,140,141,5,105,0,0,141,142,5,109,0, + 0,142,143,5,101,0,0,143,144,5,115,0,0,144,145,5,116,0,0,145,146, + 5,97,0,0,146,147,5,109,0,0,147,155,5,112,0,0,148,149,5,110,0,0,149, + 150,5,117,0,0,150,151,5,109,0,0,151,152,5,98,0,0,152,153,5,101,0, + 0,153,155,5,114,0,0,154,139,1,0,0,0,154,148,1,0,0,0,155,44,1,0,0, + 0,156,157,5,109,0,0,157,158,5,115,0,0,158,159,5,103,0,0,159,160, + 5,46,0,0,160,161,1,0,0,0,161,162,5,115,0,0,162,163,5,101,0,0,163, + 164,5,110,0,0,164,165,5,100,0,0,165,166,5,101,0,0,166,167,5,114, + 0,0,167,46,1,0,0,0,168,179,5,60,0,0,169,170,5,60,0,0,170,179,5,61, + 0,0,171,179,5,62,0,0,172,173,5,62,0,0,173,179,5,61,0,0,174,175,5, + 61,0,0,175,179,5,61,0,0,176,177,5,33,0,0,177,179,5,61,0,0,178,168, + 1,0,0,0,178,169,1,0,0,0,178,171,1,0,0,0,178,172,1,0,0,0,178,174, + 1,0,0,0,178,176,1,0,0,0,179,48,1,0,0,0,180,182,7,4,0,0,181,180,1, + 0,0,0,182,183,1,0,0,0,183,181,1,0,0,0,183,184,1,0,0,0,184,185,1, + 0,0,0,185,186,6,24,0,0,186,50,1,0,0,0,8,0,89,94,102,108,154,178, + 183,1,6,0,0 + ] + +class SolidityLexer(Lexer): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + T__0 = 1 + T__1 = 2 + T__2 = 3 + T__3 = 4 + T__4 = 5 + T__5 = 6 + T__6 = 7 + T__7 = 8 + T__8 = 9 + T__9 = 10 + T__10 = 11 + T__11 = 12 + T__12 = 13 + BOOLEAN_LITERAL = 14 + INTEGER = 15 + ADDRESS = 16 + VariableName = 17 + LengthAccess = 18 + ArrayElement = 19 + MappingElement = 20 + AddressLiteral = 21 + BlockAccess = 22 + MsgAccess = 23 + RelOp = 24 + WS = 25 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + + modeNames = [ "DEFAULT_MODE" ] + + literalNames = [ "", + "'&&'", "'||'", "'!'", "'('", "')'", "'+'", "'-'", "'*'", "'/'", + "'**'", "'.'", "'['", "']'" ] + + symbolicNames = [ "", + "BOOLEAN_LITERAL", "INTEGER", "ADDRESS", "VariableName", "LengthAccess", + "ArrayElement", "MappingElement", "AddressLiteral", "BlockAccess", + "MsgAccess", "RelOp", "WS" ] + + ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", + "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "BOOLEAN_LITERAL", + "INTEGER", "ADDRESS", "VariableName", "LengthAccess", + "ArrayElement", "MappingElement", "AddressLiteral", "BlockAccess", + "MsgAccess", "RelOp", "WS" ] + + grammarFileName = "Solidity.g4" + + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.13.2") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + diff --git a/src/kontrol/solidity/SolidityLexer.tokens b/src/kontrol/solidity/SolidityLexer.tokens new file mode 100644 index 000000000..a5bc42fd8 --- /dev/null +++ b/src/kontrol/solidity/SolidityLexer.tokens @@ -0,0 +1,38 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +BOOLEAN_LITERAL=14 +INTEGER=15 +ADDRESS=16 +VariableName=17 +LengthAccess=18 +ArrayElement=19 +MappingElement=20 +AddressLiteral=21 +BlockAccess=22 +MsgAccess=23 +RelOp=24 +WS=25 +'&&'=1 +'||'=2 +'!'=3 +'('=4 +')'=5 +'+'=6 +'-'=7 +'*'=8 +'/'=9 +'**'=10 +'.'=11 +'['=12 +']'=13 diff --git a/src/kontrol/solidity/SolidityListener.py b/src/kontrol/solidity/SolidityListener.py new file mode 100644 index 000000000..8494e8ae9 --- /dev/null +++ b/src/kontrol/solidity/SolidityListener.py @@ -0,0 +1,246 @@ +# Generated from src/kontrol/solidity/Solidity.g4 by ANTLR 4.13.2 +from antlr4 import * +if "." in __name__: + from .SolidityParser import SolidityParser +else: + from SolidityParser import SolidityParser + +# This class defines a complete listener for a parse tree produced by SolidityParser. +class SolidityListener(ParseTreeListener): + + # Enter a parse tree produced by SolidityParser#expression. + def enterExpression(self, ctx:SolidityParser.ExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#expression. + def exitExpression(self, ctx:SolidityParser.ExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#RelationalExpression. + def enterRelationalExpression(self, ctx:SolidityParser.RelationalExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#RelationalExpression. + def exitRelationalExpression(self, ctx:SolidityParser.RelationalExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#AndExpression. + def enterAndExpression(self, ctx:SolidityParser.AndExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#AndExpression. + def exitAndExpression(self, ctx:SolidityParser.AndExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#BooleanLiteral. + def enterBooleanLiteral(self, ctx:SolidityParser.BooleanLiteralContext): + pass + + # Exit a parse tree produced by SolidityParser#BooleanLiteral. + def exitBooleanLiteral(self, ctx:SolidityParser.BooleanLiteralContext): + pass + + + # Enter a parse tree produced by SolidityParser#NotExpression. + def enterNotExpression(self, ctx:SolidityParser.NotExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#NotExpression. + def exitNotExpression(self, ctx:SolidityParser.NotExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#OrExpression. + def enterOrExpression(self, ctx:SolidityParser.OrExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#OrExpression. + def exitOrExpression(self, ctx:SolidityParser.OrExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#ParenthesizedBooleanExpression. + def enterParenthesizedBooleanExpression(self, ctx:SolidityParser.ParenthesizedBooleanExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#ParenthesizedBooleanExpression. + def exitParenthesizedBooleanExpression(self, ctx:SolidityParser.ParenthesizedBooleanExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#SubtractExpression. + def enterSubtractExpression(self, ctx:SolidityParser.SubtractExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#SubtractExpression. + def exitSubtractExpression(self, ctx:SolidityParser.SubtractExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#DivideExpression. + def enterDivideExpression(self, ctx:SolidityParser.DivideExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#DivideExpression. + def exitDivideExpression(self, ctx:SolidityParser.DivideExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#AddExpression. + def enterAddExpression(self, ctx:SolidityParser.AddExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#AddExpression. + def exitAddExpression(self, ctx:SolidityParser.AddExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#PowExpression. + def enterPowExpression(self, ctx:SolidityParser.PowExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#PowExpression. + def exitPowExpression(self, ctx:SolidityParser.PowExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#MultiplyExpression. + def enterMultiplyExpression(self, ctx:SolidityParser.MultiplyExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#MultiplyExpression. + def exitMultiplyExpression(self, ctx:SolidityParser.MultiplyExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#AtomExpression. + def enterAtomExpression(self, ctx:SolidityParser.AtomExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#AtomExpression. + def exitAtomExpression(self, ctx:SolidityParser.AtomExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#Variable. + def enterVariable(self, ctx:SolidityParser.VariableContext): + pass + + # Exit a parse tree produced by SolidityParser#Variable. + def exitVariable(self, ctx:SolidityParser.VariableContext): + pass + + + # Enter a parse tree produced by SolidityParser#LengthAccess. + def enterLengthAccess(self, ctx:SolidityParser.LengthAccessContext): + pass + + # Exit a parse tree produced by SolidityParser#LengthAccess. + def exitLengthAccess(self, ctx:SolidityParser.LengthAccessContext): + pass + + + # Enter a parse tree produced by SolidityParser#ArrayElement. + def enterArrayElement(self, ctx:SolidityParser.ArrayElementContext): + pass + + # Exit a parse tree produced by SolidityParser#ArrayElement. + def exitArrayElement(self, ctx:SolidityParser.ArrayElementContext): + pass + + + # Enter a parse tree produced by SolidityParser#MappingElement. + def enterMappingElement(self, ctx:SolidityParser.MappingElementContext): + pass + + # Exit a parse tree produced by SolidityParser#MappingElement. + def exitMappingElement(self, ctx:SolidityParser.MappingElementContext): + pass + + + # Enter a parse tree produced by SolidityParser#AddressLiteral. + def enterAddressLiteral(self, ctx:SolidityParser.AddressLiteralContext): + pass + + # Exit a parse tree produced by SolidityParser#AddressLiteral. + def exitAddressLiteral(self, ctx:SolidityParser.AddressLiteralContext): + pass + + + # Enter a parse tree produced by SolidityParser#IntegerLiteral. + def enterIntegerLiteral(self, ctx:SolidityParser.IntegerLiteralContext): + pass + + # Exit a parse tree produced by SolidityParser#IntegerLiteral. + def exitIntegerLiteral(self, ctx:SolidityParser.IntegerLiteralContext): + pass + + + # Enter a parse tree produced by SolidityParser#ParenthesizedArithmeticExpression. + def enterParenthesizedArithmeticExpression(self, ctx:SolidityParser.ParenthesizedArithmeticExpressionContext): + pass + + # Exit a parse tree produced by SolidityParser#ParenthesizedArithmeticExpression. + def exitParenthesizedArithmeticExpression(self, ctx:SolidityParser.ParenthesizedArithmeticExpressionContext): + pass + + + # Enter a parse tree produced by SolidityParser#BlockAccess. + def enterBlockAccess(self, ctx:SolidityParser.BlockAccessContext): + pass + + # Exit a parse tree produced by SolidityParser#BlockAccess. + def exitBlockAccess(self, ctx:SolidityParser.BlockAccessContext): + pass + + + # Enter a parse tree produced by SolidityParser#MsgAccess. + def enterMsgAccess(self, ctx:SolidityParser.MsgAccessContext): + pass + + # Exit a parse tree produced by SolidityParser#MsgAccess. + def exitMsgAccess(self, ctx:SolidityParser.MsgAccessContext): + pass + + + # Enter a parse tree produced by SolidityParser#ContractVariableAccess. + def enterContractVariableAccess(self, ctx:SolidityParser.ContractVariableAccessContext): + pass + + # Exit a parse tree produced by SolidityParser#ContractVariableAccess. + def exitContractVariableAccess(self, ctx:SolidityParser.ContractVariableAccessContext): + pass + + + # Enter a parse tree produced by SolidityParser#ContractVariableArrayElement. + def enterContractVariableArrayElement(self, ctx:SolidityParser.ContractVariableArrayElementContext): + pass + + # Exit a parse tree produced by SolidityParser#ContractVariableArrayElement. + def exitContractVariableArrayElement(self, ctx:SolidityParser.ContractVariableArrayElementContext): + pass + + + # Enter a parse tree produced by SolidityParser#contractVariableAccessExpr. + def enterContractVariableAccessExpr(self, ctx:SolidityParser.ContractVariableAccessExprContext): + pass + + # Exit a parse tree produced by SolidityParser#contractVariableAccessExpr. + def exitContractVariableAccessExpr(self, ctx:SolidityParser.ContractVariableAccessExprContext): + pass + + + # Enter a parse tree produced by SolidityParser#contractVariableArrayElemExpr. + def enterContractVariableArrayElemExpr(self, ctx:SolidityParser.ContractVariableArrayElemExprContext): + pass + + # Exit a parse tree produced by SolidityParser#contractVariableArrayElemExpr. + def exitContractVariableArrayElemExpr(self, ctx:SolidityParser.ContractVariableArrayElemExprContext): + pass + + + +del SolidityParser \ No newline at end of file diff --git a/src/kontrol/solidity/SolidityParser.py b/src/kontrol/solidity/SolidityParser.py new file mode 100644 index 000000000..5711f5896 --- /dev/null +++ b/src/kontrol/solidity/SolidityParser.py @@ -0,0 +1,1287 @@ +# Generated from src/kontrol/solidity/Solidity.g4 by ANTLR 4.13.2 +# encoding: utf-8 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + +def serializedATN(): + return [ + 4,1,25,90,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,1,0,1, + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,27,8,1,1,1, + 1,1,1,1,1,1,1,1,1,1,5,1,35,8,1,10,1,12,1,38,9,1,1,2,1,2,1,2,1,2, + 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,5,2,58,8, + 2,10,2,12,2,61,9,2,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1, + 3,1,3,1,3,3,3,77,8,3,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5,1,5, + 1,5,0,2,2,4,6,0,2,4,6,8,10,0,1,1,0,15,17,103,0,12,1,0,0,0,2,26,1, + 0,0,0,4,39,1,0,0,0,6,76,1,0,0,0,8,78,1,0,0,0,10,82,1,0,0,0,12,13, + 3,2,1,0,13,1,1,0,0,0,14,15,6,1,-1,0,15,16,5,3,0,0,16,27,3,2,1,4, + 17,18,3,4,2,0,18,19,5,24,0,0,19,20,3,4,2,0,20,27,1,0,0,0,21,27,5, + 14,0,0,22,23,5,4,0,0,23,24,3,2,1,0,24,25,5,5,0,0,25,27,1,0,0,0,26, + 14,1,0,0,0,26,17,1,0,0,0,26,21,1,0,0,0,26,22,1,0,0,0,27,36,1,0,0, + 0,28,29,10,6,0,0,29,30,5,1,0,0,30,35,3,2,1,7,31,32,10,5,0,0,32,33, + 5,2,0,0,33,35,3,2,1,6,34,28,1,0,0,0,34,31,1,0,0,0,35,38,1,0,0,0, + 36,34,1,0,0,0,36,37,1,0,0,0,37,3,1,0,0,0,38,36,1,0,0,0,39,40,6,2, + -1,0,40,41,3,6,3,0,41,59,1,0,0,0,42,43,10,6,0,0,43,44,5,6,0,0,44, + 58,3,4,2,7,45,46,10,5,0,0,46,47,5,7,0,0,47,58,3,4,2,6,48,49,10,4, + 0,0,49,50,5,8,0,0,50,58,3,4,2,5,51,52,10,3,0,0,52,53,5,9,0,0,53, + 58,3,4,2,4,54,55,10,2,0,0,55,56,5,10,0,0,56,58,3,4,2,3,57,42,1,0, + 0,0,57,45,1,0,0,0,57,48,1,0,0,0,57,51,1,0,0,0,57,54,1,0,0,0,58,61, + 1,0,0,0,59,57,1,0,0,0,59,60,1,0,0,0,60,5,1,0,0,0,61,59,1,0,0,0,62, + 77,5,17,0,0,63,77,5,18,0,0,64,77,5,19,0,0,65,77,5,20,0,0,66,77,5, + 21,0,0,67,77,5,15,0,0,68,69,5,4,0,0,69,70,3,4,2,0,70,71,5,5,0,0, + 71,77,1,0,0,0,72,77,5,22,0,0,73,77,5,23,0,0,74,77,3,8,4,0,75,77, + 3,10,5,0,76,62,1,0,0,0,76,63,1,0,0,0,76,64,1,0,0,0,76,65,1,0,0,0, + 76,66,1,0,0,0,76,67,1,0,0,0,76,68,1,0,0,0,76,72,1,0,0,0,76,73,1, + 0,0,0,76,74,1,0,0,0,76,75,1,0,0,0,77,7,1,0,0,0,78,79,5,17,0,0,79, + 80,5,11,0,0,80,81,5,17,0,0,81,9,1,0,0,0,82,83,5,17,0,0,83,84,5,11, + 0,0,84,85,5,17,0,0,85,86,5,12,0,0,86,87,7,0,0,0,87,88,5,13,0,0,88, + 11,1,0,0,0,6,26,34,36,57,59,76 + ] + +class SolidityParser ( Parser ): + + grammarFileName = "Solidity.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ "", "'&&'", "'||'", "'!'", "'('", "')'", "'+'", + "'-'", "'*'", "'/'", "'**'", "'.'", "'['", "']'" ] + + symbolicNames = [ "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "BOOLEAN_LITERAL", "INTEGER", + "ADDRESS", "VariableName", "LengthAccess", "ArrayElement", + "MappingElement", "AddressLiteral", "BlockAccess", + "MsgAccess", "RelOp", "WS" ] + + RULE_expression = 0 + RULE_booleanExpression = 1 + RULE_arithmeticExpression = 2 + RULE_atom = 3 + RULE_contractVariableAccessExpr = 4 + RULE_contractVariableArrayElemExpr = 5 + + ruleNames = [ "expression", "booleanExpression", "arithmeticExpression", + "atom", "contractVariableAccessExpr", "contractVariableArrayElemExpr" ] + + EOF = Token.EOF + T__0=1 + T__1=2 + T__2=3 + T__3=4 + T__4=5 + T__5=6 + T__6=7 + T__7=8 + T__8=9 + T__9=10 + T__10=11 + T__11=12 + T__12=13 + BOOLEAN_LITERAL=14 + INTEGER=15 + ADDRESS=16 + VariableName=17 + LengthAccess=18 + ArrayElement=19 + MappingElement=20 + AddressLiteral=21 + BlockAccess=22 + MsgAccess=23 + RelOp=24 + WS=25 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.13.2") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + + + + + class ExpressionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def booleanExpression(self): + return self.getTypedRuleContext(SolidityParser.BooleanExpressionContext,0) + + + def getRuleIndex(self): + return SolidityParser.RULE_expression + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterExpression" ): + listener.enterExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitExpression" ): + listener.exitExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitExpression" ): + return visitor.visitExpression(self) + else: + return visitor.visitChildren(self) + + + + + def expression(self): + + localctx = SolidityParser.ExpressionContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_expression) + try: + self.enterOuterAlt(localctx, 1) + self.state = 12 + self.booleanExpression(0) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class BooleanExpressionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return SolidityParser.RULE_booleanExpression + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + class RelationalExpressionContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + def RelOp(self): + return self.getToken(SolidityParser.RelOp, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRelationalExpression" ): + listener.enterRelationalExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRelationalExpression" ): + listener.exitRelationalExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitRelationalExpression" ): + return visitor.visitRelationalExpression(self) + else: + return visitor.visitChildren(self) + + + class AndExpressionContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def booleanExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.BooleanExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.BooleanExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterAndExpression" ): + listener.enterAndExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitAndExpression" ): + listener.exitAndExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAndExpression" ): + return visitor.visitAndExpression(self) + else: + return visitor.visitChildren(self) + + + class BooleanLiteralContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def BOOLEAN_LITERAL(self): + return self.getToken(SolidityParser.BOOLEAN_LITERAL, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterBooleanLiteral" ): + listener.enterBooleanLiteral(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitBooleanLiteral" ): + listener.exitBooleanLiteral(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitBooleanLiteral" ): + return visitor.visitBooleanLiteral(self) + else: + return visitor.visitChildren(self) + + + class NotExpressionContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def booleanExpression(self): + return self.getTypedRuleContext(SolidityParser.BooleanExpressionContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterNotExpression" ): + listener.enterNotExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitNotExpression" ): + listener.exitNotExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitNotExpression" ): + return visitor.visitNotExpression(self) + else: + return visitor.visitChildren(self) + + + class OrExpressionContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def booleanExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.BooleanExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.BooleanExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterOrExpression" ): + listener.enterOrExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitOrExpression" ): + listener.exitOrExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitOrExpression" ): + return visitor.visitOrExpression(self) + else: + return visitor.visitChildren(self) + + + class ParenthesizedBooleanExpressionContext(BooleanExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.BooleanExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def booleanExpression(self): + return self.getTypedRuleContext(SolidityParser.BooleanExpressionContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterParenthesizedBooleanExpression" ): + listener.enterParenthesizedBooleanExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitParenthesizedBooleanExpression" ): + listener.exitParenthesizedBooleanExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitParenthesizedBooleanExpression" ): + return visitor.visitParenthesizedBooleanExpression(self) + else: + return visitor.visitChildren(self) + + + + def booleanExpression(self, _p:int=0): + _parentctx = self._ctx + _parentState = self.state + localctx = SolidityParser.BooleanExpressionContext(self, self._ctx, _parentState) + _prevctx = localctx + _startState = 2 + self.enterRecursionRule(localctx, 2, self.RULE_booleanExpression, _p) + try: + self.enterOuterAlt(localctx, 1) + self.state = 26 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,0,self._ctx) + if la_ == 1: + localctx = SolidityParser.NotExpressionContext(self, localctx) + self._ctx = localctx + _prevctx = localctx + + self.state = 15 + self.match(SolidityParser.T__2) + self.state = 16 + self.booleanExpression(4) + pass + + elif la_ == 2: + localctx = SolidityParser.RelationalExpressionContext(self, localctx) + self._ctx = localctx + _prevctx = localctx + self.state = 17 + self.arithmeticExpression(0) + self.state = 18 + self.match(SolidityParser.RelOp) + self.state = 19 + self.arithmeticExpression(0) + pass + + elif la_ == 3: + localctx = SolidityParser.BooleanLiteralContext(self, localctx) + self._ctx = localctx + _prevctx = localctx + self.state = 21 + self.match(SolidityParser.BOOLEAN_LITERAL) + pass + + elif la_ == 4: + localctx = SolidityParser.ParenthesizedBooleanExpressionContext(self, localctx) + self._ctx = localctx + _prevctx = localctx + self.state = 22 + self.match(SolidityParser.T__3) + self.state = 23 + self.booleanExpression(0) + self.state = 24 + self.match(SolidityParser.T__4) + pass + + + self._ctx.stop = self._input.LT(-1) + self.state = 36 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,2,self._ctx) + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1: + if self._parseListeners is not None: + self.triggerExitRuleEvent() + _prevctx = localctx + self.state = 34 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,1,self._ctx) + if la_ == 1: + localctx = SolidityParser.AndExpressionContext(self, SolidityParser.BooleanExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_booleanExpression) + self.state = 28 + if not self.precpred(self._ctx, 6): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") + self.state = 29 + self.match(SolidityParser.T__0) + self.state = 30 + self.booleanExpression(7) + pass + + elif la_ == 2: + localctx = SolidityParser.OrExpressionContext(self, SolidityParser.BooleanExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_booleanExpression) + self.state = 31 + if not self.precpred(self._ctx, 5): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") + self.state = 32 + self.match(SolidityParser.T__1) + self.state = 33 + self.booleanExpression(6) + pass + + + self.state = 38 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,2,self._ctx) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.unrollRecursionContexts(_parentctx) + return localctx + + + class ArithmeticExpressionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return SolidityParser.RULE_arithmeticExpression + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + class SubtractExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterSubtractExpression" ): + listener.enterSubtractExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitSubtractExpression" ): + listener.exitSubtractExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitSubtractExpression" ): + return visitor.visitSubtractExpression(self) + else: + return visitor.visitChildren(self) + + + class DivideExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterDivideExpression" ): + listener.enterDivideExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitDivideExpression" ): + listener.exitDivideExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDivideExpression" ): + return visitor.visitDivideExpression(self) + else: + return visitor.visitChildren(self) + + + class AddExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterAddExpression" ): + listener.enterAddExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitAddExpression" ): + listener.exitAddExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAddExpression" ): + return visitor.visitAddExpression(self) + else: + return visitor.visitChildren(self) + + + class PowExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterPowExpression" ): + listener.enterPowExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitPowExpression" ): + listener.exitPowExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitPowExpression" ): + return visitor.visitPowExpression(self) + else: + return visitor.visitChildren(self) + + + class MultiplyExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(SolidityParser.ArithmeticExpressionContext) + else: + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,i) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterMultiplyExpression" ): + listener.enterMultiplyExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitMultiplyExpression" ): + listener.exitMultiplyExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitMultiplyExpression" ): + return visitor.visitMultiplyExpression(self) + else: + return visitor.visitChildren(self) + + + class AtomExpressionContext(ArithmeticExpressionContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.ArithmeticExpressionContext + super().__init__(parser) + self.copyFrom(ctx) + + def atom(self): + return self.getTypedRuleContext(SolidityParser.AtomContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterAtomExpression" ): + listener.enterAtomExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitAtomExpression" ): + listener.exitAtomExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAtomExpression" ): + return visitor.visitAtomExpression(self) + else: + return visitor.visitChildren(self) + + + + def arithmeticExpression(self, _p:int=0): + _parentctx = self._ctx + _parentState = self.state + localctx = SolidityParser.ArithmeticExpressionContext(self, self._ctx, _parentState) + _prevctx = localctx + _startState = 4 + self.enterRecursionRule(localctx, 4, self.RULE_arithmeticExpression, _p) + try: + self.enterOuterAlt(localctx, 1) + localctx = SolidityParser.AtomExpressionContext(self, localctx) + self._ctx = localctx + _prevctx = localctx + + self.state = 40 + self.atom() + self._ctx.stop = self._input.LT(-1) + self.state = 59 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,4,self._ctx) + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1: + if self._parseListeners is not None: + self.triggerExitRuleEvent() + _prevctx = localctx + self.state = 57 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,3,self._ctx) + if la_ == 1: + localctx = SolidityParser.AddExpressionContext(self, SolidityParser.ArithmeticExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_arithmeticExpression) + self.state = 42 + if not self.precpred(self._ctx, 6): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") + self.state = 43 + self.match(SolidityParser.T__5) + self.state = 44 + self.arithmeticExpression(7) + pass + + elif la_ == 2: + localctx = SolidityParser.SubtractExpressionContext(self, SolidityParser.ArithmeticExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_arithmeticExpression) + self.state = 45 + if not self.precpred(self._ctx, 5): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") + self.state = 46 + self.match(SolidityParser.T__6) + self.state = 47 + self.arithmeticExpression(6) + pass + + elif la_ == 3: + localctx = SolidityParser.MultiplyExpressionContext(self, SolidityParser.ArithmeticExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_arithmeticExpression) + self.state = 48 + if not self.precpred(self._ctx, 4): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") + self.state = 49 + self.match(SolidityParser.T__7) + self.state = 50 + self.arithmeticExpression(5) + pass + + elif la_ == 4: + localctx = SolidityParser.DivideExpressionContext(self, SolidityParser.ArithmeticExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_arithmeticExpression) + self.state = 51 + if not self.precpred(self._ctx, 3): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") + self.state = 52 + self.match(SolidityParser.T__8) + self.state = 53 + self.arithmeticExpression(4) + pass + + elif la_ == 5: + localctx = SolidityParser.PowExpressionContext(self, SolidityParser.ArithmeticExpressionContext(self, _parentctx, _parentState)) + self.pushNewRecursionContext(localctx, _startState, self.RULE_arithmeticExpression) + self.state = 54 + if not self.precpred(self._ctx, 2): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") + self.state = 55 + self.match(SolidityParser.T__9) + self.state = 56 + self.arithmeticExpression(3) + pass + + + self.state = 61 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,4,self._ctx) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.unrollRecursionContexts(_parentctx) + return localctx + + + class AtomContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return SolidityParser.RULE_atom + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + + class ParenthesizedArithmeticExpressionContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def arithmeticExpression(self): + return self.getTypedRuleContext(SolidityParser.ArithmeticExpressionContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterParenthesizedArithmeticExpression" ): + listener.enterParenthesizedArithmeticExpression(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitParenthesizedArithmeticExpression" ): + listener.exitParenthesizedArithmeticExpression(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitParenthesizedArithmeticExpression" ): + return visitor.visitParenthesizedArithmeticExpression(self) + else: + return visitor.visitChildren(self) + + + class LengthAccessContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def LengthAccess(self): + return self.getToken(SolidityParser.LengthAccess, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterLengthAccess" ): + listener.enterLengthAccess(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitLengthAccess" ): + listener.exitLengthAccess(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLengthAccess" ): + return visitor.visitLengthAccess(self) + else: + return visitor.visitChildren(self) + + + class ContractVariableAccessContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def contractVariableAccessExpr(self): + return self.getTypedRuleContext(SolidityParser.ContractVariableAccessExprContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterContractVariableAccess" ): + listener.enterContractVariableAccess(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitContractVariableAccess" ): + listener.exitContractVariableAccess(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitContractVariableAccess" ): + return visitor.visitContractVariableAccess(self) + else: + return visitor.visitChildren(self) + + + class VariableContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def VariableName(self): + return self.getToken(SolidityParser.VariableName, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterVariable" ): + listener.enterVariable(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitVariable" ): + listener.exitVariable(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVariable" ): + return visitor.visitVariable(self) + else: + return visitor.visitChildren(self) + + + class MappingElementContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def MappingElement(self): + return self.getToken(SolidityParser.MappingElement, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterMappingElement" ): + listener.enterMappingElement(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitMappingElement" ): + listener.exitMappingElement(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitMappingElement" ): + return visitor.visitMappingElement(self) + else: + return visitor.visitChildren(self) + + + class BlockAccessContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def BlockAccess(self): + return self.getToken(SolidityParser.BlockAccess, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterBlockAccess" ): + listener.enterBlockAccess(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitBlockAccess" ): + listener.exitBlockAccess(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitBlockAccess" ): + return visitor.visitBlockAccess(self) + else: + return visitor.visitChildren(self) + + + class AddressLiteralContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def AddressLiteral(self): + return self.getToken(SolidityParser.AddressLiteral, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterAddressLiteral" ): + listener.enterAddressLiteral(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitAddressLiteral" ): + listener.exitAddressLiteral(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAddressLiteral" ): + return visitor.visitAddressLiteral(self) + else: + return visitor.visitChildren(self) + + + class ContractVariableArrayElementContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def contractVariableArrayElemExpr(self): + return self.getTypedRuleContext(SolidityParser.ContractVariableArrayElemExprContext,0) + + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterContractVariableArrayElement" ): + listener.enterContractVariableArrayElement(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitContractVariableArrayElement" ): + listener.exitContractVariableArrayElement(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitContractVariableArrayElement" ): + return visitor.visitContractVariableArrayElement(self) + else: + return visitor.visitChildren(self) + + + class ArrayElementContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def ArrayElement(self): + return self.getToken(SolidityParser.ArrayElement, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterArrayElement" ): + listener.enterArrayElement(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitArrayElement" ): + listener.exitArrayElement(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitArrayElement" ): + return visitor.visitArrayElement(self) + else: + return visitor.visitChildren(self) + + + class IntegerLiteralContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def INTEGER(self): + return self.getToken(SolidityParser.INTEGER, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterIntegerLiteral" ): + listener.enterIntegerLiteral(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitIntegerLiteral" ): + listener.exitIntegerLiteral(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIntegerLiteral" ): + return visitor.visitIntegerLiteral(self) + else: + return visitor.visitChildren(self) + + + class MsgAccessContext(AtomContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a SolidityParser.AtomContext + super().__init__(parser) + self.copyFrom(ctx) + + def MsgAccess(self): + return self.getToken(SolidityParser.MsgAccess, 0) + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterMsgAccess" ): + listener.enterMsgAccess(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitMsgAccess" ): + listener.exitMsgAccess(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitMsgAccess" ): + return visitor.visitMsgAccess(self) + else: + return visitor.visitChildren(self) + + + + def atom(self): + + localctx = SolidityParser.AtomContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_atom) + try: + self.state = 76 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,5,self._ctx) + if la_ == 1: + localctx = SolidityParser.VariableContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 62 + self.match(SolidityParser.VariableName) + pass + + elif la_ == 2: + localctx = SolidityParser.LengthAccessContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 63 + self.match(SolidityParser.LengthAccess) + pass + + elif la_ == 3: + localctx = SolidityParser.ArrayElementContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 64 + self.match(SolidityParser.ArrayElement) + pass + + elif la_ == 4: + localctx = SolidityParser.MappingElementContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 65 + self.match(SolidityParser.MappingElement) + pass + + elif la_ == 5: + localctx = SolidityParser.AddressLiteralContext(self, localctx) + self.enterOuterAlt(localctx, 5) + self.state = 66 + self.match(SolidityParser.AddressLiteral) + pass + + elif la_ == 6: + localctx = SolidityParser.IntegerLiteralContext(self, localctx) + self.enterOuterAlt(localctx, 6) + self.state = 67 + self.match(SolidityParser.INTEGER) + pass + + elif la_ == 7: + localctx = SolidityParser.ParenthesizedArithmeticExpressionContext(self, localctx) + self.enterOuterAlt(localctx, 7) + self.state = 68 + self.match(SolidityParser.T__3) + self.state = 69 + self.arithmeticExpression(0) + self.state = 70 + self.match(SolidityParser.T__4) + pass + + elif la_ == 8: + localctx = SolidityParser.BlockAccessContext(self, localctx) + self.enterOuterAlt(localctx, 8) + self.state = 72 + self.match(SolidityParser.BlockAccess) + pass + + elif la_ == 9: + localctx = SolidityParser.MsgAccessContext(self, localctx) + self.enterOuterAlt(localctx, 9) + self.state = 73 + self.match(SolidityParser.MsgAccess) + pass + + elif la_ == 10: + localctx = SolidityParser.ContractVariableAccessContext(self, localctx) + self.enterOuterAlt(localctx, 10) + self.state = 74 + self.contractVariableAccessExpr() + pass + + elif la_ == 11: + localctx = SolidityParser.ContractVariableArrayElementContext(self, localctx) + self.enterOuterAlt(localctx, 11) + self.state = 75 + self.contractVariableArrayElemExpr() + pass + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class ContractVariableAccessExprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def VariableName(self, i:int=None): + if i is None: + return self.getTokens(SolidityParser.VariableName) + else: + return self.getToken(SolidityParser.VariableName, i) + + def getRuleIndex(self): + return SolidityParser.RULE_contractVariableAccessExpr + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterContractVariableAccessExpr" ): + listener.enterContractVariableAccessExpr(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitContractVariableAccessExpr" ): + listener.exitContractVariableAccessExpr(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitContractVariableAccessExpr" ): + return visitor.visitContractVariableAccessExpr(self) + else: + return visitor.visitChildren(self) + + + + + def contractVariableAccessExpr(self): + + localctx = SolidityParser.ContractVariableAccessExprContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_contractVariableAccessExpr) + try: + self.enterOuterAlt(localctx, 1) + self.state = 78 + self.match(SolidityParser.VariableName) + self.state = 79 + self.match(SolidityParser.T__10) + self.state = 80 + self.match(SolidityParser.VariableName) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class ContractVariableArrayElemExprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def VariableName(self, i:int=None): + if i is None: + return self.getTokens(SolidityParser.VariableName) + else: + return self.getToken(SolidityParser.VariableName, i) + + def INTEGER(self): + return self.getToken(SolidityParser.INTEGER, 0) + + def ADDRESS(self): + return self.getToken(SolidityParser.ADDRESS, 0) + + def getRuleIndex(self): + return SolidityParser.RULE_contractVariableArrayElemExpr + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterContractVariableArrayElemExpr" ): + listener.enterContractVariableArrayElemExpr(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitContractVariableArrayElemExpr" ): + listener.exitContractVariableArrayElemExpr(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitContractVariableArrayElemExpr" ): + return visitor.visitContractVariableArrayElemExpr(self) + else: + return visitor.visitChildren(self) + + + + + def contractVariableArrayElemExpr(self): + + localctx = SolidityParser.ContractVariableArrayElemExprContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_contractVariableArrayElemExpr) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 82 + self.match(SolidityParser.VariableName) + self.state = 83 + self.match(SolidityParser.T__10) + self.state = 84 + self.match(SolidityParser.VariableName) + self.state = 85 + self.match(SolidityParser.T__11) + self.state = 86 + _la = self._input.LA(1) + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 229376) != 0)): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 87 + self.match(SolidityParser.T__12) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + + def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): + if self._predicates == None: + self._predicates = dict() + self._predicates[1] = self.booleanExpression_sempred + self._predicates[2] = self.arithmeticExpression_sempred + pred = self._predicates.get(ruleIndex, None) + if pred is None: + raise Exception("No predicate with index:" + str(ruleIndex)) + else: + return pred(localctx, predIndex) + + def booleanExpression_sempred(self, localctx:BooleanExpressionContext, predIndex:int): + if predIndex == 0: + return self.precpred(self._ctx, 6) + + + if predIndex == 1: + return self.precpred(self._ctx, 5) + + + def arithmeticExpression_sempred(self, localctx:ArithmeticExpressionContext, predIndex:int): + if predIndex == 2: + return self.precpred(self._ctx, 6) + + + if predIndex == 3: + return self.precpred(self._ctx, 5) + + + if predIndex == 4: + return self.precpred(self._ctx, 4) + + + if predIndex == 5: + return self.precpred(self._ctx, 3) + + + if predIndex == 6: + return self.precpred(self._ctx, 2) + + + + + diff --git a/src/kontrol/solidity/SolidityVisitor.py b/src/kontrol/solidity/SolidityVisitor.py new file mode 100644 index 000000000..9e4050a0d --- /dev/null +++ b/src/kontrol/solidity/SolidityVisitor.py @@ -0,0 +1,143 @@ +# Generated from src/kontrol/solidity/Solidity.g4 by ANTLR 4.13.2 +from antlr4 import * +if "." in __name__: + from .SolidityParser import SolidityParser +else: + from SolidityParser import SolidityParser + +# This class defines a complete generic visitor for a parse tree produced by SolidityParser. + +class SolidityVisitor(ParseTreeVisitor): + + # Visit a parse tree produced by SolidityParser#expression. + def visitExpression(self, ctx:SolidityParser.ExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#RelationalExpression. + def visitRelationalExpression(self, ctx:SolidityParser.RelationalExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#AndExpression. + def visitAndExpression(self, ctx:SolidityParser.AndExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#BooleanLiteral. + def visitBooleanLiteral(self, ctx:SolidityParser.BooleanLiteralContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#NotExpression. + def visitNotExpression(self, ctx:SolidityParser.NotExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#OrExpression. + def visitOrExpression(self, ctx:SolidityParser.OrExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#ParenthesizedBooleanExpression. + def visitParenthesizedBooleanExpression(self, ctx:SolidityParser.ParenthesizedBooleanExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#SubtractExpression. + def visitSubtractExpression(self, ctx:SolidityParser.SubtractExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#DivideExpression. + def visitDivideExpression(self, ctx:SolidityParser.DivideExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#AddExpression. + def visitAddExpression(self, ctx:SolidityParser.AddExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#PowExpression. + def visitPowExpression(self, ctx:SolidityParser.PowExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#MultiplyExpression. + def visitMultiplyExpression(self, ctx:SolidityParser.MultiplyExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#AtomExpression. + def visitAtomExpression(self, ctx:SolidityParser.AtomExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#Variable. + def visitVariable(self, ctx:SolidityParser.VariableContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#LengthAccess. + def visitLengthAccess(self, ctx:SolidityParser.LengthAccessContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#ArrayElement. + def visitArrayElement(self, ctx:SolidityParser.ArrayElementContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#MappingElement. + def visitMappingElement(self, ctx:SolidityParser.MappingElementContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#AddressLiteral. + def visitAddressLiteral(self, ctx:SolidityParser.AddressLiteralContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#IntegerLiteral. + def visitIntegerLiteral(self, ctx:SolidityParser.IntegerLiteralContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#ParenthesizedArithmeticExpression. + def visitParenthesizedArithmeticExpression(self, ctx:SolidityParser.ParenthesizedArithmeticExpressionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#BlockAccess. + def visitBlockAccess(self, ctx:SolidityParser.BlockAccessContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#MsgAccess. + def visitMsgAccess(self, ctx:SolidityParser.MsgAccessContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#ContractVariableAccess. + def visitContractVariableAccess(self, ctx:SolidityParser.ContractVariableAccessContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#ContractVariableArrayElement. + def visitContractVariableArrayElement(self, ctx:SolidityParser.ContractVariableArrayElementContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#contractVariableAccessExpr. + def visitContractVariableAccessExpr(self, ctx:SolidityParser.ContractVariableAccessExprContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by SolidityParser#contractVariableArrayElemExpr. + def visitContractVariableArrayElemExpr(self, ctx:SolidityParser.ContractVariableArrayElemExprContext): + return self.visitChildren(ctx) + + + +del SolidityParser \ No newline at end of file diff --git a/src/tests/integration/test-data/foundry-prove-all b/src/tests/integration/test-data/foundry-prove-all index 8f79dad6f..d7f9de07b 100644 --- a/src/tests/integration/test-data/foundry-prove-all +++ b/src/tests/integration/test-data/foundry-prove-all @@ -205,6 +205,7 @@ PrankTest.testSubtractFail(uint256) PrankTest.testSubtractStartPrank(uint256,uint256) PrankTestMsgSender.test_msgsender_setup() PrankTestOrigin.test_origin_setup() +PreconditionTest.testPrecondition(uint256) RecordLogsTest.testRecordLogs() RollTest.test_roll_setup() SafeTest.testWithdraw() diff --git a/src/tests/integration/test-data/foundry-prove-skip-legacy b/src/tests/integration/test-data/foundry-prove-skip-legacy index 4096951c6..21b5adce2 100644 --- a/src/tests/integration/test-data/foundry-prove-skip-legacy +++ b/src/tests/integration/test-data/foundry-prove-skip-legacy @@ -202,6 +202,7 @@ PrankTest.testFailAddPrank(uint256) PrankTest.testSubtractAsTxOrigin(uint256,uint256) PrankTest.testSubtractFail(uint256) PrankTest.testSubtractStartPrank(uint256,uint256) +PreconditionTest.testPrecondition(uint256) RecordLogsTest.testRecordLogs() RollTest.test_roll_setup() SafeTest.testWithdraw() diff --git a/src/tests/integration/test-data/foundry/test/PreconditionTest.t.sol b/src/tests/integration/test-data/foundry/test/PreconditionTest.t.sol new file mode 100644 index 000000000..bdf51792d --- /dev/null +++ b/src/tests/integration/test-data/foundry/test/PreconditionTest.t.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; + + +contract Precondition { + /// @custom:kontrol-precondition x >= 2, + function totalSupply(uint256 x) public pure returns (uint256) { return x; } +} + +contract PreconditionTest is Test { + /// @custom:kontrol-precondition x <= 14, + function testPrecondition(uint256 x) public { + Precondition p = new Precondition(); + uint256 r = p.totalSupply(x); + assert(r <= 14); + } +} \ No newline at end of file