{"id":16389720,"url":"https://github.com/yuce/jacl","last_synced_at":"2026-01-28T15:32:01.676Z","repository":{"id":146806431,"uuid":"193239780","full_name":"yuce/jacl","owner":"yuce","description":"Specification for just another configuration language.","archived":false,"fork":false,"pushed_at":"2020-11-19T10:13:46.000Z","size":23,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-03T20:08:36.004Z","etag":null,"topics":["configuration","jacl","language"],"latest_commit_sha":null,"homepage":"","language":"ANTLR","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-22T13:56:19.000Z","updated_at":"2025-04-13T03:34:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"c4de4af3-2e8f-4061-83a5-37ef4203dbd8","html_url":"https://github.com/yuce/jacl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yuce/jacl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fjacl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fjacl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fjacl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fjacl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuce","download_url":"https://codeload.github.com/yuce/jacl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuce%2Fjacl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T15:15:36.453Z","status":"ssl_error","status_checked_at":"2026-01-28T15:15:13.020Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","jacl","language"],"created_at":"2024-10-11T04:34:08.458Z","updated_at":"2026-01-28T15:32:01.659Z","avatar_url":"https://github.com/yuce.png","language":"ANTLR","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jacl Specification 0.1\n\nJacl is a straightforward configuration language with the following features:\n\n* Indentation does NOT matter.\n* All values in the configuration have a non-ambiguous type.\n* Separators between values are optional.\n* Familiar syntax.\n* NO magic, NO cheap tricks.\n\nGoals:\n\n* The specification should be trivial to understand and easy to implement.\n* A configuration file should be easy to edit and easy to understand.\n* Trivial mistakes shouldn't change the *meaning* of the configuration file drastically.\n\nNon-goals:\n\n* Anything not necessary in a configuration file.\n\n\n## Change Log\n\n### v0.1.3 (2019-06-30)\n\n* Added experimental specification.\n* Repeated keys are not allowed.\n\n### v0.1.2 (2019-06-26)\n\n* Single line comments start with `//` instead of `#`.\n* Numbers may optionally include underscores to increase their readability, e.g., `12_345_678_900 == 12345678900`.\n\n### v0.1.1 (2019-06-23)\n\n* Added extended specification.\n\n### v0.1.0 (2019-06-22)\n\n* Initial release.\n\n## Sample\n\n```\n// This is a Jacl file. Boom.\n\nowner: {\n    name: \"Phillips Redd\"\n    age: 34\n    bio: \"\"\"\n        Coder.\n        Loves cats.\n        \"\"\"\n}\n\ndatabase: {\n    server: \"192.168.1.1\"\n    ports: [8001 8002 8003]\n    connection_max: 5_000\n    enabled: true\n}\n\n// Some code in the config. Indentation matters only when it should:\nsource: trim\"\"\"\n    def main():\n        if True:\n            print(\"OK, fine\")\n        else:\n            print(\"Not fine\")\n    \"\"\"\n\n    /*\n        You can indent as you please, even if it doesn't make sense.\n        Tabs or spaces. Jacl doesn't care.\n        Oh, and this is a multiline comment!\n    */\n    servers: {\n        alpha: {\n            ip: \"10.0.0.1\"\n            dc: \"eqdc10\"\n        }\n        beta: {\n            ip: \"10.0.0.2\"\n            dc: \"eqdc10\"\n        }\n    }\n\nclients: {\n    data: [\n        [\"gamma\", \"delta\"]\n        [1 2]\n    ]\n}\n```\n\n## Libraries\n\nBelow are the libraries that implement Jacl:\n\nLibrary | Language | Basic Spec|Extended Spec|Experimental Spec| Home\n--------|----------|-----------|-------------|-----------------|-----\ngo-jacl | Go       | Yes       |Yes          | -               | https://github.com/yuce/go-jacl\n---------------------------------------------------------------------\n\n\n## Table Of Contents\n\n1. [Base Specification](#base-specification)\n    1. [Grammar](#grammar)\n    2. [Definitions](#definitions)\n    3. [Empty File](#empty-file)\n    4. [Comments](#comments)\n    5. [Properties](#properties)\n        1. [Property name](#property-name)\n        2. [Property value](#property-value)\n    6. [Data Types](#data-types)\n        1. [String](#string)\n        2. [Unsigned integer](#unsigned-integer)\n        2. [Signed integer](#signed-integer)\n        3. [Float](#float)\n        4. [Boolean](#boolean)\n        5. [Array](#array)\n        6. [Map](#map)\n2. [Extended Specification](#extended-specification)\n    1. [Raw String Functions](#raw-string-functions)\n        1. [trim](#trim)\n        2. [pin](#pin)\n3. [Experimental Specification](#experimental-specification)\n    1. [Additional Data Types](#additional-data-types)\n        1. [complex](#complex)\n        2. [date](#date)\n        3. [datetime](#datetime)\n        4. [null](#null)\n        5. [time](#time)\n\n## Base Specification\n\n### Grammar\n\nThe Jacl grammar is written using [ANTLR4](https://www.antlr.org/index.html). You can find the grammar [here](Jacl.g4).\n\n### Definitions\n\nHost language: The programming language that implements this specification.\n\n### Empty File\n\nAn empty file is a valid Jacl file.\n\n### Comments\n\nSingle line comments start with `//`:\n\n    // This is a single line comment.\n\nMultiline comments start with `/*` and end with `*/`:\n\n    /*\n        This is a multiline\n        comment\n    */\n\n### Properties\n\nProperties are defined at the top level of a file, and they have the following structure:\n\n    [name]: [value]\n\n#### Property name\n\nProperty name is a string which contains alphanumneric characters, `-` or `_`:\n\n    key: \"fun\"\n    another-key: \"other-fun\"\n    yet_another_fun: \"yet another fun\"\n\nOptionally with quotes (`\"`) around it:\n\n    \"new prefix\": \"more-fun-\"\n\nEscape characters are not evaluated:\n\n    \"newest\\nprefix\": \"most-fun-\"\n\nThe name above is evaluated to `newest\\nprefix`, NOT:\n\n    newest\n    prefix\n\nRepeated property names are not allowed. The following is invalid:\n\n    key: \"foo\"\n    key: \"bar\"\n\nThe maximum length of a property name is 1024 characters.\n\n#### Property value\n\nProperty value can be one of the following types:\n\n* [String](#string)\n* [Unsigned integer](#unsigned-integer)\n* [Signed integer](#signed-integer)\n* [Float](#float)\n* [Boolean](#boolean)\n* [Array](#array)\n* [Map](#map)\n\n### Data Types\n\n#### String\n\nA string is always quoted with `\"`, `'''` or `\"\"\"`. Escapes in the former one are expanded, but not in the latter ones. Latter ones can span multiple lines.\n\nA simple string:\n\n    \"A simple string\"\n\nSimple string with escape:\n\n    \"Simple\\tstring\\nwith escape\"\n\nA raw string:\n\n    '''a raw string''''\n\nA multiline raw string:\n\n    '''\n    Multiline\n    string\n    '''\n\nAnother multiline raw string:\n\n    \"\"\"Another\n    multiline\n    string\"\"\"\n\n#### Unsigned integer\n\nUnsigned integers always have the biggest size the host language supports natively (usually 64 bits these days).\n\nIf a number has one of the following prefixes below, then it is an unsigned integer:\n\n* `0b`: binary, e.g., `0b10101`.\n* `0o`: octal, e.g., `0o744`.\n* `0d`: decimal, eg., `0d987123`.\n* `0x`. hexadecimal, e.g., `0xBEEF`.\n\nUnderscore (`_`) is allowed between digits:\n\n* `0b1_0_1_0_1 == 0b10101`\n* `0d13_490_567 == 0d13490567`\n* `0o12_567 == 0o12567`\n* `0xAB_CD_EF12 == 0xABCDEF12`\n\n#### Signed integer\n\nSigned integers always have the biggest size the host language supports natively (usually 64 bits these days).\n\nSigned integers cannot have `0` as a prefix, unless the number itself is `0`. So, this is invalid: `0145`.\n\nSigned integers may have the sign: `-` or `+`.\n\n```\n    -123\n    123\n    +123\n```\n\nUnderscore (`_`) is allowed between digits: `12_345_678 == 12345678`.\n\n#### Float\n\nFloats always have the biggest size the host language supports natively (usually 64 bits these days).\n\nA float should always have a decimal point; that's how floats are distinguished from integers.\n\nUnderscore (`_`) is allowed between digits: `12_345_678.910_405 == 12345678.910405`.\n\n`NaN` and `Infinity` are not supported in the base specification.\n\n#### Boolean\n\nOne of `true` or `false`.\n\n#### Array\n\nAn array may contain items of arbitrary types. Items in the array are written between brackets `[ ... ]`. Commas between items are optional.\n\nEmpty array is `[]`.\n\nThis array:\n\n    [\"green\" true [1 2 3] {name: \"John\" age: 30}]\n\nis equivalent to:\n\n    [\"green\", true, [1, 2, 3] {name: \"John\", age: 30}]\n\nwhich in turn is equivalent to:\n\n    [\n        \"green\"\n        true\n        [1, 2, 3]\n        {name: \"John\", age: 30}\n    ]\n\n#### Map\n\nA map contains keys and their mapping values. The keys can only be strings and they have the same restrictions as a property name. Keys and values of a map are written between curly braces: `{ ... }`. A key and a value is separated by colons `:`. Commas are optional.\n\nEmpty map is `{}`.\n\nThis map:\n\n    {name: \"John\" age: 30 groups: [\"sales\" \"management\"]}\n\nis equivalent to:\n\n    {name: \"John\", age: 30, groups: [\"sales\", \"management\"]}\n\nwhich in turn is equivalent to:\n\n    {\n        name: \"John\"\n        age: 30\n        groups: [\"sales\", \"management\"]\n    }\n\nOf course, a map can be many levels deep:\n\n    {\n        title: \"An important document\"\n        attributes: {\n            permissions: {\n                read: true\n                write: false\n            }\n        }\n    }\n\nRepeated keys are not allowed. The following is invalid:\n\n    {\n        key: \"foo\"\n        key: \"bar\"\n    }\n\n## Extended Specification\n\n### Raw String Functions\n\n#### trim\n\nSets the column of the first non-space character of ther first non-empty line as the pin point. Removes empty lines at the beginning and at the end. Removes space characters from each line so the pin point is the first column.\n\nExample:\n\n```\nsome_text: trim\"\"\"\n\n    This is line 1.\n        This is line 2.\n\n    This is line 3.\n    \"\"\"\n```\n\nIn the example above, pin point is the 5th column. 4 spaces are removed from each line. So `some_text` property is set to:\n\n```\nThis is line 1.\n    This is line 2.\n\nThis is line 3.\n```\n\nIt is an error to have a line with less spaces than the pin point. Parsing the following text returns an error. The pin point is set to 5th column, but that causes loss of characters in the 2nd line:\n\n```\ninvalid_text: trim\"\"\"\n\n    This is line 1.\nThis is line2.\n\"\"\"\n```\n\nSee the [pin](#pin) function to set the pin point manually.\n\n`trim` is especially useful for indentation-sensitive text, like Python code:\n\n    source: trim\"\"\"\n        import sys\n\n        def main():\n            args = sys.argv[1:]\n            if args:\n                print(f\"{len(args)} arguments passed.\")\n                for i, arg in enumerate(args):\n                    print(f\"  {i}. {arg}\")\n            else:\n                print(\"No arguments passed.\")\n\n        if __name__ == \"__main__\":\n            main()\n        \"\"\"\n\n\n#### pin\n\nThis function allows to set the pin point manually using the caret (`^`). The pin line and the empty lines before it are removed, but not the empty lines after it.\n\nExample:\n\n```\nsome_text: pin\"\"\"\n\n    ^\n    This is line 1.\n        This is line 2.\n\n    This is line 3.\n\n    \"\"\"\n```\n\nIn the example above, pin point is the 5th column. 4 spaces are removed from each line. So `some_text` property is set to:\n\n```\nThis is line 1.\n    This is line 2.\n\nThis is line 3.\n\n```\n\nNote that the blank line at the end of the text was not removed.\n\nThe same text using a different pin point:\n\n```\nsome_text: pin\"\"\"\n\n  ^\n    This is line 1.\n        This is line 2.\n\n    This is line 3.\n\n    \"\"\"\n```\n\nThis time, pin point is the 3rd column. 2 spaces are removed from each line. So `some_text` property is set to:\n\n```\n  This is line 1.\n      This is line 2.\n\n  This is line 3.\n\n```\n\nJust like `trim`, it is an error if the pin point choice results in loss of non-space characters. The following returns an error:\n\n```\ninvalid_text: pin\"\"\"\n  ^\n    This is line 1.\nThis is line2.\n\"\"\"\n```\n\nMoving the pin point to the 1st column makes that configuration valid:\n\n```\nvalid_text: pin\"\"\"\n^\n    This is line 1.\nThis is line2.\n\"\"\"\n```\n\nThe pin must be the first non-space character in the text, otherwise an error is returned:\n\n```\ninvalid_text: pin\"\"\"\n    Here, some text.\n    ^\n    Rest of the text.\n    \"\"\"\n```\n\nIt is an error to not have the pin:\n\n```\ninvalid_text: pin\"\"\"\n    Here, some text.\n    Rest of the text.\n    \"\"\"\n```\n\n`pin` preserves the space on empty lines in contrast with `trim` which removes them.\n\n## Experimental Specification\n\n### Additional Data Types\n\nJacl's base specification is minimal but supports many of the data types required by a configuration system. Nevertheless, there are other data types which can be useful in some situations, such as a date, complex number, etc.\n\nJacl supports additional data types via a syntax similar to a function call:\n\n    [name]( [parameter 1], [parameter 2] ... )\n\n#### complex\n\nA complex number: `complex(REAL, IMAGINERY)`\n\n    // corresponds to: 3+4i\n    a1: complex(3, 4)\n\n#### date\n\nA date given in the `[year]-[month]-[day]` format:\n\n    birthdate: date(\"2019-06-13\")\n\n#### datetime\n\nA timestamp containg both the date and time in the `[year]-[month]-[day]T[24-hour]:[minute]:[second]Z[timezone]` format. `[timezone]` is optional:\n\n    with-timezone: datetime(\"2019-06-13T22:47:31Z03:00\")\n    without-timezone: datetime(\"2019-06-13T22:47:31Z\")\n\n#### null\n\nJust the null value:\n\n    owner: null()\n\n#### time\n\nA time given in the `[24-hour]:[minute]:[second]` format:\n\n    next_time: time(\"13:34:45\")\n\n\n## Thanks\n\n* Alan Bernstein for the name of the language.\n* Matt Jaffee for early feedback.\n\n## License\n\nCopyright (c) 2019 Yuce Tekol. Licensed under [MIT](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Fjacl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuce%2Fjacl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuce%2Fjacl/lists"}