From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Konstantin Kharlamov Newsgroups: gmane.emacs.help Subject: SMIE: defining a build.ninja grammar Date: Fri, 07 Apr 2023 17:18:27 +0300 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="26556"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Evolution 3.46.4 To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sat Apr 08 10:57:45 2023 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pl4OG-0006hu-LJ for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 08 Apr 2023 10:57:45 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pl4O4-0007qP-3u; Sat, 08 Apr 2023 04:57:32 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pkmvL-0006qa-6Q for help-gnu-emacs@gnu.org; Fri, 07 Apr 2023 10:18:44 -0400 Original-Received: from forward103b.mail.yandex.net ([178.154.239.150]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pkmvH-0007MQ-Ee for help-gnu-emacs@gnu.org; Fri, 07 Apr 2023 10:18:42 -0400 Original-Received: from mail-nwsmtp-smtp-production-main-77.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-77.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:8a85:0:640:8fc9:0]) by forward103b.mail.yandex.net (Yandex) with ESMTP id 3E11B600FB for ; Fri, 7 Apr 2023 17:18:29 +0300 (MSK) Original-Received: by mail-nwsmtp-smtp-production-main-77.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id SISe9UVWq0U0-38Rtyory; Fri, 07 Apr 2023 17:18:28 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baumlab.pro; s=mail; t=1680877108; bh=fHz0Mp7HEP6tDDI6D2A81KCISXLIG51O6iAzTH+Vus0=; h=Date:To:From:Subject:Message-ID; b=Dgqjapads/f0WHrNDksouUcpulcAnqPH4zzKjkgfl6d3RlOpVV54ltKQiuWmg319T KzOkPR3fg4dWPnGrkjaQaB4Pimz93pUdf9Tuh+8ANB0nLkfNrzr6kp+yFUQoGeFyzN mxCd0fHzl4+IdZ/Z/41NQOgto4HcaV21O0jjBnqw= Authentication-Results: mail-nwsmtp-smtp-production-main-77.iva.yp-c.yandex.net; dkim=pass header.i=@baumlab.pro Received-SPF: pass client-ip=178.154.239.150; envelope-from=k.harlamov@baumlab.pro; helo=forward103b.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_PDS_PRO_TLD=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 08 Apr 2023 04:57:30 -0400 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:143224 Archived-At: I initially posted this on Emacs stackexchange, but in absence of replies d= ecided to re-post on the mailing list as that's where usually people knowin= g how SMIE works hang out. I'm trying to write a mode in SMIE, to figure out how it works and to creat= e some documentation=C2=B9. `build.ninja` (a build system used by Meson and others) is a perfect candid= ate due to its very simple syntax. So despite there being a `ninja-mode`, I= decided to create one based on SMIE and to possibly include it into upstre= am Emacs. Syntax showcase (barring that there's a few more keywords and `rule` only a= llows special variables): rule my_rule_title local_var_rule =3D some text command =3D cc -c $in -o $out global_var =3D some text build path/obj.o: my_rule_title path/obj.c local_var_build =3D some text Basically, `rule` and `build` accept a few parameters and have a body. The = body only allows variable assignments to appear and is characterized by non= -zero indentation level. So you can see `local_var_rule` is inside a `rule`= region, but `global_var` is outside it. ------------- I have spent some time studying other SMIE-based modes, reading documentati= on, and writing code. At this point I've monkey-typed something working, bu= t not really properly, and I think main reason is that I don't know if my g= rammar is correct (unlikely). My current grammar is attached at the bottom. So, here are questions I didn't find answers to: 1. Does a grammar have to cover complete buffer or only the interesting par= ts? To give an example: the `build.ninja` example above has `rule` and `buil= d` paragraphs. Obviously that means I have to write at least two SMIE rules= : one is to cover possible appearance of `rule` and another for `build`. Bu= t once that's done, do I also write a rule that connects the two on the lev= el of an entire buffer, i.e. to say "the buffer is expected to be composed = of `rule`s and `build`s"? Or having just the two is enough? 2. How do I define what symbols an identifier contains? For example a `buil= d` title may contain slashes and escaped spaces, but variable and `rule` na= mes are not allowed to have them. 3. How to define newline as a separator? E.g. a `build` ends with a newline= , and then follows a region of assignments. I tried using a `"\n"`, but I'm= not sure if SMIE interprets the backslash, nor that a `\n` will work with = other newline types. * sub-question: defining that a line is allowed to continue on the next = one if the previous line ended with a `$` (i.e. escapes the newline). I gue= ss if `"\n"` works, then I just have to create a separate rule for `"$\n"`.= But I decided to question that explicitly in case the answer to `3` is mor= e complicated than that. 4. How to define a non-zero space token, that is to define that the variabl= e assignment belongs to the previous `build` or `rule`? ------------- My last attempt is the grammar below. I had some other variants that worked= incorrectly, but they were incomplete as well. For this post I created a m= ore complete version, but it does not compile for me because it doesn't lik= e `text` definition, it throws `Adjacent non-terminals: id text`. (defvar test-mode-smie-grammar (smie-prec2->grammar (smie-bnf->prec2 '((id) (path) ;; TODO: define how it's different from `id' (statements (statement) (statement "\n" statements)) (statement (top_decls) (variable)) (text (id text) (text "\n")) (variable (id "=3D" text)) (build_title (path build_title) (path ":")) (top_decls ("rule" id) ("build" build_title ":" text) ) )))) 1: https://emacs.stackexchange.com/questions/20264/is-there-any-smie-docume= ntation-that-is-clear