-
Notifications
You must be signed in to change notification settings - Fork 0
Template Generator
Benedict Albrecht edited this page May 20, 2026
·
7 revisions
The Crodox Template Generator is a Python script that produces starter Crodox grammar definitions for supported programming languages.
python crodox_template_generator.py <language>
python crodox_template_generator.py <language> --output <file># Print Python definition to stdout
python crodox_template_generator.py python
# Write to a file
python crodox_template_generator.py python --output python.crodox| Language | Command |
|---|---|
| Python | python crodox_template_generator.py python |
To add a new language, edit crodox_template_generator.py:
-
Create a new generator function:
def generate_mylang() -> str: lines = [ '<~"FROM".ext~>', ' # ... your objects here ...', '<~>', ] return '\n'.join(lines) + '\n'
-
Register it in the
LANGUAGESdictionary:LANGUAGES: dict[str, Callable[[], str]] = { "python": generate_python, "mylang": generate_mylang, }
-
Run it:
python crodox_template_generator.py mylang
Save the following as crodox_template_generator.py:
Click to expand the full script
"""
Crodox Template Generator
Generates starter Crodox grammar definition files for supported programming languages.
Usage:
python crodox_template_generator.py <language> [--output <file>]
Example:
python crodox_template_generator.py python
python crodox_template_generator.py python --output python.crodox
"""
import argparse
from typing import Callable
def generate_python() -> str:
tq = '"""'
sq = "'''"
lines = [
'<~"FROM".py~>',
'',
' <*comment_line*> # -->> \\n <*>',
f' <*comment_block*> <| {tq} -->> {tq} <||> {sq} -->> {sq} |> <*>',
'',
' <*()*> ( <---> ) <*>',
' <*[]*> [ <---> ] <*>',
' <*{}*> { <---> } <*>',
'',
' <:import:>',
' import <<name:up>> <| as <<name:up>> <||> |> \\n',
' <:>',
'',
' <:from_import:>',
' from <<"FROM">> import <| <<name:up>> <||> ( <? <<name:up>> <| , <||> |> ?> ) |> \\n',
' <:>',
'',
' <:decorator:>',
" @ <<'name'>> <| ( <? <| <<'name'>> <||> ' <<'name'>> ' <||> \" <<'name'>> \" <||> <<name>> |> <| , <||> |> ?> ) <||> |> \\n",
' <:>',
'',
' <:variable:>',
" <<name>> <| : <<'name'>> <||> |> = -->> \\n",
' <:>',
'',
' <:parameter:>',
" <<name>> <| : <<'name'>> <||> |> <| = -->> <| , <||> ) |> <||> <| , <||> ) |> |>",
' <:>',
'',
' <:function:>',
" <| async <||> |> def <<name:up>> ( <? <-{parameter}-> ?> ) <| -> <<'name'>> <||> |> : <--->",
' <:>',
'',
' <:class:>',
" class <<name:up>> <| ( <? <<'name'>> <| , <||> |> ?> ) <||> |> : <-function->",
' <:>',
'',
' <:return:>',
' return -->> \\n',
' <:>',
'',
' <:raise:>',
" raise <<'name'>> ( -->> ) \\n",
' <:>',
'',
' <:if:> if -->> : <--->',
' <:>',
'',
' <:elif:> elif -->> : <--->',
' <:>',
'',
' <:else:> else : <--->',
' <:>',
'',
' <:for:> for <<name>> in -->> : <--->',
' <:>',
'',
' <:while:> while -->> : <--->',
' <:>',
'',
' <:try:> try : <--->',
' <:>',
'',
' <:except:>',
" except <| <<'name'>> <| as <<name>> <||> |> <||> |> : <--->",
' <:>',
'',
' <:finally:> finally : <--->',
' <:>',
'',
' <:with:> with -->> as <<name>> : <--->',
' <:>',
'',
' <:assert:> assert -->> \\n',
' <:>',
'',
' <:pass:> pass \\n',
' <:>',
'',
'<~>',
]
return '\\n'.join(lines) + '\\n'
def generate_tsql() -> str:
lines = [
'<~"FROM".sql~>',
'',
' <*comment_line*> -- -->> \\n <*>',
' <*comment_block*> /* -->> */ <*>',
'',
' <*()*> ( <---> ) <*>',
'',
' <:use:>',
' USE <<name>> \\n',
' <:>',
'',
' <:go:>',
' GO \\n',
' <:>',
'',
' <:declare:>',
" DECLARE <<name>> <<'name'>> <| = -->> <| , <||> \\n |> <||> <| , <||> \\n |> |>",
' <:>',
'',
' <:set:>',
" SET <<'name'>> = -->> <| ; <||> \\n |>",
' <:>',
'',
' <:exec:>',
" <| EXEC <||> EXECUTE |> <<'name'>> <? <<name>> <| , <||> |> ?> <| ; <||> \\n |>",
' <:>',
'',
' <:join:>',
" <| INNER <||> LEFT <||> RIGHT <||> FULL <||> CROSS <||> |> JOIN <| <<'name'>> <||> <<name>> |> <| <| AS <||> |> <<name>> <||> |> ON -->> \\n",
' <:>',
'',
' <:select:>',
" SELECT <| TOP <<name>> <||> |> <? <| <<'name'>> <||> <<name>> |> <| <| AS <||> |> <<name>> <||> |> <| , <||> |> ?>",
" <| FROM <? <| <<'name'>> <||> <<name>> |> <| <| AS <||> |> <<name>> <||> |> <| , <||> |> ?> <||> |>",
' <? <-{join}-> ?>',
' <| WHERE -->> \\n <||> |>',
" <| GROUP BY <? <<'name'>> <| , <||> |> ?> <||> |>",
' <| HAVING -->> \\n <||> |>',
" <| ORDER BY <? <<'name'>> <| ASC <||> DESC <||> |> <| , <||> |> ?> <||> |>",
' <| ; <||> \\n |>',
' <:>',
'',
' <:insert:>',
" INSERT INTO <<'name'>> <| ( <? <<'name'>> <| , <||> |> ?> ) <||> |>",
' <| VALUES ( -->> ) <||> |>',
' <| ; <||> \\n |>',
' <:>',
'',
' <:update:>',
" UPDATE <<'name'>>",
" SET <? <<'name'>> = -->> <| , <||> |> ?>",
' <| WHERE -->> \\n <||> |>',
' <| ; <||> \\n |>',
' <:>',
'',
' <:delete:>',
" DELETE FROM <<'name'>>",
' <| WHERE -->> \\n <||> |>',
' <| ; <||> \\n |>',
' <:>',
'',
' <:if:>',
' IF -->> BEGIN <---> END <| ELSE BEGIN <---> END <||> |>',
' <:>',
'',
' <:while:>',
' WHILE -->> BEGIN <---> END',
' <:>',
'',
' <:begin_try:>',
' BEGIN TRY <---> END TRY',
' BEGIN CATCH <---> END CATCH',
' <:>',
'',
' <:return:>',
' RETURN <| -->> <| ; <||> \\n |> <||> <| ; <||> \\n |> |>',
' <:>',
'',
' <:print:>',
' PRINT -->> <| ; <||> \\n |>',
' <:>',
'',
' <:column_def:>',
" <<name>> <<'name'>> <| ( <<name>> ) <||> |>",
' <| NOT NULL <||> NULL <||> |>',
' <| DEFAULT -->> \\n <||> |>',
' <| PRIMARY KEY <||> |>',
' <| IDENTITY ( <<name>> , <<name>> ) <||> |>',
" <| REFERENCES <<'name'>> ( <<'name'>> ) <||> |>",
' <| , <||> |>',
' <:>',
'',
' <:create_table:>',
' CREATE TABLE <<name:up>> ( <? <-{column_def}-> ?> ) <| ; <||> \\n |>',
' <:>',
'',
' <:alter_table:>',
" ALTER TABLE <<'name'>>",
' <| ADD -->> <| ; <||> \\n |>',
" <||> DROP COLUMN <<'name'>> <| ; <||> \\n |>",
' <||> ALTER COLUMN -->> <| ; <||> \\n |>',
' |>',
' <:>',
'',
' <:drop_table:>',
" DROP TABLE <| IF EXISTS <||> |> <<'name'>> <| ; <||> \\n |>",
' <:>',
'',
' <:param:>',
" <<name>> <<'name'>> <| = -->> <| , <||> \\n |> <||> |> <| OUTPUT <||> |> <| , <||> |>",
' <:>',
'',
' <:create_proc:>',
' CREATE <| OR ALTER <||> |> PROCEDURE <<name:up>>',
' <? <-{param}-> ?>',
' AS BEGIN <---> END <| ; <||> \\n |>',
' <:>',
'',
' <:create_function:>',
' CREATE <| OR ALTER <||> |> FUNCTION <<name:up>> (',
' <? <-{param}-> ?>',
" ) RETURNS <<'name'>> <| ( <<name>> ) <||> |>",
' AS BEGIN <---> END <| ; <||> \\n |>',
' <:>',
'',
' <:create_view:>',
' CREATE <| OR ALTER <||> |> VIEW <<name:up>>',
' AS <| ; <||> \\n |>',
' <:>',
'',
' <:create_index:>',
' CREATE <| UNIQUE <||> |> <| CLUSTERED <||> NONCLUSTERED <||> |> INDEX <<name:up>>',
" ON <<'name'>> ( <? <<'name'>> <| ASC <||> DESC <||> |> <| , <||> |> ?> )",
' <| ; <||> \\n |>',
' <:>',
'',
' <:create_trigger:>',
' CREATE <| OR ALTER <||> |> TRIGGER <<name:up>>',
" ON <<'name'>>",
' <| AFTER <||> INSTEAD OF |> <? <| INSERT <||> UPDATE <||> DELETE |> <| , <||> |> ?>',
' AS BEGIN <---> END <| ; <||> \\n |>',
' <:>',
'',
'<~>',
]
return '\\n'.join(lines) + '\\n'
LANGUAGES: dict[str, Callable[[], str]] = {
"python": generate_python,
"tsql": generate_tsql,
}
def main() -> None:
parser = argparse.ArgumentParser(
description="Generate a starter Crodox grammar definition for a programming language.",
)
parser.add_argument(
"language",
choices=sorted(LANGUAGES.keys()),
help="Target language for the Crodox definition",
)
parser.add_argument(
"--output", "-o",
help="Output file path (default: stdout)",
)
args = parser.parse_args()
template = LANGUAGES[args.language]()
if args.output:
with open(args.output, "w", encoding="utf-8") as f:
f.write(template)
print(f"Wrote Crodox definition to {args.output}")
else:
print(template)
if __name__ == "__main__":
main()Alternatively, clone the wiki repo to get the script directly:
git clone https://crodox-software-gmbh.ghe.com/crodox/Wiki.wiki.git- Getting Started
- Sign-Up
- Home Screen
- Creating Your First Template
- Template Editor
- Application Navigation
- Syntax Overview
- Workflow: End-to-End
- Workflow: Test with simpleDemo
- Workflow: Build Template from angularTemp
- Demo Repositories
- Template
- Workbench
- GitHub Integration
- GitHub App Installation
- GitHub Repository Setup
- GitHub Re-linking
- Settings
- Overview
- Declarations
- Types
- Scoping