1616Generate C++ parser and lexer from a grammar file.
1717"""
1818
19- load ("@rules_antlr//antlr:antlr4.bzl" , "antlr" )
20-
21- def antlr_cc_library (name , src , package = None , listener = False , visitor = True ):
19+ def antlr_cc_library (name , src , package ):
2220 """Creates a C++ lexer and parser from a source grammar.
2321
2422 Args:
2523 name: Base name for the lexer and the parser rules.
2624 src: source ANTLR grammar file
2725 package: The namespace for the generated code
28- listener: generate ANTLR listener (default: False)
29- visitor: generate ANTLR visitor (default: True)
3026 """
3127 generated = name + "_grammar"
32- antlr (
28+ antlr_library (
3329 name = generated ,
34- srcs = [src ],
35- language = "Cpp" ,
36- listener = listener ,
37- visitor = visitor ,
30+ src = src ,
3831 package = package ,
3932 )
4033 native .cc_library (
@@ -46,3 +39,63 @@ def antlr_cc_library(name, src, package = None, listener = False, visitor = True
4639 ],
4740 linkstatic = 1 ,
4841 )
42+
43+ def _antlr_library (ctx ):
44+ output = ctx .actions .declare_directory (ctx .attr .name )
45+
46+ antlr_args = ctx .actions .args ()
47+ antlr_args .add ("-Dlanguage=Cpp" )
48+ antlr_args .add ("-no-listener" )
49+ antlr_args .add ("-visitor" )
50+ antlr_args .add ("-o" , output .path )
51+ antlr_args .add ("-package" , ctx .attr .package )
52+ antlr_args .add (ctx .file .src )
53+
54+ basename = ctx .file .src .basename [:- 3 ]
55+ suffixes = ["Lexer" , "Parser" , "BaseVisitor" , "Visitor" ]
56+
57+ ctx .actions .run (
58+ arguments = [antlr_args ],
59+ inputs = [ctx .file .src ],
60+ outputs = [output ],
61+ executable = ctx .executable ._tool ,
62+ progress_message = "Processing ANTLR grammar" ,
63+ )
64+
65+ files = []
66+ for suffix in suffixes :
67+ header = ctx .actions .declare_file (basename + suffix + ".h" )
68+ source = ctx .actions .declare_file (basename + suffix + ".cpp" )
69+ generated = output .path + "/" + ctx .file .src .short_path [:- 3 ] + suffix
70+
71+ ctx .actions .run_shell (
72+ mnemonic = "CopyHeader" + suffix ,
73+ inputs = [output ],
74+ outputs = [header ],
75+ command = 'cp "{generated}" "{out}"' .format (generated = generated + ".h" , out = header .path ),
76+ )
77+ ctx .actions .run_shell (
78+ mnemonic = "CopySource" + suffix ,
79+ inputs = [output ],
80+ outputs = [source ],
81+ command = 'cp "{generated}" "{out}"' .format (generated = generated + ".cpp" , out = source .path ),
82+ )
83+
84+ files .append (header )
85+ files .append (source )
86+
87+ compilation_context = cc_common .create_compilation_context (headers = depset (files ))
88+ return [DefaultInfo (files = depset (files )), CcInfo (compilation_context = compilation_context )]
89+
90+ antlr_library = rule (
91+ implementation = _antlr_library ,
92+ attrs = {
93+ "src" : attr .label (allow_single_file = [".g4" ], mandatory = True ),
94+ "package" : attr .string (),
95+ "_tool" : attr .label (
96+ executable = True ,
97+ cfg = "host" ,
98+ default = Label ("//bazel:antlr4_tool" ),
99+ ),
100+ },
101+ )
0 commit comments