diff --git a/gen_seq_diag.py b/gen_seq_diag.py
index 9f9cc33df9b7fa9df7c4c104bb534abee02c7be2..992e7cb253c78b19df88b8426c54318a6db5558c 100755
--- a/gen_seq_diag.py
+++ b/gen_seq_diag.py
@@ -35,7 +35,7 @@ def walk_dir(p):
 def expr_to_str(e):
     if type(e) is tr.BinaryOperation:
         return (f'{expr_to_str(e.operandl)} ' +
-            f'{e.operator} {expr_to_str(e.operandr)}')
+                f'{e.operator} {expr_to_str(e.operandr)}')
     elif type(e) is tr.MemberReference:
         return f'{"".join(e.prefix_operators)}{e.member}'
     elif type(e) is tr.Cast:
@@ -49,9 +49,9 @@ def expr_to_str(e):
 
 def latex_escape(s):
     return (s.replace("_", "\\_")
-        .replace("&", "\\&")
-        .replace("{", "\\{")
-        .replace("}", "\\}"))
+            .replace("&", "\\&")
+            .replace("{", "\\{")
+            .replace("}", "\\}"))
 def assert_latex_safe(*args):
     for arg in args:
         for c in '_&{}':
@@ -172,7 +172,7 @@ class Call(Stmt):
                 met2 = types[t].get_method(call.member)
             else:
                 ctx.comment(lvl,
-                    f'cant find type {var.t} ({call.qual}.{call.member})')
+                            f'cant find type {var.t} ({call.qual}.{call.member})')
                 return
 
         # check for recursion
@@ -203,12 +203,12 @@ class Call(Stmt):
         assert_latex_safe(edge[0], edge[1])
         ctx.args.append(args)
         ctx.append(lvl, '\\begin{umlcall}' +
-                '[' +
-                    f'op={{{call.member}({args_str})}},' +
-                    f'return={{{ret}}},' +
-                    f'dt=7' +
-                ']' +
-                f'{{{edge[0]}}}{{{edge[1]}}}')
+                   '[' +
+                   f'op={{{call.member}({args_str})}},' +
+                   f'return={{{ret}}},' +
+                   f'dt=7' +
+                   ']' +
+                   f'{{{edge[0]}}}{{{edge[1]}}}')
         met2.gen_seq(var, lvl + 1, ctx)
         ctx.append(lvl, '\\end{umlcall}')
 
@@ -228,8 +228,8 @@ class CreateCall(Stmt):
         if self.ret is not None and self.ret.t in types:
             assert_latex_safe(obj.name, self.ret.name)
             ctx.append(lvl, '\\umlcreatecall' +
-                    f'[dt=7,class={{{self.ret.t}}}]' +
-                    f'{{{obj.name}}}{{{self.ret.name}}}')
+                       f'[dt=7,class={{{self.ret.t}}}]' +
+                       f'{{{obj.name}}}{{{self.ret.name}}}')
             o = (self.ret.t, self.ret.name)
             ctx.objs[o] = -1
 
@@ -275,7 +275,7 @@ class If(Control):
 
         pre = '' if ctx.has_any() else '% '
         ctx.append_fragment(lvl, f'{pre}\\begin{{umlfragment}}' +
-                f'[type=alt, label={{{latex_escape(cond)}}}, inner xsep=20]')
+                            f'[type=alt, label={{{latex_escape(cond)}}}, inner xsep=20]')
         ctx.pop_fragment()
         if pre != '':
             ctx.append(lvl, '% \\end{umlfragment}')
@@ -312,7 +312,7 @@ class For(Control):
             ctx.inc_comm_label()
         pre = '' if ctx.has_any() else '% '
         ctx.append_fragment(lvl, f'{pre}\\begin{{umlfragment}}' +
-                f'[type=loop, label={{{control}}}, inner xsep=20]')
+                            f'[type=loop, label={{{control}}}, inner xsep=20]')
         ctx.pop_fragment()
         ctx.append(lvl, f'{pre}\\end{{umlfragment}}')
 
