def parse_type(self, ctx: ParserRuleContext, type: TypeSymbol): if not ctx.typeSymbol(): type.is_void = True type.name = 'void' else: if ctx.typeSymbol().primitiveTypeSymbol(): ctxSymbol = ctx.typeSymbol().primitiveTypeSymbol( ) # type:TParser.PrimitiveTypeSymbolContext type.is_primitive = True type.name = ctxSymbol.name.text elif ctx.typeSymbol().complexTypeSymbol(): ctxSymbol = ctx.typeSymbol().complexTypeSymbol( ) # type:TParser.ComplexTypeSymbolContext type.is_complex = True type.name = ctxSymbol.name.text elif ctx.typeSymbol().listTypeSymbol(): ctxSymbol = ctx.typeSymbol().listTypeSymbol( ) # type:TParser.ListTypeSymbolContext type.is_list = True type.name = 'list' type.nested = TypeSymbol("", type) self.parse_type(ctxSymbol, type.nested) elif ctx.typeSymbol().modelTypeSymbol(): ctxSymbol = ctx.typeSymbol().modelTypeSymbol( ) # type:TParser.ModelTypeSymbolContext type.is_model = True type.name = 'model' type.nested = TypeSymbol("", type) self.parse_type(ctxSymbol, type.nested) if not type.module.checkType(type): log.warn('Unknown type: {0}. Missing import?'.format(type.name))
def _visitBinaryExpression(self, ctx: ParserRuleContext): """ All binary expressions fit this patten so we refactored the code """ if ctx.getChildCount() == 1: return self.visit(ctx.getChild(0)) else: return BinaryExpression( op=BinaryOperator[ctx.getChild(1).getText()], lhs=self.visit(ctx.getChild(0)), rhs=self.visit(ctx.getChild(2)), )
def visit_symbol(self, ctx: antlr4.ParserRuleContext, kind:int=SymbolKind.Variable, visit_children:bool=True): id_ctx = ctx.getChild(0, Parser.IdentifierContext) symbol = DocumentSymbol( name=id_ctx.start.text, kind=kind, range=Range( start=Position(ctx.start.line-1, ctx.start.column), end=Position(ctx.stop.line-1, ctx.stop.column) ), selection_range=Range( start=Position(id_ctx.start.line-1, id_ctx.start.column), end=Position(id_ctx.stop.line-1, id_ctx.stop.column) ), detail="", children=[], deprecated=False ) logging.debug(f"found symbol: {symbol.name}") self.scope.append(symbol) if visit_children: logging.debug(f"Visiting children of symbol: {symbol.name}") prev_scope = self.scope self.scope = symbol.children res = self.visitChildren(ctx) self.scope = prev_scope return res
def get_value_pattern(self, ctx: ParserRuleContext): """ :param ctx: the ParserRuleContext :return formatted key closing string :rtype str """ _count = ctx.getChildCount() if _count != 1: raise Exception("Not a value ctx: " + ctx.getText()) _key = str(ctx.getText()) if not self._ignore_value_case: if self._uppercase_values: _key = _key.upper() else: _key = _key.lower() _ret_string = _key return _ret_string
def __get_namespace_prefix(self, ctx: ParserRuleContext): prefix = "" while not isinstance(ctx.parentCtx, DynabuffersParser.CompilationContext): ctx = ctx.parentCtx if isinstance(ctx, DynabuffersParser.NamespaceTypeContext): prefix = "{}.{}".format(ctx.getText(), prefix) return prefix
def _checkIfMethodBelongsToClass(self, node: ParserRuleContext, classType) -> ClassName: while node.parentCtx: if isinstance(node, classType): return node.getChild(1).getText() node = node.parentCtx return cast(ClassName, None)
def get_key_value_pattern(self, ctx: ParserRuleContext): """ returns the key/value pattern of the context It is assumed, that the context has 5 children, that represent the k/v: '0' left parenthesis '1' key '2' equals '3' value '4' right parenthesis :param ctx: the ParserRuleContext :return formatted key value string :rtype str """ _count = ctx.getChildCount() # count==5 indicates Key/Value context if _count == 5: _key = str(ctx.getChild(1)) if not self._ignore_keyword_case: if self._uppercase_keywords: _key = _key.upper() else: _key = _key.lower() _value = str(ctx.getChild(3)) if not self._ignore_value_case: if self._uppercase_values: _value = _value.upper() else: _value = _value.lower() _ret_string = str(ctx.getChild(0)) + _key + str( ctx.getChild(2)) + _value + str(ctx.getChild(4)) return _ret_string raise Exception("Not a key value ctx: " + ctx.getText())
def fun_wrapper(self, ctx: antlr4.ParserRuleContext) -> str: if PRINT_TREE: self.tree_depth += 1 print(' ' * self.tree_depth + ctx.getText().replace('\n', '; ')) ret_val = fun(self, ctx) self.tree_depth -= 1 return ret_val else: return fun(self, ctx)
def get_key_opening_pattern(self, ctx: ParserRuleContext): """ returns the key opening pattern, like (address= :param ctx: the ParserRuleContext :return formatted key opening string :rtype str """ _count = ctx.getChildCount() if _count < 5: raise Exception("Not a key opening ctx: " + ctx.getText()) _key = str(ctx.getChild(1)) if not self._ignore_keyword_case: if self._uppercase_keywords: _key = _key.upper() else: _key = _key.lower() _ret_string = str(ctx.getChild(0)) + _key + str(ctx.getChild(2)) return _ret_string
def get_key_closing_pattern(self, ctx: ParserRuleContext): """ returns the key closing pattern :param ctx: the ParserRuleContext :return formatted key closing string :rtype str """ _count = ctx.getChildCount() if _count < 5: raise Exception("Not a key closing ctx") _key = str(ctx.getChild(_count - 1)) if not self._ignore_keyword_case: if self._uppercase_keywords: _key = _key.upper() else: _key = _key.lower() _ret_string = _key return _ret_string
def evaluate(self, t: ParseTree): dummyRoot = ParserRuleContext() dummyRoot.children = [t] # don't set t's parent. work = [dummyRoot] for i in range(0, len(self.elements)): next = set() for node in work: if len(node.children) > 0: # only try to match next element if it has children # e.g., //func/*/stat might have a token node for which # we can't go looking for stat nodes. matching = self.elements[i].evaluate(node) next |= matching i += 1 work = next return work
def process(self, ctx: ParserRuleContext): rule = ctx.getRuleIndex() if rule in self.ASSIGNMENTS: self.a += 1 elif rule in self.BRANCHES: self.b += 1 elif rule in self.CONDITIONALS: self.c += 1 return self.visitChildren(ctx)
def evaluate(self, t:ParseTree): dummyRoot = ParserRuleContext() dummyRoot.children = [t] # don't set t's parent. work = [dummyRoot] for i in range(0, len(self.elements)): next = set() for node in work: if len( node.children) > 0 : # only try to match next element if it has children # e.g., //func/*/stat might have a token node for which # we can't go looking for stat nodes. matching = self.elements[i].evaluate(node) next |= matching i += 1 work = next return work
def get_key_value_pattern(self, ctx: ParserRuleContext): """ returns the key/value pattern of the context It is assumed, that the context has 5 children, that represent the k/v: '0' left parenthesis '1' key '2' equals '3' value '4' right parenthesis :param ctx: the ParserRuleContext :return formatted key value string :rtype str """ _count = ctx.getChildCount() # count==5 indicates Key/Value context if _count == 5: _key = str(ctx.getChild(1)) if not self._ignore_keyword_case: if self._uppercase_keywords: _key = _key.upper() else: _key = _key.lower() _value = str(ctx.getChild(3)) if not self._ignore_value_case: if self._uppercase_values: _value = _value.upper() else: _value = _value.lower() _ret_string = str(ctx.getChild(0)) + _key + str(ctx.getChild(2)) + _value + str(ctx.getChild(4)) return _ret_string raise Exception("Not a key value ctx: " + ctx.getText())
def validate_ctx(py_ctx:ParserRuleContext, cpp_ctx:ParserRuleContext): assert type(py_ctx) == type(cpp_ctx) pc = list(py_ctx.getChildren()) cc = list(cpp_ctx.getChildren()) assert len(pc) == len(cc) # Validate children for i in range(len(pc)): if isinstance(pc[i], TerminalNodeImpl): validate_tnode(pc[i], cc[i]) elif isinstance(pc[i], ParserRuleContext): validate_ctx(pc[i], cc[i]) else: raise RuntimeError assert pc[i].parentCtx is py_ctx assert cc[i].parentCtx is cpp_ctx # Validate start/stop markers if (py_ctx.start is not None and py_ctx.stop is not None and py_ctx.start.type != Token.EOF and py_ctx.stop.type != Token.EOF and py_ctx.start.tokenIndex <= py_ctx.stop.tokenIndex): validate_common_token(py_ctx.start, cpp_ctx.start) validate_common_token(py_ctx.stop, cpp_ctx.stop) # Validate labels for label in get_rule_labels(py_ctx): if label.startswith("_"): continue py_label = getattr(py_ctx, label) cpp_label = getattr(cpp_ctx, label) assert type(py_label) == type(cpp_label) if isinstance(py_label, CommonToken): validate_common_token(py_label, cpp_label) elif isinstance(py_label, ParserRuleContext): validate_ctx(py_label, cpp_label) # Validate other ctx members assert py_ctx.invokingState == cpp_ctx.invokingState
def evaluate(self, t: ParseTree): dummyRoot = ParserRuleContext() dummyRoot.children = [t] # don't set t's parent. work = [dummyRoot] for element in self.elements: work_next = list() for node in work: if not isinstance(node, TerminalNode) and node.children: # only try to match next element if it has children # e.g., //func/*/stat might have a token node for which # we can't go looking for stat nodes. matching = element.evaluate(node) # See issue antlr#370 - Prevents XPath from returning the # same node multiple times matching = filter(lambda m: m not in work_next, matching) work_next.extend(matching) work = work_next return work
def __init__(self, parent_node, filename: str, ctx: ParserRuleContext): """ :param parent_node: :param filename: :param ctx: ParserRuleContextNode """ super().__init__(parent_node) start = ctx.start self._filename = filename self._line = start.line self._column = start.column self._value = ctx.getText()
def get_context_data(context_cls:antlr4.ParserRuleContext) -> ContextData: """ Given a ParserRuleContext class, extract information about it and return a ContextData object """ if antlr4.ParserRuleContext in context_cls.__bases__: # Is a pure rule context ctx_classname = context_cls.__name__ label_ctx_classname = None else: # Is a labeled sub-context ctx_classname = context_cls.__bases__[0].__name__ label_ctx_classname = context_cls.__name__ labels = get_rule_labels(context_cls) is_label_parent = bool(context_cls.__subclasses__()) return ContextData(ctx_classname, label_ctx_classname, is_label_parent, labels)
def _visit_binary_expression(self, ctx: ParserRuleContext): return ast.BinaryExpression( lhs=self.visit(ctx.expression(0)), op=ast.BinaryOperator[ctx.op.text], rhs=self.visit(ctx.expression(1)), )
def _createPrimitive( self, ctx: ParserRuleContext ) -> Optional[Union[QuotedString, int, bool, float, str]]: ret: Optional[Union[int, bool, float, str]] first_idx = 0 last_idx = ctx.getChildCount() # skip first if whitespace if self.is_ws(ctx.getChild(0)): if last_idx == 1: # Only whitespaces => this is not allowed. raise HydraException( "Trying to parse a primitive that is all whitespaces" ) first_idx = 1 if self.is_ws(ctx.getChild(-1)): last_idx = last_idx - 1 num = last_idx - first_idx if num > 1: # Concatenate, while un-escaping as needed. tokens = [] for i, n in enumerate(ctx.getChildren()): if n.symbol.type == OverrideLexer.WS and ( i < first_idx or i >= last_idx ): # Skip leading / trailing whitespaces. continue tokens.append( n.symbol.text[1::2] # un-escape by skipping every other char if n.symbol.type == OverrideLexer.ESC else n.symbol.text ) ret = "".join(tokens) else: node = ctx.getChild(first_idx) if node.symbol.type == OverrideLexer.QUOTED_VALUE: text = node.getText() qc = text[0] text = text[1:-1] if qc == "'": quote = Quote.single text = text.replace("\\'", "'") elif qc == '"': quote = Quote.double text = text.replace('\\"', '"') else: assert False return QuotedString(text=text, quote=quote) elif node.symbol.type in (OverrideLexer.ID, OverrideLexer.INTERPOLATION): ret = node.symbol.text elif node.symbol.type == OverrideLexer.INT: ret = int(node.symbol.text) elif node.symbol.type == OverrideLexer.FLOAT: ret = float(node.symbol.text) elif node.symbol.type == OverrideLexer.NULL: ret = None elif node.symbol.type == OverrideLexer.BOOL: text = node.getText().lower() if text == "true": ret = True elif text == "false": ret = False else: assert False elif node.symbol.type == OverrideLexer.ESC: ret = node.symbol.text[1::2] else: return node.getText() # type: ignore return ret
def ctx(): """Returns a dummy rule context""" return ParserRuleContext()
def to_runtime_error(self, ctx: ParserRuleContext) -> Exception: interval = ctx.getSourceInterval() msg = "\n" + self.sql.get_raw_lines( interval[0], interval[1], add_lineno=True) return FugueSQLRuntimeError(msg)
def ast_to_str(tree: ParserRuleContext) -> str: """ Antlr4 "lisp" style tree print for comparison. """ tree.toStringTree(None, tree.parser)
def visit(self, ctx: ParserRuleContext): return ctx.accept(self) if ctx is not None else None
def visitTerminal(self, ctx: ParserRuleContext) -> Terminal: """Converts case insensitive keywords and identifiers to lowercase""" text = ctx.getText() return Terminal.from_text(text, ctx)