def __init__(self, language_def, root_rule_name, comment_rule_name=None, *args, **kwargs): """ Constructs parser from textual PEG definition. Args: language_def (str): A string describing language grammar using PEG notation. root_rule_name(str): The name of the root rule. comment_rule_name(str): The name of the rule for comments. """ super(ParserPEG, self).__init__(*args, **kwargs) self.root_rule_name = root_rule_name self.comment_rule_name = comment_rule_name # PEG Abstract Syntax Graph self.parser_model, self.comments_model = self._from_peg(language_def) # Comments should be optional and there can be more of them if self.comments_model: self.comments_model.root = True self.comments_model.rule_name = comment_rule_name # In debug mode export parser model to dot for # visualization if self.debug: from arpeggio.export import PMDOTExporter root_rule = self.parser_model.rule_name PMDOTExporter().exportFile( self.parser_model, "{}_peg_parser_model.dot".format(root_rule))
def main(debug=False): current_dir = os.path.dirname(__file__) peg_grammar = open(os.path.join(current_dir, 'peg.peg')).read() # ParserPEG will use ParserPython to parse peg_grammar definition and # create parser_model for parsing PEG based grammars # In debug mode dot (graphviz) files for parser model # and parse tree will be created for visualization. # Checkout current folder for .dot files. parser = ParserPEG(peg_grammar, 'peggrammar', debug=debug) # Now we will use created parser to parse the same peg_grammar used for # parser initialization. We can parse peg_grammar because it is specified # using PEG itself. print("PARSING") parse_tree = parser.parse(peg_grammar) # ASG should be the same as parser.parser_model because semantic # actions will create PEG parser (tree of ParsingExpressions). parser_model, comment_model = visit_parse_tree( parse_tree, PEGVisitor(root_rule_name='peggrammar', comment_rule_name='comment', ignore_case=False, debug=debug)) if debug: # This graph should be the same as peg_peg_parser_model.dot because # they define the same parser. PMDOTExporter().exportFile(parser_model, "peg_peg_new_parser_model.dot") # If we replace parser_mode with ASG constructed parser it will still # parse PEG grammars parser.parser_model = parser_model parser.parse(peg_grammar)
def parse_from_str(language_def, debug=False): """ Constructs parser and initializes the model that is put into the parser. Args: language_def (str): The language in applang. Returns: The parser with the initialized model. """ if debug: print("*** APPLANG PARSER ***") # First create parser for TextX descriptions parser = ParserPython(model, comment_def=comment, debug=debug) PMDOTExporter().exportFile(parser.parser_model, "applang_parse_tree_model.dot") # Parse language description with textX parser parse_tree = parser.parse(language_def) #Invoice semantic analyze lang_parser = parser.getASG() if debug: # Create dot file for debuging purposes PTDOTExporter().exportFile(parse_tree, "applang_parse_tree.dot") return parser
def language_from_str(language_def, metamodel): """ Constructs parser and initializes metamodel from language description given in textX language. Args: language_def (str): A language description in textX. metamodel (TextXMetaModel): A metamodel to initialize. Returns: Parser for the new language. """ if metamodel.debug: metamodel.dprint("*** PARSING LANGUAGE DEFINITION ***") # Check the cache for already conctructed textX parser if metamodel.debug in textX_parsers: parser = textX_parsers[metamodel.debug] else: # Create parser for TextX grammars using # the arpeggio grammar specified in this module parser = ParserPython(textx_model, comment_def=comment, ignore_case=False, reduce_tree=False, memoization=metamodel.memoization, debug=metamodel.debug, file=metamodel.file) # Cache it for subsequent calls textX_parsers[metamodel.debug] = parser # Parse language description with textX parser try: parse_tree = parser.parse(language_def) except NoMatch as e: line, col = parser.pos_to_linecol(e.position) raise TextXSyntaxError(text(e), line, col) # Construct new parser and meta-model based on the given language # description. lang_parser = visit_parse_tree(parse_tree, TextXVisitor(parser, metamodel)) # Meta-model is constructed. Validate its semantics. metamodel.validate() # Here we connect meta-model and language parser for convenience. lang_parser.metamodel = metamodel metamodel._parser_blueprint = lang_parser if metamodel.debug: # Create dot file for debuging purposes PMDOTExporter().exportFile( lang_parser.parser_model, "{}_parser_model.dot".format(metamodel.rootcls.__name__)) return lang_parser
def test_export_parser_model(parser): """ Testing parser model export """ PMDOTExporter().exportFile(parser.parser_model, "test_exporter_parser_model.dot") assert os.path.exists("test_exporter_parser_model.dot")
def language_from_str(language_def, metamodel): """ Constructs parser and initializes metamodel from language description given in textX language. Args: language_def (str): A language description in textX. metamodel (TextXMetaModel): A metamodel to initialize. Returns: Parser for the new language. """ if metamodel.debug: metamodel.dprint("*** PARSING LANGUAGE DEFINITION ***") # Check the cache for already conctructed textX parser if metamodel.debug in textX_parsers: parser = textX_parsers[metamodel.debug] else: # Create parser for TextX descriptions from # the textX grammar specified in this module parser = ParserPython(textx_model, comment_def=comment, ignore_case=False, reduce_tree=False, debug=metamodel.debug) # Prepare regex used in keyword-like strmatch detection. # See str_match_SA flags = 0 if metamodel.ignore_case: flags = re.IGNORECASE parser.keyword_regex = re.compile(r'[^\d\W]\w*', flags) # Cache it for subsequent calls textX_parsers[metamodel.debug] = parser # This is used during parser construction phase. # Metamodel is filled in. Classes are created based on grammar rules. parser.metamodel = metamodel # Builtin rules representing primitive types parser.root_rule_name = None # Parse language description with textX parser try: parser.parse(language_def) except NoMatch as e: line, col = parser.pos_to_linecol(e.position) raise TextXSyntaxError(text(e), line, col) # Construct new parser based on the given language description. lang_parser = parser.getASG() # Meta-model is constructed. Validate semantics of metamodel. parser.metamodel.validate() # Meta-model is constructed. Here we connect meta-model and language # parser for convenience. lang_parser.metamodel = parser.metamodel metamodel.parser = lang_parser if metamodel.debug: # Create dot file for debuging purposes PMDOTExporter().exportFile( lang_parser.parser_model, "{}_parser_model.dot".format(metamodel.rootcls.__name__)) return lang_parser