@@ -443,7 +443,7 @@ def dump_tree(t):
                 t.vars[vd.name] = Var(decl.type.name, vd.name)
         for method in type_.body:
             if isinstance(method, tr.MethodDeclaration) or isinstance(method,
-                    tr.ConstructorDeclaration):
+                                                                      tr.ConstructorDeclaration):
                 met = Method(method.name)
                 met.t = t
                 met.doc = method.documentation
@@ -484,9 +484,9 @@ def main():
 
     ctx = Ctx(repl)
     (types[spec_type]
-        .methods[spec_method]
-        .gen_seq(Var(spec_type, spec_obj), 1, ctx)
-    )
+     .methods[spec_method]
+     .gen_seq(Var(spec_type, spec_obj), 1, ctx)
+     )
     ctx.objs[(spec_type, spec_obj)] = 0
     sorted_objs = sorted(ctx.objs.items(), key = lambda i: i[1])
 
@@ -504,7 +504,7 @@ def main():
         args_str = latex_escape(', '.join(
             [p[1] for p in types[spec_type].methods[spec_method].params]))
         print(f'\\begin{{umlcall}}[op={{{spec_method}({args_str})}},' +
-            f'return={{\\ }}]{{act}}{{{spec_obj}}}')
+              f'return={{\\ }}]{{act}}{{{spec_obj}}}')
         print(''.join(ctx.s))
         print('\\end{umlcall}')
         print('\\end{umlseqdiag}\n\\end{tikzpicture}')
diff --git a/plab/.gitignore b/plab/.gitignore
index f3a9241361fa1564131f7f2476f341f4f453a603..426e0248963a52379b341d9dcece876ff4b21ef2 100644
--- a/plab/.gitignore
+++ b/plab/.gitignore
@@ -1,4 +1,6 @@
 plab
 test.yml
 tmp
-out
\ No newline at end of file
+out
+Java9.g4
+parser
\ No newline at end of file
diff --git a/plab/classdiag.go b/plab/classdiag.go
index b3c7b7f64e6f75675c3ff3d2c9ea38e0961bb3d0..87071e014e72e3b1065f79949eedcf880ddac3c8 100644
--- a/plab/classdiag.go
+++ b/plab/classdiag.go
@@ -3,13 +3,14 @@ package main
 import (
 	"bytes"
 	"fmt"
+	"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
 	"io/ioutil"
 	"os"
 	"regexp"
 	"strings"
 )
 
