Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Use grammar
4This module requires `antlr4-python3-runtime <https://pypi.python.org/pypi/antlr4-python3-runtime/>`_.
5"""
6import os
7from antlr4 import ParseTreeWalker, CommonTokenStream, InputStream
8from .tree_string_listener import TreeStringListener
9from .tree_graph_listener import TreeGraphListener
12def get_parser_lexer(language):
13 """
14 Returns two classes, a parser and a lexer from :epkg:`antlr4`.
16 @param language to analyse
17 @return Parser, Lexer
18 """
19 try:
20 if language == "C#" or language == "CSharp":
21 language = "CSharp4"
23 if language == "R":
24 from .RLexer import RLexer
25 from .RParser import RParser
26 return RParser, RLexer
27 elif language == "CSharp4":
28 from .CSharpLexer import CSharpLexer
29 from .CSharpParser import CSharpParser
30 return CSharpParser, CSharpLexer
31 elif language == "SQLite":
32 from .SQLiteLexer import SQLiteLexer
33 from .SQLiteParser import SQLiteParser
34 return SQLiteParser, SQLiteLexer
35 elif language == "DOT":
36 from .DOTLexer import DOTLexer
37 from .DOTParser import DOTParser
38 return DOTParser, DOTLexer
39 elif language == "Pig":
40 raise ImportError("Pig is not available yet")
41 # from .PigLexer import PigLexer
42 # from .PigParser import PigParser
43 # return PigParser, PigLexer
44 elif language == "Python3":
45 from .Python3Lexer import Python3Lexer
46 from .Python3Parser import Python3Parser
47 return Python3Parser, Python3Lexer
48 elif language == "SimpleWorkflow":
49 from .SimpleWorkflowLexer import SimpleWorkflowLexer
50 from .SimpleWorkflowParser import SimpleWorkflowParser
51 return SimpleWorkflowParser, SimpleWorkflowLexer
52 else:
53 folder = os.path.dirname(__file__)
54 if folder == "":
55 folder = "."
56 files = os.listdir(folder)
57 raise ImportError(
58 "unable to import parsers for language: " +
59 language +
60 "\navailable files:\n{0}".format(
61 "\n".join(files)))
62 except ImportError as e:
63 folder = os.path.dirname(__file__)
64 if folder == "":
65 folder = "."
66 files = os.listdir(folder)
67 raise ImportError(
68 "unable to import parsers for language: " +
69 language +
70 "\navailable files:\n{0}".format(
71 "\n".join(files))) from e
74def parse_code(code, class_parser, class_lexer):
75 """
76 Parses a code and returns a tree.
78 @param code code to parse
79 @param class_parser parser
80 @param class_lexer lexer
81 @return parsed code
83 .. exref::
84 :title: Check the syntax of a script PIG
86 ::
88 code = '''
89 A = LOAD 'filename.txt' USING PigStorage('\t');
90 STORE A INTO 'samefile.txt' ;
91 '''
93 clparser, cllexer = get_parser_lexer("Pig")
94 parser = parse_code(code, clparser, cllexer)
95 tree = parser.compilation_unit()
96 st = get_tree_string(tree, parser, None)
97 print(st)
98 """
99 if isinstance(code, str):
100 # we assume it is a string
101 code = InputStream(code)
103 lexer = class_lexer(code)
104 stream = CommonTokenStream(lexer)
105 parser = class_parser(stream)
106 return parser
109def get_tree_string(tree, parser, format=TreeStringListener):
110 """
111 Returns a string which shows the parsed tree.
113 @param tree from @see fn parse_code
114 @param parser the parser used to build the tree, output of @see fn parse_code
115 @param format None or a class `ParseTreeListener <https://github.com/antlr/antlr4-python3/blob/master/src/antlr4/tree/Tree.py>`_
116 @return string
117 """
118 if format is None:
119 return tree.toStringTree()
120 else:
121 walker = ParseTreeWalker()
122 listen = format(parser)
123 walker.walk(listen, tree)
124 return str(listen)
127def get_tree_graph(tree, parser, format=TreeGraphListener):
128 """
129 Returns a graph with :epkg:`networkx`.
131 @param tree from @see fn parse_code
132 @param parser the parser used to build the tree, output of @see fn parse_code
133 @param format None or a class `ParseTreeListener <https://github.com/antlr/antlr4-python3/blob/master/src/antlr4/tree/Tree.py>`_
134 @return string
135 """
136 if format is None:
137 raise TypeError( # pragma: no cover
138 "format cannot be None")
139 walker = ParseTreeWalker()
140 listen = format(parser)
141 walker.walk(listen, tree)
142 return listen