{"id":24302,"date":"2026-09-16T11:46:58","date_gmt":"2026-09-16T11:46:58","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/"},"modified":"2026-09-16T11:46:58","modified_gmt":"2026-09-16T11:46:58","slug":"wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/","title":{"rendered":"Wie wir einen von Lucene inspirierten Parser in Go entwickelt haben"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Bei Mailgun haben wir zahlreiche Systeme, die zu jeder Tagesstunde eine Unmenge an Ereignissen generieren. Diese Zahl ist so gro\u00df, dass es f\u00fcr ein Team unm\u00f6glich ist, ElasticSearch-Ergebnisse manuell zu durchsuchen und konsistente Resultate zu erwarten \u2013 oder dabei nicht den Verstand zu verlieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wie viele Unternehmen <b>m\u00fcssen auch wir einen Weg finden, mit all diesen Daten umzugehen<\/b>. Das f\u00fchrt zu einer komplexen Aufgabe: ein System zu entwickeln, mit dem unsere internen Kunden in Echtzeit auf Ereignisse reagieren k\u00f6nnen.<\/p>\n\n\n\r\n    <nav data-content-type=\"longform\" class=\"toc-block longform-spacings px-5 py-6 px-md-6 px-lg-7 py-md-7 bg-light fs-sm rounded-lg\" aria-labelledby=\"toc-title-1336\"><p class=\"h5 m-0\" id=\"toc-title-1336\">Inhaltsverzeichnis<\/p><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">01<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#brainstorming\">Brainstorming<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">02<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#es-wird-grammatikalisch\">Es wird grammatikalisch<\/a><a class=\"scrollme link-body-color\" href=\"#kontextfreie-grammatiken-und-parsing-expression-grammars\">Kontextfreie Grammatiken und Parsing Expression Grammars<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">03<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#wir-heben-ab\">Wir heben ab<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">04<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#wie-ein-blatt-im-wind\">Wie ein Blatt im Wind<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">05<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#cool-aber-was-nun\">Cool, aber was nun?<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">06<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#ueberlegungen\">\u00dcberlegungen<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">07<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#die-naechsten-schritte\">Die n\u00e4chsten Schritte<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">08<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#vor-und-nachteile\">Vor- und Nachteile<\/a><a class=\"scrollme link-body-color\" href=\"#vorteile\">Vorteile:<\/a><a class=\"scrollme link-body-color\" href=\"#nachteile\">Nachteile:<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">09<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#endlich-am-ende\">Endlich am Ende<\/a><\/div><\/div><\/nav>\n\n\n<p class=\"wp-block-paragraph\">Traditionell gibt es f\u00fcr dieses Problem folgende L\u00f6sungsans\u00e4tze:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Daten in eine Datenbank einspeisen und dann Datenbankabfragen ausf\u00fchren, oft in einem festen Zeitintervall<\/li>\n\n\n\n<li>Map-Reduce-L\u00f6sungen wie Hadoop<\/li>\n\n\n\n<li>Mechanical Turk \u00a0<\/li>\n\n\n\n<li>Echtzeitfilter.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Wir konzentrierten uns auf die Entwicklung eines Systems, das es im Grunde allen im Entwicklungs- und Support-Team erm\u00f6glicht, <b>Regeln zu verfassen, die reagieren und in ihrem Namen Aktionen ausf\u00fchren.<\/b><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Brainstorming<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Beim Design dieses Systems versuchten wir etwas zu entwickeln, das allen das richtige Werkzeug an die Hand gibt, um schnell zu iterieren und auf Bedrohungen f\u00fcr unser System zu reagieren, wobei folgende Regeln gelten sollten:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Die Nutzer sollten nach Belieben eigene Regeln hinzuf\u00fcgen k\u00f6nnen<\/li>\n\n\n\n<li>Die dom\u00e4nenspezifische Sprache, fortan als DSL bezeichnet, sollte so einfach wie m\u00f6glich sein und idealerweise wie etwas aussehen, das sie bereits kennen.<\/li>\n\n\n\n<li>Man sollte seine Regeln anhand historischer Daten testen k\u00f6nnen, bevor sie angewendet werden.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Wir verwenden intern Kibana, <b>daher war etwas ideal, das sich damit testen lie\u00df, um Punkt 3 zu erf\u00fcllen<\/b>. Das f\u00fchrt zu einer einfachen Schlussfolgerung: Wir sollten einen von Lucene inspirierten DSL-Parser schreiben.\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die erste Iteration des Systems st\u00fctzte sich auf regul\u00e4re Ausdr\u00fccke und eine Menge zeichenweises Parsen. Es erf\u00fcllte seinen Zweck, aber die folgenden Iterationen wurden schnell immer komplexer. Falls Sie jemals ein gro\u00dfes String-Parsing-Projekt durchgef\u00fchrt haben, wissen Sie, was wir meinen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr die Zukunft <b>wussten wir, dass wir etwas entwickeln mussten, worauf sich schnell aufbauen lie\u00df<\/b> \u2013 und das idealerweise einem bekannten Standard entspricht.<\/p>\n\n\n\r\n    <aside data-content-type=\"longform\"  class=\"banner-block longform-spacings rounded-lg shadow-lg px-5 py-6 px-md-6 py-md-7 p-lg-7 bg-light\" data-theme=\"dark\" aria-labelledby=\"banner-block-block_d7055e50f0440e06e2c6cda1d14e9820\">\r\n                    <p class=\"text-uppercase section-caption text-body-color\">\r\n                Registrieren            <\/p>\r\n                            <p class=\"h4 text-accent fw-bold\" id=\"banner-block-block_d7055e50f0440e06e2c6cda1d14e9820\">\r\n                Loslegen ist ganz einfach. Und es ist kostenlos.            <\/p>\r\n                            <div class=\"mb-0 text-body-color\">\r\n                                    <div class=\"content-body mb-0 text-body-color\">Erfahren Sie, was Sie mit der weltbesten Plattform f\u00fcr E-Mail-Zustellung alles erreichen k\u00f6nnen.<\/div>\r\n                            <\/div>\r\n        \r\n        <div class=\"text-start mt-5\"><a href=\"https:\/\/signup.mailgun.com\/new\/signup\"  class=\"btn btn-secondary\" >Get started<\/a><\/div>\r\n    <\/aside>\r\n\r\n\n\n\n<h2 class=\"wp-block-heading\">Es wird grammatikalisch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wer im Studium Kurse in Automatentheorie und \u00c4hnlichem belegt hat, erinnert sich wahrscheinlich an Grammatiken im Kontext von Programmiersprachen. Zudem ist davon auszugehen, dass einige aus der Leserschaft bei diesem Thema weitaus mehr Expertise haben als ich als bescheidener Autor. F\u00fcr tiefergehende Erkl\u00e4rungen verweise ich daher auf die Suchmaschine des Vertrauens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Trotzdem lohnt es sich, kurz dar\u00fcber zu sprechen, was eine Grammatik ausmacht und warum sie n\u00fctzlich ist. Um Wikipedia zu zitieren: eine <a href=\"https:\/\/en.wikipedia.org\/wiki\/Formal_grammar\" target=\"_tabs\" rel=\"noopener noreferrer\">formale Grammatik<\/a> ist \u201e&#8230;eine Menge von Produktionsregeln f\u00fcr Strings in einer formalen Sprache. <b>Die Regeln beschreiben, wie man aus dem Alphabet der Sprache Strings bildet, die gem\u00e4\u00df der Syntax der Sprache g\u00fcltig sind<\/b>. Eine Grammatik beschreibt weder die Bedeutung der Strings noch, was mit ihnen in welchem Kontext auch immer getan werden kann \u2013 sondern ausschlie\u00dflich ihre Form.\u201c<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Auf die Gefahr hin, es zu stark zu vereinfachen: Sie erm\u00f6glicht es uns, einen String wie \u201eYou&#8217;ve got mail!\u201c in Tokens zu zerlegen, die wir semantisch analysieren k\u00f6nnen. Mit anderen Worten: Falls unsere Grammatik gut definiert ist, k\u00f6nnen wir weiteren Code schreiben, um die Bedeutung dieses Strings zu bestimmen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Geschichte und die Arten von Grammatiken f\u00fcllen tonnenweise B\u00fccher und sprengen daher den Rahmen eines Blog-Beitrags. Stattdessen konzentrieren wir uns auf <b>kontextfreie Grammatiken<\/b> und genauer gesagt auf Parsing Expression Grammars.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Kontextfreie Grammatiken und Parsing Expression Grammars<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Um noch einmal Wikipedia zu zitieren: eine<a href=\"https:\/\/en.m.wikipedia.org\/wiki\/Context-free_grammar\" target=\"_tabs\" rel=\"noopener noreferrer\"> kontextfreie Grammatik<\/a> ist \u201eein bestimmter Typ einer formalen Grammatik: eine Menge von Produktionsregeln, die alle m\u00f6glichen Strings in einer gegebenen formalen Sprache beschreiben. Produktionsregeln sind einfache Ersetzungen.\u201c<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anders gesagt: Eine kontextfreie Grammatik <b>definiert einen Graphen, der wiederum definiert, wie eine Sprache analysiert (geparst) wird<\/b>. Wie oben erw\u00e4hnt, sagt sie uns <i>nicht<\/i>, wie wir die Sprache verstehen sollen. Es ist auch erw\u00e4hnenswert \u2013 wie wir weiter unten sehen werden \u2013, dass der Graph Zyklen haben kann, aber er terminiert schlie\u00dflich.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kontextfreie Grammatiken haben eine Art Verwandten in Form der<a href=\"https:\/\/en.m.wikipedia.org\/wiki\/Parsing_expression_grammar\" target=\"_tabs\" rel=\"noopener noreferrer\"> Parsing Expression Grammar<\/a>, oder PEG. Sie <i>sehen<\/i> stark nach einer kontextfreien Grammatik (CFG) aus, bringen aber einen sehr n\u00fctzlichen Unterschied mit sich: Wenn eine PEG mit einer mehrdeutigen Auswahl konfrontiert wird, w\u00e4hlt sie stets die erste definierte Produktionsregel. Die CFG bel\u00e4sst die Auswahl stattdessen mehrdeutig\u00a0\u2013 und warum sollten wir uns mit Mehrdeutigkeit herumschlagen, wenn wir nicht m\u00fcssen?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das bedeutet letztlich, dass <b>es einfacher ist, Tools zur Definition von PEGs zu schreiben<\/b>. Zum Gl\u00fcck haben das bereits viele Menschen f\u00fcr uns \u00fcbernommen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wir heben ab<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nach einiger Recherche entschieden wir uns f\u00fcr <a href=\"https:\/\/github.com\/mna\/pigeon\" target=\"_tabs\" rel=\"noopener noreferrer\">Pigeon<\/a> als Basis f\u00fcr unsere PEG. Pigeon folgt dem gleichen Paradigma wie viele Go-Tools, indem es Code generiert, der zusammen mit Ihrem Programm kompiliert wird.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Nutzung ist recht einfach: Sie definieren sowohl die Grammatik als auch den Go-Code, um jede der Regeln im selben Paket zu handhaben, und rufen einfach Parse() im generierten Parser auf. Die Herausforderung besteht darin, Handler f\u00fcr jede dieser Regeln zu schreiben. Wie bei Grammatiken k\u00f6nnte auch das Thema Kompilierung ganze Bibliotheken f\u00fcllen. Zum Gl\u00fcck <b>ist das Schreiben eines Interpreters weniger komplex<\/b>, und der resultierende Code ist f\u00fcr unsere Anforderungen schnell genug.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Au\u00dferdem versucht die Syntax, sich eng an die Go-Syntax selbst anzulehnen. Das erleichtert es, Ihre PEG parallel zu Ihrem Go-Programm zu schreiben, das diese Grammatik nutzt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wie ein Blatt im Wind<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Angenommen, Sie haben ein Ereignis, das durch den Versand einer E-Mail generiert wird, codiert in JSON, und das so aussieht:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>{<br>\n\u00a0\"event\": \"sent\",<br>\n\u00a0\"subject\": \"A special offer just for you!\",<br>\n\u00a0\"account\": \"12345\",<br>\n}<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es gibt mehrere M\u00f6glichkeiten, dieses Ereignis zu betrachten: Sie k\u00f6nnten entscheiden, dass dies eine harmlose E-Mail ist, oder Sie k\u00f6nnten sagen: \u201eDas k\u00f6nnte Spam sein, aber es gibt nicht genug Informationen f\u00fcr eine Entscheidung.\u201c Dies ist ein sehr h\u00e4ufiges Problem in unserem System und erfordert immer viele aggregierte Daten, um zu einem Schluss zu kommen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Schreiben wir also eine Regel, die auf das obige Ereignis zutrifft:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    event:&quot;sent&quot; AND subject:&quot;A special offer just for you!&quot;\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Das l\u00e4sst sich ziemlich einfach parsen, und besser noch: Es kann auch in Kibana \u00fcberpr\u00fcft werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gehen wir nun Schritt f\u00fcr Schritt durch, <b>wie man eine sehr einfache PEG aufbaut<\/b>, die auf diese Regel zutrifft. Wir implementieren jede Produktionsregel einzeln und erkl\u00e4ren, was sie tut. Regelnamen folgen \u00fcblicherweise<a href=\"https:\/\/en.wikipedia.org\/wiki\/Pascal_(programming_language)#Language_constructs\" target=\"_tabs\" rel=\"noopener noreferrer\"> PascalCase<\/a> und erlauben zudem Zahlen sowie Unterstriche. Jede Regel hat folgendes Format:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    RuleName &lt;- \r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Beachten Sie, dass es eigentlich mehrere g\u00fcltige Zeichen f\u00fcr den Regeldefinitions-Operator gibt, aber wir verwenden gerne &lt;-, da es leicht einzutippen ist und am ehesten so aussieht wie Grammatiken, die akademisch definiert sind.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die erste Regel in der Grammatik wird als Einstiegspunkt behandelt:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Input &lt;- Term !.\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Unsere <code>Input<\/code>-Regel besagt mit <code>!.<\/code>: \u201eStimme mit dem gesamten Eingabe-String \u00fcberein\u201c, was \u201eStimme mit dem Ende der Datei \u00fcberein\u201c bedeutet. Dies \u00fcbergibt den gesamten Eingabe-String an eine Regel namens Term, die wie folgt aussieht:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Term &lt;- Variable AndVar*\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Dadurch wird der Kontrollfluss an die Variable-Produktionsregel \u00fcbergeben:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Variable &lt;-  FieldChars+ _ &quot;:&quot; _ Value\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt wird es etwas komplexer. Zuerst gleichen wir alle Zeichen gierig (greedy) ab, bis die FieldChars-Regel erf\u00fcllt ist. Beachten Sie das <code>+<\/code> am Ende. Die PEG-Syntax hat viel mit regul\u00e4ren Ausdr\u00fccken gemeinsam. Das hier besagt also: \u201eStimme einmal oder mehrmals mit der Regel <code>FieldChars<\/code> \u00fcberein\u201c.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    FieldChars &lt;- [a-z]\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Erneut gilt: Falls Sie mit der Regex-Syntax vertraut sind, sollte dies unkompliziert sein: Gleichen Sie einfach ein beliebiges einzelnes Zeichen zwischen \u201ea\u201c und \u201ez\u201c ab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nun zur\u00fcck zu Variable. Der n\u00e4chste Teil <code>_<\/code> ist eine Regel, die besagt: \u201eStimme mit einem beliebigen Leerzeichen (Whitespace) \u00fcberein\u201c. Beachten Sie, dass <code>_<\/code> ein absolut g\u00fcltiger Bezeichner f\u00fcr eine Produktionsregel ist\u00a0\u2013 und weniger tippen zu m\u00fcssen, ist normalerweise von Vorteil.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                Java                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-Java\">\r\n                                <code id=\"code_0_content\" class=\"language-Java\">\r\n\r\n                                    _ &quot;whitespace&quot; &lt;- [ \\n\\t\\r]*\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Hier gibt es einige Dinge zu beachten:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Der String \u201ewhitespace\u201c ist der \u201eanzeigefreundliche Name\u201c und dient der Dokumentation sowie Ihrem zuk\u00fcnftigen Verstand.<\/li>\n\n\n\n<li>Wie bei der Syntax regul\u00e4rer Ausdr\u00fccke stimmt dies mit jeder Form von Leerzeichen, Zeilenumbr\u00fcchen, Tabs oder Wagenr\u00fcckl\u00e4ufen \u00fcberein.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Der n\u00e4chste Teil der Variable-Regel stimmt mit dem String-Literal \u201eAND\u201c \u00fcberein. Viel einfacher geht es nicht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Als N\u00e4chstes haben wir eine weitere Whitespace-Regel und dann schlie\u00dflich die Value-Regel.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Value &lt;- &#039;&quot;&#039; ValueChars* &#039;&quot;&#039;\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Diese Regel stimmt mit dem String-Literal <code>'\"'<\/code>, null oder mehr ValueChars-Regeln und schlie\u00dflich einem weiteren Anf\u00fchrungszeichen \u00fcberein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ValueChars<\/code> sieht folgenderma\u00dfen aus:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    How we built a Lucene-inspired parser in Go\r\n\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Diese <code>ValueChars<\/code> stimmen mit dem Klein- und Gro\u00dfbuchstaben-Alphabet, beliebigen Zahlen, Leerzeichen sowie dem Ausrufezeichen \u00fcberein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Warum haben wir Value so definiert? Weil <b>die Regel die doppelten Anf\u00fchrungszeichen f\u00fcr uns entfernen kann, sodass wir es nicht tun m\u00fcssen<\/b>\u00a0\u2013 und wir sind nat\u00fcrlich bequem. Das ist jedoch lediglich eine Annehmlichkeit, die wir auch h\u00e4tten weglassen k\u00f6nnen, um stattdessen die Regelform von Value in die Definition der Variable-Regel aufzunehmen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Schlie\u00dflich sollte <code>AndVar<\/code> an dieser Stelle ziemlich selbsterkl\u00e4rend sein. Beachten Sie, dass sie auf Term verweist und den bereits erw\u00e4hnten Zyklus implementiert.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    ValueChars &lt;- [a-zA-Z0-9 !]\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Die vollst\u00e4ndige Definition sieht so aus.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Input &lt;- Term !.\r\nTerm &lt;- Variable AndVar*\r\nAndVar &lt;- _ &quot;AND&quot; _ Term\r\nVariable &lt;- FieldChars+ _ &quot;:&quot; _ Value\r\n_ &quot;whitespace&quot; &lt;- [ \\n\\t\\r]*\r\nValue &lt;- &#039;&quot;&#039; ValueChars &#039;&quot;&#039;\r\nFieldChars &lt;- [a-z]\r\nValueChars &lt;- [a-zA-Z0-9 !]\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">Cool, aber was nun?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Der wahre Wert bei der Definition einer eigenen Grammatik zeigt sich erst, wenn Sie Implementierungen f\u00fcr die Aktionen der Regeln bereitstellen. Schauen wir uns die echte PEG-Definition an:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    {\r\n package main\r\n\r\n import (\r\n   &quot;strings&quot;\r\n )\r\n\r\n type Node interface {\r\n   Evaluate(input Event) (bool, error)\r\n }\r\n\r\n type Term struct {\r\n   node Node\r\n }\r\n\r\n func (t *Term) Evaluate(input Event) (bool, error) {\r\n   return t.node.Evaluate(input)\r\n }\r\n\r\n type AndNode struct {\r\n   Nodes []Node\r\n }\r\n\r\n func (n *AndNode) Evaluate(input Event) (bool, error) {\r\n   for _, node := range n.Nodes {\r\n     matched, err := node.Evaluate(input)\r\n     if err != nil {\r\n       return false, err\r\n     }\r\n     if !matched {\r\n       return false, nil\r\n     }\r\n   }\r\n   return true, nil\r\n }\r\n\r\n type Variable struct {\r\n   Field string\r\n   Value string\r\n }\r\n\r\n func (v *Variable) Evaluate(input Event) (bool, error) {\r\n   fieldVal, ok := input[v.Field]\r\n   if !ok {\r\n     return false, fmt.Errorf(&quot;Field &#039;%s&#039; not present in the event&quot;, v.Field)\r\n   }\r\n\r\n   return fieldVal == v.Value, nil\r\n }\r\n\r\n func toString(label interface{}) string {\r\n   var sb strings.Builder\r\n   value := label.([]interface{})\r\n   for _, i := range(value) {\r\n     if i == nil {\r\n       continue\r\n     }\r\n     switch b := i.(type) {\r\n     case []byte:\r\n       sb.WriteByte(b[0])\r\n     case []interface{}:\r\n       s := toString(i)\r\n       sb.WriteString(s)\r\n     default:\r\n       fmt.Printf(&quot;She&#039;s dead, Jim %T %+v\\n&quot;, i, i)\r\n     }\r\n   }\r\n   return sb.String()\r\n }\r\n}\r\n\r\nInput &lt;- Term !.\r\n\r\nTerm &lt;- variable:Variable rest:AndVar* {\r\n andVars := rest.([]interface{})\r\n variables := make([]Node, 0, len(andVars))\r\n variables = append(variables, variable.(Node))\r\n for _, r := range(andVars) {\r\n      variables = append(variables, r.(Node))\r\n   }\r\n   return &amp;AndNode{Nodes: variables}, nil\r\n}\r\n\r\nAndVar &lt;- _ &quot;AND&quot; _ rightSide:Term {\r\n   return rightSide, nil\r\n}\r\n\u200b\r\nVariable &lt;- field:FieldChars+ _ &quot;:&quot; _ value:Value {\r\n   return &amp;Variable{Field: toString(field), Value: toString(value)}, nil\r\n}\r\n\r\nValue &lt;- &#039;&quot;&#039; value:ValueChars* &#039;&quot;&#039; {\r\n   return value, nil\r\n}\r\n\r\n_ &quot;whitespace&quot; &lt;- [ \\n\\t\\r]*\r\nFieldChars &lt;- [a-z]\r\nValueChars &lt;- [a-zA-Z0-9 !]\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Hier gibt es einiges zu entschl\u00fcsseln, also gehen wir es Schritt f\u00fcr Schritt durch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ganz oben haben wir einen Codeblock, der von geschweiften Klammern umschlossen ist. Das ist eine Pigeon-Konvention, die den umschlossenen Code wortw\u00f6rtlich \u00fcbernimmt und in die endg\u00fcltige generierte Code-Ausgabe einf\u00fcgt. Beachten Sie, dass Sie hier bequem die f\u00fcr Ihre Grammatik relevanten Typen definieren k\u00f6nnen. Alternativ packen Sie diese in eine andere Datei, da Pigeon den hier deklarierten Paketnamen verwendet. Alles danach ist die Definition der Grammatik selbst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An dieser Stelle haben Sie wahrscheinlich bemerkt, dass sich die Regeln etwas davon unterscheiden, wie wir sie oben definiert haben. Schauen wir uns <code>Term<\/code> an.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    Term &lt;- variable:Variable rest:AndVar*\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Dies ist fast unsere <code>Term<\/code>-Definition von vorhin, aber nun haben wir sie n\u00fctzlich gemacht. Stellt man einer Regel in der Definition <code>name<\/code>: voran, wird der R\u00fcckgabewert dieser Regel an name zugewiesen und <code>name<\/code> wird dann an die Funktion \u00fcbergeben, die von Ihrer Regel-Aktion definiert wurde, wenn der Code generiert wird. Der gesamte Code zwischen den geschweiften Klammern <b>wird zu einer mit dieser Regel verkn\u00fcpften Funktion<\/b> und wird aufgerufen, wenn die Regel zutrifft:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    func (c *current) onTerm1(variable, rest interface{}) (interface{}, error) {\r\n andVars := rest.([]interface{})\r\n variables := make([]Node, 0, len(andVars))\r\n variables = append(variables, variable.(Node))\r\n for _, r := range andVars {\r\n   variables = append(variables, r.(Node))\r\n }\r\n return &amp;AndNode{Nodes: variables}, nil\r\n}\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Hier sehen wir, dass Pigeon ausschlie\u00dflich mit leeren Interface-Typen arbeitet. Das ist gro\u00dfartig f\u00fcr die Flexibilit\u00e4t, aber weniger ideal f\u00fcr das Schreiben der Implementierung, da wir diese ber\u00fccksichtigen m\u00fcssen.<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    andVars := rest.([]interface{})\r\nvariables := make([]Node, 0, len(andVars))\r\nvariables = append(variables, variable.(Node))\r\nfor _, r := range andVars {\r\n variables = append(variables, r.(Node))\r\n}\r\nreturn &amp;AndNode{Nodes: variables}, nil\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">Wie bereits erw\u00e4hnt, <b>k\u00f6nnen wir in den Regeln Zyklen haben<\/b>. Daher wissen wir, dass es m\u00f6glich ist, eine unendliche Anzahl von Terms zu erhalten, die der <code>rest<\/code>-Variable zugeordnet sind. Pigeon l\u00f6st dies, indem es uns einen Slice aus leeren Interfaces \u00fcbergibt. Wir haben ein <code>Node<\/code>-Interface erstellt, in das alles per Type-Inference umgewandelt werden muss, bevor wir es verwenden k\u00f6nnen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nachdem wir die gesamte Liste der <code>AND<\/code>-verkn\u00fcpften Variablen durchlaufen haben, erstellen wir einen <code>AndNode<\/code>, der jeden der Terms enth\u00e4lt. Die Definition des AndNode ist im Code-Literal-Abschnitt zu finden, der ganz oben in der PEG definiert wurde. Als Implementierung des Node-Interfaces definiert sie eine Evaluate-Methode, die besagt, dass der Ausdruck nur dann als wahr evaluiert, wenn auch alle einzelnen Terms als wahr evaluiert werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An diesem Punkt sollte der Rest der Definition hoffentlich Sinn ergeben, also springen wir direkt zur Ausf\u00fchrung. Das folgende Code-Listing zeigt das Parsen unserer Regel, ihre Nutzung sowie einige zus\u00e4tzliche Beispiele, um Fehler und Error-Handling zu demonstrieren:<\/p>\n\n\n    <div data-content-type=\"longform\" class=\"code-snippet longform-spacings rounded-lg overflow-hidden shadow \" data-count=\"1\">\r\n        <ul class=\"nav nav-buttons code-snippet__tabs longform-except position-relative d-flex gap-2 flex-wrap p-3\" role=\"tablist\">\r\n\r\n                            \r\n                    \r\n                        <li class=\"nav-item\" role=\"presentation\">\r\n                            <button class=\"nav-link active\" data-bs-toggle=\"tab\" data-bs-target=\"#code_0\" type=\"button\" role=\"tab\" aria-controls=\"code_0\" aria-selected=\"true\">\r\n                                PHP                            <\/button>\r\n                        <\/li>\r\n\r\n                    \r\n                            \r\n        <\/ul>\r\n        <div class=\"code-snippet__tab-content tab-content\">\r\n\r\n                            \r\n                    <div class=\"tab-pane show active\" id=\"code_0\" role=\"tabpanel\" aria-labelledby=\"code_0\">\r\n                        <div class=\"code-snippet__code-wrapper\">\r\n                            <div class=\"nav nav-buttons code-snippet__copy-wrapper\">\r\n                                <button type=\"button\" class=\"nav-link code-snippet__copy\" data-clipboard-target=\"#code_0_content\" data-clipboard-label=\"In die Zwischenablage kopieren\" data-clipboard-success-label=\"Kopiert\" data-clipboard-error-label=\"Kopieren nicht m\u00f6glich\" data-tooltip=\"In die Zwischenablage kopieren\" data-tooltip-placement=\"left\" role=\"tooltip\" aria-label=\"In die Zwischenablage kopieren\">\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--default\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/file-stack.svg\"><\/svg>\r\n                                    <svg class=\"code-snippet__copy-icon code-snippet__copy-icon--success\" width=\"24\" height=\"24\" aria-hidden=\"true\" data-url=\"https:\/\/www.mailgun.com\/wp-content\/plugins\/sinch-core\/assets\/icons\/sinch\/badge-check.svg\"><\/svg>\r\n                                <\/button>\r\n                            <\/div>\r\n                            <pre class=\"w-100 h-100 m-0 line-numbers language-PHP\">\r\n                                <code id=\"code_0_content\" class=\"language-PHP\">\r\n\r\n                                    package main\r\n\r\nimport (\r\n &quot;fmt&quot;\r\n)\r\n\r\ntype Event map[string]string\r\n\r\nfunc Match(rule string, event Event) (bool, error) {\r\n \/\/ Parse is generated by pigeon in this package\r\n tree, err := Parse(&quot;parsing&quot;, []byte(rule))\r\n if err != nil {\r\n   return false, err\r\n }\r\n\r\n \/\/ Yes, this is a bit ugly. It&#039;s a consequence of pigeon dealing in interface slices\r\n iface, ok := tree.([]interface{})\r\n if !ok {\r\n   return false, fmt.Errorf(&quot;Internal Error&quot;)\r\n }\r\n\r\n ast, ok := iface[0].(Node)\r\n if !ok {\r\n   return false, fmt.Errorf(&quot;Internal Error&quot;)\r\n }\r\n\r\n \/\/ ast is the tree generated by our supplementary Go defined by the production rules\r\n return ast.Evaluate(event)\r\n}\r\n\r\nfunc main() {\r\n  rules := []string{\r\n   &quot;event:\\&quot;sent\\&quot; AND subject:\\&quot;A special offer just for you!\\&quot;&quot;,\r\n   &quot;event:\\&quot;found\\&quot; AND subject:\\&quot;A special offer just for you!\\&quot;&quot;,\r\n   &quot;event:\\&quot;sent\\&quot; AND badfield:\\&quot;A special offer just for you!\\&quot;&quot;,\r\n  }\r\n\r\n  event := map[string]string{\r\n    &quot;event&quot;:   &quot;sent&quot;,\r\n    &quot;subject&quot;: &quot;A special offer just for you!&quot;,\r\n    &quot;account&quot;: &quot;12345&quot;,\r\n  }\r\n\r\n  for _, rule := range rules {\r\n    matched, err := Match(rule, Event(event))\r\n    if err != nil {\r\n      fmt.Printf(&quot;Rule &#039;%s&#039; failed with error &#039;%s&#039;\\n&quot;, rule, err.Error())\r\n    } else {\r\n      fmt.Printf(&quot;Rule &#039;%s&#039; matched: %t\\n&quot;, rule, matched)\r\n    }\r\n  }\r\n}\r\n                                <\/code>\r\n                            <\/pre>\r\n                        <\/div>\r\n                    <\/div>\r\n                                    <\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fchren Sie einfach Folgendes aus:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>~&gt; go get\u00a0<\/code><a href=\"https:\/\/github.com\/mna\/pigeon\"><code>github.com\/mna\/pigeon<\/code><\/a><code>\u00a0\u00a0 ~&gt; pigeon rules.peg &gt; rules.go \u00a0 ~&gt; go run . Rule 'event:\"sent\" AND subject:\"A special offer just for you!\"' matched: true Rule 'event:\"found\" AND subject:\"A special offer just for you!\"' matched: false Rule 'event:\"sent\" AND badfield:\"A special offer just for you!\"' failed with error 'Field 'badfield' not present in the event'<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Herzlichen Gl\u00fcckwunsch! <b>Sie haben nun Ihre eigene Sprache geschrieben\u00a0\u2013 auch wenn sie von \u00e4u\u00dferst begrenztem Nutzen ist.<\/b><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00dcberlegungen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An dieser Stelle denken Sie vielleicht:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Verwenden nicht viele Absender solche Betreffzeilen?<\/li>\n\n\n\n<li>Ist eine Rules-Engine, die nur String-Literale abgleicht, \u00fcberhaupt so n\u00fctzlich?<\/li>\n\n\n\n<li>H\u00e4tte dieser Beitrag nicht auch halb so lang sein k\u00f6nnen?<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Darauf w\u00fcrden wir antworten:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Wir w\u00fcrden eine Art Handling f\u00fcr das <code>account<\/code> implementieren wollen, wie im urspr\u00fcnglichen Ereignis definiert. Mailgun l\u00f6st dieses Problem, indem es Gesch\u00e4ftslogik in die Codebasis integriert, um Rate-Limiting basierend auf einem definierten Feld zu unterst\u00fctzen. Mit anderen Worten k\u00f6nnen wir sagen: \u201eFalls diese Regel zutrifft, speichere das Konto und die aktuelle Uhrzeit und f\u00fchre diese Aktion f\u00fcr die n\u00e4chsten N Minuten nicht f\u00fcr dieses Konto aus.\u201c Offensichtlich w\u00fcrde der Support eine Million Mal benachrichtigt, falls wir dieses Handling nicht h\u00e4tten und der betreffende Absender eine Million E-Mails versenden w\u00fcrde. Das w\u00e4re ein hervorragender Weg, um Ihr Support-Team in Meldungen ertrinken zu lassen\u00a0\u2013 und nach der Arbeit auf dem Parkplatz aufgelauert zu bekommen.<\/li>\n\n\n\n<li>Man k\u00f6nnte Regeln implementieren, um regul\u00e4re Ausdr\u00fccke und Teilstrings (Substrings) zu parsen, was weitaus n\u00fctzlicher w\u00e4re als ein expliziter String-Abgleich. Tats\u00e4chlich haben wir genau das getan.<\/li>\n\n\n\n<li>Entschuldigung.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Zu guter Letzt ist Ihnen wahrscheinlich aufgefallen, dass wir hier nicht definiert haben, was die Regel ausf\u00fchrt, wenn sie <i>tats\u00e4chlich<\/i> zutrifft. Eine m\u00f6gliche L\u00f6sung ist, dass die Regel eine Nachricht in einem Slack-Kanal postet, wenn sie ausgel\u00f6st wird. Dies ist eine g\u00e4ngige L\u00f6sung hier bei Mailgun und sieht folgenderma\u00dfen aus:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>slack:#channel-name<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die n\u00e4chsten Schritte<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hoffentlich sprudeln Sie an diesem Punkt \u00fcber vor lauter M\u00f6glichkeiten. Hier sind einige \u00dcberlegungen, die wir uns gemacht haben:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In der Lucene-Syntax gibt es noch viel mehr zu emulieren, wie NOT- und OR-Anweisungen sowie Klammern.<\/li>\n\n\n\n<li>Eine separate Grammatik f\u00fcr Aktionen bereitstellen.<\/li>\n\n\n\n<li>Templatization implementieren, um Werte aus dem Ereignis in die Aktion einzuf\u00fcgen.<\/li>\n\n\n\n<li>Syntax-Zucker hinzuf\u00fcgen, um das Schreiben bestimmter Filter zu erleichtern.<\/li>\n\n\n\n<li>Ein System implementieren, das eine bestimmte Anzahl von Ereignissen \u00fcber einen bestimmten Zeitraum hinweg z\u00e4hlt und darauf reagiert.<\/li>\n\n\n\n<li>Einen Cache implementieren, da das Parsen der Regeln ziemlich ressourcenintensiv ist.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Es gibt noch unz\u00e4hlige weitere M\u00f6glichkeiten, insbesondere beim Ausbau des Aktions-Parsers. <b>Sie k\u00f6nnten andere Services aufrufen, Kunden benachrichtigen, das Licht ein- und ausschalten und vieles mehr.<\/b> Wenn es darum geht, auf dieser Basis eigene Tools zu erfinden, sind Ihnen keine Grenzen gesetzt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vor- und Nachteile<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wahrscheinlich fragen Sie sich an diesem Punkt: \u201eWarum haben die nicht $SOME_OTHER_TOOL genutzt?\u201c\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Antwort: Weil wir derzeit weder die Leistung eines dieser Tools ben\u00f6tigen noch die Komplexit\u00e4t, die ihr Betrieb h\u00e4ufig mit sich bringt. Unser aktuelles Stream-Processing-Tool ist eine einzelne, einfache Binary, die in einem Container bereitgestellt wird und Just Works\u2122. Es gibt kaum etwas zu verwalten, und es h\u00e4lt m\u00fchelos mit unserem hochvolumigen Event-Feed mit.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Vorteile:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Es ist einfach zu entwickeln<\/li>\n\n\n\n<li>Es nutzt weiterhin standardm\u00e4\u00dfige FOSS-Tools<\/li>\n\n\n\n<li>Es l\u00e4sst sich genau auf unsere Bed\u00fcrfnisse zuschneiden<\/li>\n\n\n\n<li>Die Syntax unserer DSL ist winzig, leicht zu artikulieren und zu verstehen. Zudem zwingt sie alle, Regeln in etwa auf die gleiche Weise zu verfassen. Dadurch wird es auch schwieriger, unbeabsichtigte Nebeneffekte zu erzeugen<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Nachteile:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Sprachfunktionen, die \u00fcber das bereits Implementierte hinausgehen, stellen einen erheblichen Sprung in der Komplexit\u00e4t dar.<\/li>\n\n\n\n<li>Das Aktualisieren der Quell-PEG generiert neuen Code, was Code-Diffs ziemlich un\u00fcbersichtlich macht.<\/li>\n\n\n\n<li>Die bewusste Einfachheit von Lucene kann das Verfassen komplexerer Regeln erschweren.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Vielleicht entscheiden wir uns irgendwann, dass $SOME_OTHER_TOOL besser f\u00fcr unsere Anforderungen geeignet ist. F\u00fcr die absehbare Zukunft <b>reicht die Leistung, die unsere Mailgun-DSL liefert, jedoch v\u00f6llig aus.<\/b><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Endlich am Ende<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wir hoffen, an diesem Punkt verdeutlicht zu haben, wie n\u00fctzlich das Schreiben einer eigenen DSL sein kann. Unsere Implementierung verarbeitet t\u00e4glich eine enorme Menge an Ereignissen und macht dabei das Leben vieler unserer Teammitglieder sehr viel leichter (zumindest reden wir ihnen das ein).\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Was die unterst\u00fctzten Features angeht: <b>Wir fangen gerade erst an<\/b>. Falls Sie das dazu inspiriert hat, die Implementierung Ihrer eigenen Stream-Processing-Grammatik in Betracht zu ziehen, lassen Sie es uns bitte wissen. Wir w\u00fcrden uns freuen, davon zu h\u00f6ren.<\/p>\n\n\n\r\n    <aside data-content-type=\"longform\"  class=\"banner-block longform-spacings rounded-lg shadow-lg px-5 py-6 px-md-6 py-md-7 p-lg-7 bg-light\" data-theme=\"dark\" aria-labelledby=\"banner-block-block_d7055e50f0440e06e2c6cda1d14e9820\">\r\n                    <p class=\"text-uppercase section-caption text-body-color\">\r\n                Registrieren            <\/p>\r\n                            <p class=\"h4 text-accent fw-bold\" id=\"banner-block-block_d7055e50f0440e06e2c6cda1d14e9820\">\r\n                Loslegen ist ganz einfach. Und es ist kostenlos.            <\/p>\r\n                            <div class=\"mb-0 text-body-color\">\r\n                                    <div class=\"content-body mb-0 text-body-color\">Erfahren Sie, was Sie mit der weltbesten Plattform f\u00fcr E-Mail-Zustellung alles erreichen k\u00f6nnen.<\/div>\r\n                            <\/div>\r\n        \r\n        <div class=\"text-start mt-5\"><a href=\"https:\/\/signup.mailgun.com\/new\/signup\"  class=\"btn btn-secondary\" >Get started<\/a><\/div>\r\n    <\/aside>\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Bei Mailgun haben wir zahlreiche Systeme, die zu jeder Tagesstunde eine Unmenge an Ereignissen generieren. Diese Zahl ist so gro\u00df, dass es f\u00fcr ein Team unm\u00f6glich ist, ElasticSearch-Ergebnisse manuell zu durchsuchen und konsistente Resultate zu erwarten \u2013 oder dabei nicht den Verstand zu verlieren.<\/p>\n","protected":false},"author":62,"featured_media":4843,"menu_order":0,"template":"","meta":{"_acf_changed":true,"footnotes":""},"blog_category":[23],"class_list":["post-24302","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog_category-it-and-engineering"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013\" \/>\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.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"11\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/\",\"name\":\"Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"datePublished\":\"2026-09-16T11:46:58+00:00\",\"description\":\"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-IT-Engineering.png\",\"width\":720,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/it-and-engineering\\\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Wie wir einen von Lucene inspirierten Parser in Go entwickelt haben\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Leistungsstarke Transaktions-E-Mail-APIs, mit denen Sie E-Mails senden, empfangen und nachverfolgen k\u00f6nnen, speziell f\u00fcr Entwickler konzipiert. Erfahren Sie noch heute mehr!\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Transactional Email API Service For Developers | Mailgun\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun","description":"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013","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.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/","og_locale":"de_DE","og_type":"article","og_title":"Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun","og_description":"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013","og_url":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","og_image":[{"width":720,"height":448,"url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"11\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/","url":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/","name":"Wie wir einen von Lucene inspirierten Parser in GoLang entwickelt haben - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","datePublished":"2026-09-16T11:46:58+00:00","description":"Wir sind stolz darauf, mit sehr wenig sehr viel zu erreichen. Also machten wir uns daran, herauszufinden, wie wir Echtzeitfilter f\u00fcr uns nutzen k\u00f6nnen. Weiterlesen \u2013","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/#primaryimage","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-IT-Engineering.png","width":720,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/www.mailgun.com\/de\/blog\/it-and-engineering\/wie-wir-einen-von-lucene-inspirierten-parser-in-go-entwickelt-haben\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/de\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/de\/blog\/"},{"@type":"ListItem","position":3,"name":"Wie wir einen von Lucene inspirierten Parser in Go entwickelt haben"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/de\/#website","url":"https:\/\/www.mailgun.com\/de\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Leistungsstarke Transaktions-E-Mail-APIs, mit denen Sie E-Mails senden, empfangen und nachverfolgen k\u00f6nnen, speziell f\u00fcr Entwickler konzipiert. Erfahren Sie noch heute mehr!","publisher":{"@id":"https:\/\/www.mailgun.com\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/de\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.mailgun.com\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","width":512,"height":512,"caption":"Transactional Email API Service For Developers | Mailgun"},"image":{"@id":"https:\/\/www.mailgun.com\/de\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/blog\/24302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/users\/62"}],"version-history":[{"count":0,"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/blog\/24302\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/media\/4843"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/media?parent=24302"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/de\/wp-json\/wp\/v2\/blog_category?post=24302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}