-var Classdiag = Subcommand{
+var Classdiag = helpers.Subcommand{
 	Name: "classdiag",
 	Command: func(args []string) {
 		if len(args) > 1 {
@@ -78,7 +79,7 @@ func genPlantUMLStr(classes map[string]*Class) {
 					for _, e := range a.Elements {
 						switch e.QualifiedName {
 						case "projlab.Docs.uml":
-							e.Value = unescape(e.Value)
+							e.Value = helpers.Unescape(e.Value)
 							uml = true
 							t := f.Type.Name
 							if strings.Contains(t, "..") {
@@ -116,7 +117,7 @@ func genPlantUMLStr(classes map[string]*Class) {
 		for _, a := range c.Annotations {
 			if a.TypeName == "Docs" {
 				for _, e := range a.Elements {
-					e.Value = unescape(e.Value)
+					e.Value = helpers.Unescape(e.Value)
 					switch e.QualifiedName {
 					case "projlab.Docs.uml":
 						output.WriteString(fmt.Sprintln(e.Value))
diff --git a/plab/go.mod b/plab/go.mod
index 69e002efabd731791013b2089e48e0b1b91c899f..5df514318a6f8e386f9944209868e0d02c399995 100644
--- a/plab/go.mod
+++ b/plab/go.mod
@@ -4,4 +4,6 @@ replace git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab => ./
 
 go 1.15
 
-require gopkg.in/yaml.v2 v2.4.0
+require (
+	gopkg.in/yaml.v2 v2.4.0
+)
diff --git a/plab/go.sum b/plab/go.sum
index 75346616b19bda7882ecbba954fe5bc1e5577468..18e2290d6e3a1f9672383001af4547bb033b737a 100644
--- a/plab/go.sum
+++ b/plab/go.sum
@@ -1,3 +1,5 @@
+github.com/antlr/antlr4 v0.0.0-20210302031819-dc460a0514b7 h1:KjMzhtSUAUy2cdWc6jwBp9rHQRUdcgTBBTjyMmtJufY=
+github.com/antlr/antlr4 v0.0.0-20210302031819-dc460a0514b7/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
diff --git a/plab/subcmd.go b/plab/helpers/subcmd.go
similarity index 96%
rename from plab/subcmd.go
rename to plab/helpers/subcmd.go
index 54a009166f20dbf6fdbebf73e5cbce01365bde56..d463c436505b8a9757cc7ef05c71ecc641907415 100644
--- a/plab/subcmd.go
+++ b/plab/helpers/subcmd.go
@@ -1,4 +1,4 @@
-package main
+package helpers
 
 import "fmt"
 
diff --git a/plab/unescape.go b/plab/helpers/unescape.go
similarity index 65%
rename from plab/unescape.go
rename to plab/helpers/unescape.go
index 616e103b569df643ebcdc033602dd9177616865b..0e8fc623780464c54fcd1596f322515d240c0e8c 100644
--- a/plab/unescape.go
+++ b/plab/helpers/unescape.go
@@ -1,8 +1,8 @@
-package main
+package helpers
 
 import "encoding/json"
 
-func unescape(s string) string {
+func Unescape(s string) string {
 	var ret string
 	_ = json.Unmarshal([]byte(s), &ret)
 	return ret
diff --git a/plab/javadoc.go b/plab/javadoc.go
index 8ffc7478fbb5fff05af5fe70dc84345014660dde..d1e9a596ee122426d5bc59487b8337aae53cbe0e 100644
--- a/plab/javadoc.go
+++ b/plab/javadoc.go
@@ -3,6 +3,7 @@ package main
 import (
 	"encoding/json"
 	"fmt"
+	"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -93,7 +94,7 @@ func (c *Class) getMethod(name string) *Method {
 	return nil
 }
 
-var Javadoc = Subcommand{
+var Javadoc = helpers.Subcommand{
 	Name: "javadoc",
 	Command: func(args []string) {
 		if len(args) > 1 {
@@ -204,7 +205,7 @@ func readJson(fname string) (*Class, error) {
 					for _, e := range a.Elements {
 						switch e.QualifiedName {
 						case "projlab.Docs.type":
-							e.Value = unescape(e.Value)
+							e.Value = helpers.Unescape(e.Value)
 							if e.Value != "" {
 								replace(arr[i], e.Value)
 							}
diff --git a/plab/main.go b/plab/main.go
index 23ef0b8b480a604b14d182336f51590cb8f3440d..64c583e9cf24c5a6a72b3db3c905a7f47cefeb1c 100644
--- a/plab/main.go
+++ b/plab/main.go
@@ -1,9 +1,12 @@
 package main
 
-import "os"
+import (
+	"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
+	"os"
+)
 
 func main() {
-	mainCmds := CmdFrom(os.Args[0], "go projlab tool", Timetable, Javadoc, Classdiag)
+	mainCmds := helpers.CmdFrom(os.Args[0], "go projlab tool", Timetable, Javadoc, Classdiag)
 	if len(os.Args) < 2 {
 		os.Args = append(os.Args, "help")
 	}
diff --git a/plab/timetable.go b/plab/timetable.go
index 7efaf89771426530224b1abc594f0c913996ced7..1cd75884fff833e5312db6ec197c37d7d022eb50 100644
--- a/plab/timetable.go
+++ b/plab/timetable.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"fmt"
+	"git.sch.bme.hu/insert-epic-projlab-team-name-here/tooling/plab/helpers"
 	"gopkg.in/yaml.v2"
 	"io/ioutil"
 	"os"
@@ -66,7 +67,7 @@ func lastWeek(table *timetable) string {
 	return strconv.Itoa(i)
 }
 
-var Timetable = Subcommand{
+var Timetable = helpers.Subcommand{
 	Name: "timetable",
 	Command: func(args []string) {
 		if len(args) < 1 {