<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.E-MailFormatvorlage17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Hi Yclept.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>> That is ambiguous concatenation - I removed "(store Rx.word)?" for clarity.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Well, like I said, it was untested. Though this expression does pass the tests imposed by augparse:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>let match = [ Util.del_opt_ws "" . key Rx.word . Sep.space_equal . (store Rx.word)? . Util.comment_noindent? ]<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Yet I feel like you actually wanted to point out something different with your mail from the start and I cannot comment on that (I'm merely a subscriber to this list and not an Augeas developer).<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Best regards,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Xavier.<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><div style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=DE style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span lang=DE style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Yclept Nemo [mailto:orbisvicis@gmail.com] <br><b>Sent:</b> Saturday, October 31, 2015 6:14 PM<br><b>To:</b> Mol, Xavier (SCC)<br><b>Cc:</b> augeas-devel<br><b>Subject:</b> Re: [augeas-devel] Matching key/value statement<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>On Fri, Oct 30, 2015 at 4:13 AM, Mol, Xavier (SCC) <<a href="mailto:xavier.mol@kit.edu">xavier.mol@kit.edu</a>> wrote:<br>> let match = [ Util.del_opt_ws . key  Rx.word . Sep.space_equal . (store Rx.word)? . Util.comment_or_eol ]<br>><br>> I haven't tested this, since you did not give a real word example either, so try it for yourself.<br><br>Hi,<br><br>    let match = [ Util.del_opt_ws "" . key  Rx.word . Sep.space_equal . Util.comment_or_eol ]<br><br>That is ambiguous concatenation - I removed "(store Rx.word)?" for clarity.<br><br>In the put direction augeas differentiates lenses using child nodes, and nodes using key/value properties. This isn't documented and caused me lots of grief. For example<br>    lenses, ambiguous:      [ (del "a" "a") | (del "b" "b") ]<br>    lenses, unambiguous:    [ (del "a" "a") | (del "b" "b" . [ label "bleh" ]) ]<br>    nodes, ambiguous:       [ label "a" . store /a/ ] | [ label "a" . store /a/ . del / / " " ]<br>    nodes, unambiguous:     [ label "a" . store /a/ ] | ([ label "a" . store /a/ . del / / " " ] . [ label "bleh" ])<br>    nodes, unambiguous:     [ label "a" . store /a/ ] | [ label "a" . del / / " " ]<br>This isn't some theoretical limitation, but a shortcoming of augeas.<br><br>In the above examples, creating null placeholder nodes renders lenses unusable in the put direction [1], but unnecessary for this particular problem. The solution - move the node ambiguities to the lens level, and the lens ambiguities to the node level.<br><br>These equivalent statements are both ambiguous:<br>    Node-level ambiguities:<br>    let record  = [ key . spaces? . equal . spaces? ]<br>                | [ key . spaces? . equal . spaces? . comment ]<br>                | [ key . spaces? . equal . spaces? . value ]<br>                | [ key . spaces? . equal . spaces? . value . spaces? . comment ]<br><br>    Lens-level ambiguities:<br>    let record  = [ key . spaces? . equal . spaces? . (comment | value | (value . spaces? . comment))?<br><br>Merge the node-level ambiguities to create a lens without ambiguities:<br>    let record  = [ key . spaces? . equal . spaces? . comment? ]<br>                | [ key . spaces? . equal . spaces? . value . (spaces . comment)? ] <br><br>Note the flattened equivalent still has lens-level ambiguities:<br>    let record  = [ key . spaces? . equal . spaces? . (comment? | value . (spaces? . comment)?)<br><br>Anyway, the non-ambiguous version can be made easier to use via a constructor, and the default valueless placeholder changed from "key = " to "key =":<br>    let spaces              = /[ \t]+/ " "<br>    let spaces_none         = del /[ \t]*/ ""<br>    let recorder<br>        (prefix:lens)       =<br>        let template<br>            (suffix:lens)   = [ prefix . key . spaces? . equal . suffix ] in<br>        let suffix_empty    = spaces_none | (spaces? . comment) in<br>        let suffix_value    = spaces? . value . (spaces? . comment)? in<br>        let records         = template suffix_empty | template suffix_value in<br>        records<br><br>But the version I want is actually:<br>    let record  = [ key . spaces? . equal . spaces_none ]<br>                | [ key . spaces? . equal . spaces? . comment ]<br>                | [ key . spaces? . equal . spaces? . value . spaces_none ]<br>                | [ key . spaces? . equal . spaces? . value . spaces? . comment ]<br><br>Which simplifies to:<br>    let record  = [ key . spaces? . equal . (spaces_none | (spaces? . comment)) ]<br>                | [ key . spaces? . equal . spaces? . value (spaces_none | (spaces? . comment)) ]<br><br>And then, nicely without ambiguities, to:<br>    let record  = [ key . spaces? . equal . (spaces? . value)? . (spaces_none | (spaces? . comment) ]<br><br>I'm going to update my ConfigObj lenses soon with functional examples.<br><br>Sincerely,<br><br>[1] @augeas-devs: placeholder nodes that are ignored in the put direction would be *extremely* useful. Drawing inspiration from perl regexes, perhaps using modifier syntax such as "[?>lens]".<o:p></o:p></p></div></div></div></body></html>