Quellcode durchsuchen

antlr4: fix rules (#7007)

* antlr4: fix rules

* improve job

* improve group name

* fix parser visitor & listener

* use on_prepare_files

* use `xmake.version():ge("3.0.0")`
star9029 vor 4 Monaten
Ursprung
Commit
5071f4bc6c
3 geänderte Dateien mit 176 neuen und 113 gelöschten Zeilen
  1. 176 0
      packages/a/antlr4/rules/g4.lua
  2. 0 53
      packages/a/antlr4/rules/lexer.lua
  3. 0 60
      packages/a/antlr4/rules/parser.lua

+ 176 - 0
packages/a/antlr4/rules/g4.lua

@@ -0,0 +1,176 @@
+-- Usage
+--[[
+    add_requires("antlr4", "antlr4-runtime")
+
+    set_languages("c++17")
+    set_exceptions("cxx")
+
+    target("test")
+        set_kind("object")
+        add_files("src/*.g4")
+        add_rules("@antlr4/g4")
+        add_packages("antlr4", "antlr4-runtime")
+--]]
+
+rule("g4")
+    set_extensions(".g4")
+
+    add_deps("@find_antlr4")
+
+    if xmake.version():ge("3.0.0") then
+        on_prepare_files(function (target, jobgraph, sourcebatch, opt)
+            import("core.project.depend")
+            import("utils.progress")
+
+            local group_name = path.join(target:fullname(), "generate/g4")
+            local autogendir = path.join(target:autogendir(), "rules/antlr4")
+            jobgraph:group(group_name, function()
+                for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+                    local jave_job = path.join(group_name, sourcefile)
+                    local sourcefile_dir = path.normalize(path.join(autogendir, path.directory(sourcefile)))
+                    target:add("includedirs", sourcefile_dir, {public = true})
+                    os.mkdir(sourcefile_dir)
+                    jobgraph:add(jave_job, function (index, total, opt)
+                        local java = target:data("antlr4.tool")
+                        local argv = target:data("antlr4.tool.argv")
+                        table.join2(argv, target:values("antlr4.flags"))
+
+                        local fileconfig = target:fileconfig(sourcefile)
+                        if fileconfig then
+                            table.insert(argv, (fileconfig.visitor and "-visitor" or "-no-visitor"))
+                            table.insert(argv, (fileconfig.listener and "-listener" or "-no-listener"))
+                        end
+                        table.insert(argv, "-o")
+                        table.insert(argv, autogendir)
+                        table.insert(argv, "-lib")
+                        table.insert(argv, sourcefile_dir)
+                        table.insert(argv, sourcefile)
+
+                        depend.on_changed(function()
+                            progress.show(opt.progress or 0, "${color.build.object}compiling.g4 %s", sourcefile)
+                            os.vrunv(java.program, argv)
+                        end, {
+                            files = sourcefile,
+                            dependfile = target:dependfile(sourcefile),
+                            changed = target:is_rebuilt()
+                        })
+                    end)
+                end
+            end)
+        end, {jobgraph = true})
+
+        on_build_files(function (target, jobgraph, sourcebatch, opt)
+            for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+                local group_name = path.join(target:fullname(), "obj", sourcefile)
+                local sourcefile_dir = path.normalize(path.join(target:autogendir(), "rules/antlr4", path.directory(sourcefile)))
+                jobgraph:group(group_name, function()
+                    local batchcxx = {
+                        rulename = "c++.build",
+                        sourcekind = "cxx",
+                        sourcefiles = {},
+                        objectfiles = {},
+                        dependfiles = {}
+                    }
+                    -- g4 file have 3 case
+                    -- lexer grammar LuaLexer;
+                    -- parser grammar LuaParser;
+                    -- grammar C;
+                    local sourcefile_string = io.readfile(sourcefile)
+                    local lexer_name = sourcefile_string:match("lexer grammar (%w+);")
+                    local parser_name = sourcefile_string:match("parser grammar (%w+);")
+                    -- lexer and parser same name
+                    local grammar_name = sourcefile_string:match("grammar (%w+);")
+                    if lexer_name or parser_name then
+                        if lexer_name then
+                            table.insert(batchcxx.sourcefiles, path.join(sourcefile_dir, lexer_name .. ".cpp"))
+                        end
+                        if parser_name then
+                            table.insert(batchcxx.sourcefiles, path.join(sourcefile_dir, parser_name .. ".cpp"))
+                        end
+                    elseif grammar_name then
+                        table.insert(batchcxx.sourcefiles, path.join(sourcefile_dir, grammar_name .. "Parser.cpp"))
+                        table.insert(batchcxx.sourcefiles, path.join(sourcefile_dir, grammar_name .. "Lexer.cpp"))
+                    end
+
+                    for _, sourcefile in ipairs(batchcxx.sourcefiles) do
+                        local objectfile = target:objectfile(sourcefile)
+                        local dependfile = target:dependfile(objectfile)
+                        table.insert(target:objectfiles(), objectfile)
+                        table.insert(batchcxx.objectfiles, objectfile)
+                        table.insert(batchcxx.dependfiles, dependfile)
+                    end
+                    import("private.action.build.object")(target, jobgraph, batchcxx, opt)
+                end)
+            end
+        end, {jobgraph = true, distcc = true})
+    else
+        on_config(function (target)
+            local includedirs = {}
+            local autogendir = path.join(target:autogendir(), "rules/antlr4")
+            for _, sourcebatch in pairs(target:sourcebatches()) do
+                if sourcebatch.rulename == "@antlr4/g4" then
+                    for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+                        table.insert(includedirs, path.normalize(path.join(autogendir, path.directory(sourcefile))))
+                    end
+                    break
+                end
+            end
+            target:add("includedirs", table.unique(includedirs), {public = true})
+        end)
+
+        before_buildcmd_file(function (target, batchcmds, sourcefile_g4, opt)
+            local autogendir = path.join(target:autogendir(), "rules/antlr4")
+            local sourcefile_dir = path.normalize(path.join(autogendir, path.directory(sourcefile_g4)))
+            batchcmds:mkdir(sourcefile_dir)
+
+            local java = target:data("antlr4.tool")
+            local argv = target:data("antlr4.tool.argv")
+            table.join2(argv, target:values("antlr4.flags"))
+
+            local fileconfig = target:fileconfig(sourcefile_g4)
+            if fileconfig then
+                table.insert(argv, (fileconfig.visitor and "-visitor" or "-no-visitor"))
+                table.insert(argv, (fileconfig.listener and "-listener" or "-no-listener"))
+            end
+            table.insert(argv, "-o")
+            table.insert(argv, autogendir)
+            table.insert(argv, "-lib")
+            table.insert(argv, sourcefile_dir)
+            table.insert(argv, path(sourcefile_g4))
+
+            batchcmds:show_progress(opt.progress, "${color.build.object}compiling.g4 %s", sourcefile_g4)
+            batchcmds:vrunv(java.program, argv)
+
+            local _build = function (sourcefile_cxx)
+                local objectfile = target:objectfile(sourcefile_cxx)
+                table.insert(target:objectfiles(), objectfile)
+                batchcmds:show_progress(opt.progress, "${color.build.object}compiling.$(mode) %s", sourcefile_cxx)
+                batchcmds:compile(sourcefile_cxx, objectfile)
+        
+                batchcmds:add_depfiles(sourcefile_g4)
+                batchcmds:set_depmtime(os.mtime(objectfile))
+                batchcmds:set_depcache(target:dependfile(objectfile))
+            end
+
+            -- g4 file have 3 case
+            -- lexer grammar LuaLexer;
+            -- parser grammar LuaParser;
+            -- grammar C;
+            local g4_string = io.readfile(sourcefile_g4)
+            local lexer_name = g4_string:match("lexer grammar (%w+);")
+            local parser_name = g4_string:match("parser grammar (%w+);")
+            -- lexer and parser same name
+            local grammar_name = g4_string:match("grammar (%w+);")
+            if lexer_name or parser_name then
+                if lexer_name then
+                    _build(path.join(sourcefile_dir, lexer_name .. ".cpp"))
+                end
+                if parser_name then
+                    _build(path.join(sourcefile_dir, parser_name .. ".cpp"))
+                end
+            elseif grammar_name then
+                _build(path.join(sourcefile_dir, grammar_name .. "Lexer.cpp"))
+                _build(path.join(sourcefile_dir, grammar_name .. "Parser.cpp"))
+            end
+        end)
+    end

+ 0 - 53
packages/a/antlr4/rules/lexer.lua

@@ -1,53 +0,0 @@
-rule("lexer")
-    set_extensions(".g4")
-
-    add_deps("@find_antlr4")
-
-    on_config(function (target)
-        local includedirs = {}
-        local autogendir = path.join(target:autogendir(), "rules/antlr4/lexer")
-        for _, sourcebatch in pairs(target:sourcebatches()) do
-            if sourcebatch.rulename == "@antlr4/lexer" then
-                local sourcefiles = {}
-                for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
-                    -- remove parser g4
-                    if not sourcefile:lower():find("parser", 1, true) then
-                        table.insert(sourcefiles, sourcefile)
-                        table.insert(includedirs, path.normalize(path.join(autogendir, path.directory(sourcefile))))
-                    end
-                end
-                sourcebatch.sourcefiles = sourcefiles
-                break
-            end
-        end
-        target:add("includedirs", table.unique(includedirs), {public = true})
-    end)
-
-    before_buildcmd_file(function (target, batchcmds, sourcefile_g4, opt)
-        local java = target:data("antlr4.tool")
-        local argv = target:data("antlr4.tool.argv")
-        table.join2(argv, target:values("antlr4.lexer.flags"))
-
-        local autogendir = path.join(target:autogendir(), "rules/antlr4/lexer")
-        local sourcefile_cxx = path.normalize(path.join(autogendir, path.directory(sourcefile_g4), path.basename(sourcefile_g4) .. ".cpp"))
-        local sourcefile_dir = path.directory(sourcefile_cxx)
-
-        batchcmds:mkdir(sourcefile_dir)
-        table.insert(argv, "-o")
-        table.insert(argv, autogendir)
-        table.insert(argv, "-lib")
-        table.insert(argv, sourcefile_dir)
-
-        table.insert(argv, sourcefile_g4)
-        batchcmds:show_progress(opt.progress, "${color.build.object}compiling.g4 %s", sourcefile_g4)
-        batchcmds:vrunv(java.program, argv)
-
-        local objectfile = target:objectfile(sourcefile_cxx)
-        table.insert(target:objectfiles(), objectfile)
-        batchcmds:show_progress(opt.progress, "${color.build.object}compiling.$(mode) %s", sourcefile_cxx)
-        batchcmds:compile(sourcefile_cxx, objectfile)
-
-        batchcmds:add_depfiles(sourcefile_g4)
-        batchcmds:set_depmtime(os.mtime(objectfile))
-        batchcmds:set_depcache(target:dependfile(objectfile))
-    end)

+ 0 - 60
packages/a/antlr4/rules/parser.lua

@@ -1,60 +0,0 @@
-rule("parser")
-    set_extensions(".g4")
-
-    add_deps("@lexer", {order = true})
-
-    on_config(function (target)
-        local includedirs = {}
-        local autogendir = path.join(target:autogendir(), "rules/antlr4/parser")
-        for _, sourcebatch in pairs(target:sourcebatches()) do
-            if sourcebatch.rulename == "@antlr4/parser" then
-                local sourcefiles = {}
-                for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
-                    -- remove lexer g4
-                    if not sourcefile:lower():find("lexer", 1, true) then
-                        table.insert(sourcefiles, sourcefile)
-                        table.insert(includedirs, path.normalize(path.join(autogendir, path.directory(sourcefile))))
-                    end
-                end
-                sourcebatch.sourcefiles = sourcefiles
-                break
-            end
-        end
-        target:add("includedirs", table.unique(includedirs), {public = true})
-    end)
-
-    before_buildcmd_file(function (target, batchcmds, sourcefile_g4, opt)
-        local java = target:data("antlr4.tool")
-        local argv = target:data("antlr4.tool.argv")
-
-        local visitor = target:extraconf("rules", "@antlr4/parser", "visitor")
-        local listener = target:extraconf("rules", "@antlr4/parser", "listener")
-        
-        table.insert(argv, (visitor and "-visitor" or "-no-visitor"))
-        table.insert(argv, (listener and "-listener" or "-no-listener"))
-
-        table.join2(argv, target:values("antlr4.parser.flags"))
-
-        local autogendir = path.join(target:autogendir(), "rules/antlr4/parser")
-        local sourcefile_cxx = path.normalize(path.join(autogendir, path.directory(sourcefile_g4), path.basename(sourcefile_g4) .. ".cpp"))
-        local sourcefile_dir = path.directory(sourcefile_cxx)
-
-        batchcmds:mkdir(sourcefile_dir)
-        table.insert(argv, "-o")
-        table.insert(argv, autogendir)
-        table.insert(argv, "-lib")
-        table.insert(argv, sourcefile_dir)
-
-        table.insert(argv, sourcefile_g4)
-        batchcmds:show_progress(opt.progress, "${color.build.object}compiling.g4 %s", sourcefile_g4)
-        batchcmds:vrunv(java.program, argv)
-
-        local objectfile = target:objectfile(sourcefile_cxx)
-        table.insert(target:objectfiles(), objectfile)
-        batchcmds:show_progress(opt.progress, "${color.build.object}compiling.$(mode) %s", sourcefile_cxx)
-        batchcmds:compile(sourcefile_cxx, objectfile)
-
-        batchcmds:add_depfiles(sourcefile_g4)
-        batchcmds:set_depmtime(os.mtime(objectfile))
-        batchcmds:set_depcache(target:dependfile(objectfile))
-    end)