{"id":19515,"date":"2026-06-19T16:22:37","date_gmt":"2026-06-19T14:22:37","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=19515"},"modified":"2026-06-19T16:22:41","modified_gmt":"2026-06-19T14:22:41","slug":"syntax-diagrams-for-apexlang","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/","title":{"rendered":"Syntax Diagrams for APEXlang"},"content":{"rendered":"\n<h2 id=\"introduction\" class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/apex\/26.1\/apxln\/\" target=\"_blank\" rel=\"noreferrer noopener\">APEXlang API Reference documentation<\/a> went live a few days ago. You can also download the APEXlang EBNF grammar. In <a href=\"https:\/\/www.linkedin.com\/pulse\/apexlang-now-has-published-ebnf-grammar-heres-what-unlocks-kris-rice-5tsoc\/\" type=\"link\" id=\"https:\/\/www.linkedin.com\/pulse\/apexlang-now-has-published-ebnf-grammar-heres-what-unlocks-kris-rice-5tsoc\/\" target=\"_blank\" rel=\"noreferrer noopener\">this post<\/a>, Kris Rice explains the value of having an EBNF.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since the APEXlang grammar is available as EBNF, it can be used to generate <a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntax_diagram\" type=\"link\" id=\"https:\/\/en.wikipedia.org\/wiki\/Syntax_diagram\" target=\"_blank\" rel=\"noreferrer noopener\">syntax diagrams<\/a>. These diagrams (also known as railroad diagrams) make the language easier to explore and provide a visual complement to the API Reference.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this blog post, I explain how to produce the syntax diagrams for APEXlang. <\/p>\n\n\n\n<h2 id=\"what-is-ebnf\" class=\"wp-block-heading\">What Is EBNF<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wikipedia describes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Extended_Backus%E2%80%93Naur_form\" target=\"_blank\" rel=\"noreferrer noopener\">Extended Backus-Naur Form<\/a>. However, it&#8217;s important to notice that there are several variants of EBNF. <\/p>\n\n\n\n<h2 id=\"apexlang-ebnf\" class=\"wp-block-heading\">APEXlang EBNF<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The APEXlang EBNF grammar uses a variant of the BNF in the SQL:2023 standard, with some extensions\u00a0explained at the top of the <a href=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/apex\/26.1\/apxln\/apexlang.ebnf\" type=\"link\" id=\"https:\/\/docs.oracle.com\/en\/database\/oracle\/apex\/26.1\/apxln\/apexlang.ebnf\" target=\"_blank\" rel=\"noreferrer noopener\">apexlang.ebnf<\/a> file.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">1) Syntax conventions in apexlang.ebnf<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>(* Syntax conventions\n   &lt;nl> is significant: component declarations, groups, properties, and closing delimiters are line-oriented.\n   &#91; X &#93; means optional X. { X } means zero or more X. A | B means either A or B.\n*)<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">(* Syntax conventions<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">   &lt;nl&gt; is significant: component declarations, groups, properties, and closing delimiters are line-oriented.<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #6A9955\">   &#91; X &#93; means optional X. { X } means zero or more X. A | B means either A or B.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">*)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Square brackets <code>[]<\/code> indicate optionality, while curly brackets <code>{}<\/code> enclose a repeated group as defined in <a href=\"https:\/\/www.cl.cam.ac.uk\/~mgk25\/iso-14977.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">ISO\/IEC 14977<\/a>. However, the <code>apexlang.ebnf<\/code> file does not fully use this ISO EBNF standard. <code>apexlang.ebnf<\/code> uses <code>::=<\/code> while the ISO standard uses a simple <code>=<\/code> for symbol definitions. This variant resembles a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Wirth_syntax_notation\" target=\"_blank\" rel=\"noreferrer noopener\">Wirth EBNF<\/a> with comments.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the definition of the <code>app<\/code> rule in the <code>apexlang.ebnf<\/code> file.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-start:248;--cbp-line-number-width:calc(3 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">2) app rule in apexlang.ebnf<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>&lt;app> ::= \"app\" &#91; &lt;required-ws> &lt;component-id> &#93; &lt;ws> \"(\" &lt;line-end> { &lt;app-body-line> } &lt;indent> \")\" &lt;line-end><\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">app<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">::=<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;app&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&#91;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">required<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">ws<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">component<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">id<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&#93;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">ws<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;(&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">line<\/span><span style=\"color: #569CD6\">-end&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">app<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">body<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">line<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">indent<\/span><span style=\"color: #569CD6\">&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;)&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">&lt;<\/span><span style=\"color: #D4D4D4\">line<\/span><span style=\"color: #569CD6\">-end&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 id=\"syntax-diagram\" class=\"wp-block-heading\">Syntax Diagram<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the syntax diagram, or railroad diagram, for the app rule.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/app.svg\"><img wpfc-lazyload-disable=\"true\" decoding=\"async\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/app.svg\" alt=\"\" class=\"wp-image-19562\"\/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I produced this syntax diagram with the <a href=\"https:\/\/www.bottlecaps.de\/rr\/ui\" target=\"_blank\" rel=\"noreferrer noopener\">Railroad Diagram Generator (RR)<\/a> by Gunter Rademacher. However, this tool requires a <a href=\"https:\/\/www.w3.org\/TR\/xml\/#sec-notation\">W3<\/a><a href=\"https:\/\/www.w3.org\/TR\/xml\/#sec-notation\" target=\"_blank\" rel=\"noreferrer noopener\">C EBNF<\/a> as input. In other words, the original <code>apexlang.ebnf<\/code> produces runtime errors. <\/p>\n\n\n\n<h2 id=\"w3c-ebnf\" class=\"wp-block-heading\">W3C EBNF<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fortunately, it is straightforward to convert the APEXlang EBNF grammar to W3C EBNF. For the current APEXlang grammar, the conversion can be performed entirely through automated text transformations without manual edits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a list of the most important replacement actions:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Action<\/th><th class=\"has-text-align-left\" data-align=\"left\">Example From<\/th><th class=\"has-text-align-left\" data-align=\"left\">Example To<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Replace multiline comments<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>(* ... *)<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>\/* ... *\/<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Remove leading <code>&lt;<\/code> and trailing <code>><\/code> in symbol names<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>&lt;app><\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>app<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Use expression and <code>?<\/code> to express optionality<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>[ ... ]<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>( ... )?<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Use expression and <code>*<\/code> for repetitions<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>{ ... }<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>( ... )*<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The rule <code>app<\/code> in W3C EBNF looks as follows after applying these changes:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-start:248;--cbp-line-number-width:calc(3 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">3) app rule in apexlang.w3c.ebnf<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>app ::= \"app\" ( required-ws component-id )? ws \"(\" line-end ( app-body-line )* indent \")\" line-end<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">app <\/span><span style=\"color: #569CD6\">::=<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;app&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">(<\/span><span style=\"color: #D4D4D4\"> required<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">ws component<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">id <\/span><span style=\"color: #569CD6\">)<\/span><span style=\"color: #D4D4D4\">? ws <\/span><span style=\"color: #CE9178\">&quot;(&quot;<\/span><span style=\"color: #D4D4D4\"> line<\/span><span style=\"color: #569CD6\">-end<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">(<\/span><span style=\"color: #D4D4D4\"> app<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">body<\/span><span style=\"color: #569CD6\">-<\/span><span style=\"color: #D4D4D4\">line <\/span><span style=\"color: #569CD6\">)*<\/span><span style=\"color: #D4D4D4\"> indent <\/span><span style=\"color: #CE9178\">&quot;)&quot;<\/span><span style=\"color: #D4D4D4\"> line<\/span><span style=\"color: #569CD6\">-end<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">See <a href=\"https:\/\/github.com\/Grisselbav\/APEXlang\/blob\/main\/Convert.java\" type=\"link\" id=\"https:\/\/github.com\/Grisselbav\/APEXlang\/blob\/main\/Convert.java\" target=\"_blank\" rel=\"noreferrer noopener\">Convert.java<\/a> for the complete conversion program. <\/p>\n\n\n\n<h2 id=\"syntax-diagrams-on-github\" class=\"wp-block-heading\">Syntax Diagrams on GitHub<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You cannot produce the complete syntax diagrams in the online version of the Railroad Diagram Generator because the APEXlang grammar is huge, and you will get a timeout when trying.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, you need to run the tool locally. I&#8217;ve created a <a href=\"https:\/\/github.com\/Grisselbav\/APEXlang\/blob\/main\/.github\/workflows\/ci.yml\" type=\"link\" id=\"https:\/\/github.com\/Grisselbav\/APEXlang\/blob\/main\/.github\/workflows\/ci.yml\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub workflow<\/a> that downloads <code>apexlang.ebnf<\/code>, converts it to a W3C EBNF, and generates an HTML file containing all syntax diagrams. Finally, the workflow publishes the result:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/grisselbav.github.io\/APEXlang\/apexlang.w3c.ebnf.txt\" target=\"_blank\" rel=\"noreferrer noopener\">APEXlang grammar converted to W3C EBNF<\/a> <\/li>\n\n\n\n<li><a href=\"https:\/\/grisselbav.github.io\/APEXlang\/apexlang.html#app\" type=\"link\" id=\"https:\/\/grisselbav.github.io\/APEXlang\/apexlang.html#app\" target=\"_blank\" rel=\"noreferrer noopener\">APEXlang syntax diagrams produced by RR<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The advantage of syntax diagrams is that they show all usages of a symbol, allowing you to navigate quickly to the relevant definition.<\/p>\n\n\n\n<h2 id=\"outlook\" class=\"wp-block-heading\">Outlook<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The next step is to build a parser for APEXlang and use this as the basis for linting. This would enable APEXlang source code to be automatically validated, helping both developers and AI agents to produce code that conforms to defined quality standards.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Looking further ahead, we are considering providing full support for APEXlang within the <a href=\"https:\/\/www.united-codes.com\/products\/dblinter\/\" type=\"link\" id=\"https:\/\/www.united-codes.com\/products\/dblinter\/\" target=\"_blank\" rel=\"noreferrer noopener\">dbLinter tool suite<\/a>. Currently, dbLinter analyses only SQL and PL\/SQL code blocks embedded in APEXlang files. Full APEXlang support is a natural evolution. Stay tuned!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The APEXlang API Reference documentation went live a few days ago. You can also download the APEXlang EBNF grammar. In this post, Kris Rice explains the value of having an EBNF. Since the APEXlang grammar is available as EBNF, it can be used to generate syntax diagrams. These diagrams (also known<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":19594,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[154,151],"class_list":["post-19515","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-apexlang","tag-dblinter"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-19T14:22:37+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-19T14:22:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1731\" \/>\n\t<meta property=\"og:image:height\" content=\"909\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Syntax Diagrams for APEXlang\",\"datePublished\":\"2026-06-19T14:22:37+00:00\",\"dateModified\":\"2026-06-19T14:22:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/\"},\"wordCount\":540,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/apexlang.png\",\"keywords\":[\"APEXlang\",\"dbLinter\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/\",\"name\":\"Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/apexlang.png\",\"datePublished\":\"2026-06-19T14:22:37+00:00\",\"dateModified\":\"2026-06-19T14:22:41+00:00\",\"description\":\"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/apexlang.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/apexlang.png\",\"width\":1731,\"height\":909},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2026\\\/06\\\/19\\\/syntax-diagrams-for-apexlang\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Syntax Diagrams for APEXlang\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog","description":"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/","og_locale":"en_US","og_type":"article","og_title":"Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog","og_description":"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.","og_url":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2026-06-19T14:22:37+00:00","article_modified_time":"2026-06-19T14:22:41+00:00","og_image":[{"width":1731,"height":909,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Syntax Diagrams for APEXlang","datePublished":"2026-06-19T14:22:37+00:00","dateModified":"2026-06-19T14:22:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/"},"wordCount":540,"commentCount":2,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png","keywords":["APEXlang","dbLinter"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/","url":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/","name":"Syntax Diagrams for APEXlang - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png","datePublished":"2026-06-19T14:22:37+00:00","dateModified":"2026-06-19T14:22:41+00:00","description":"Learn how to generate syntax diagrams from APEXlang EBNF grammar by converting it to W3C EBNF and rendering railroad diagrams automatically.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2026\/06\/apexlang.png","width":1731,"height":909},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2026\/06\/19\/syntax-diagrams-for-apexlang\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Syntax Diagrams for APEXlang"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/19515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=19515"}],"version-history":[{"count":32,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/19515\/revisions"}],"predecessor-version":[{"id":19595,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/19515\/revisions\/19595"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/19594"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=19515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=19515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=19515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}