<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>In C, AFAIU you can (and probably should) defer `typedef` usage
      recognition to a separate "renamer/ name resolution" pass. In
      Haskell we are forced to do name resolution after parsing, as we
      don't need to declare stuff before use. Even so, separate pass is
      usually a good idea anyway, you are better equipped to produce
      good error messages. In fact GHC does even more: it defers the
      unbound names reporting to the type checking phase, so it can give
      the types to unbound variables, like:<br>
      <br>
          Prelude> x : "foo"<br>
          <interactive>:2:1: error: Variable not in scope: x ::
      Char<br>
      <br>
      - Oleg<br>
    </p>
    <div class="moz-cite-prefix">On 1.11.2023 2.32, Brandon Allbery
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAKFCL4Vy7sgY=y-fz4v22i2Zm0CrbpwfZeAKyzHke=eczDkLkQ@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">Feedback between lexer and parser isn't exactly
        unusual. Consider that parsing a C `typedef` generally needs to
        feed back to the lexer so uses will be recognized properly.</div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, Nov 1, 2023 at
          12:28 AM Oleg Grenrus <<a href="mailto:oleg.grenrus@iki.fi"
            moz-do-not-send="true" class="moz-txt-link-freetext">oleg.grenrus@iki.fi</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div> Yes, the "communication between lexer and parser" is
            exactly what GHC does.<br>
            <br>
            Amelia has a nice post about it <a
              href="https://amelia.how/posts/parsing-layout.html"
              target="_blank" moz-do-not-send="true"
              class="moz-txt-link-freetext">https://amelia.how/posts/parsing-layout.html</a>
            which made it click it for me.<br>
            <br>
            Note, you don't actually need to use alex and happy, you can
            do hand-written lexer and parsec (or alex and parsec, ...).
            The key insight is to have stateful lexer, and control it
            from the parser.<br>
            <br>
            Amelia's post grammar is a bit too strict, e.g. GHC accepts
            real semis in virtual layout, and also empty "statements" in
            between, so we can write<br>
            <br>
               \x y z -> case x of True -> y;;;;;; False -> z<br>
            <br>
            but that's easy (at least in parsec) to adjust the parser
            grammar to accept those.<br>
            <p>Or, you can *approximate* the parse-error rule with
              "alternative layout rule" [1], which can be implemented as
              a pass between lexing and parsing, or as a stateful lexer
              (but in this case parser won't need to adjust lexer's
              state). GHC has an undocumented AlternativeLayoutRule
              extension, so you can experiment with it to see what it
              accepts (look for tests in GHC source for examples). It
              handles let-in bindings well enough.<br>
              <br>
              [1] <a
href="https://www.mail-archive.com/haskell-prime@haskell.org/msg01938.html"
                target="_blank" moz-do-not-send="true"
                class="moz-txt-link-freetext">https://www.mail-archive.com/haskell-prime@haskell.org/msg01938.html</a>
              which can be imp<br>
              <br>
              - Oleg<br>
              <br>
            </p>
            On 1.11.2023 0.31, Travis Athougies wrote:<br>
            <blockquote type="cite">According to the Haskell report [1]
              (See Note 5), a virtual `}` token<br>
              is inserted if parsing the next token would cause a parse
              error and the<br>
              indentation stack is non-empty.<br>
              <br>
              I'm trying to lex and parse Haskell source and this sort
              of interplay<br>
              (which requires two-way communication between lexer and
              parser) makes<br>
              it very difficult to write a conformant implementation.<br>
              <br>
              I can't change the standard (obviously), but I'm wondering
              if this is<br>
              actually what GHC (de facto the only Haskell compiler)
              does, or if it<br>
              applies some other rule. If so, does anyone know the exact
              mechanism of<br>
              its implementation?<br>
              <br>
              I've been programming Haskell for more than a decade, and
              while I have<br>
              an intuitive understanding of the indentation rules, I
              would have<br>
              assumed the source could be lexed without also having a
              parser. In<br>
              particular, the note seems to imply that the main purpose
              of this is to<br>
              properly lex `let`/`in` bindings. Perhaps there's an
              alternate<br>
              equivalent rule?<br>
              <br>
              Curious to hear other's thoughts.<br>
              <br>
              Travis<br>
              <br>
              [1]<br>
              <a
href="https://www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17800010.3"
                target="_blank" moz-do-not-send="true"
                class="moz-txt-link-freetext">https://www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17800010.3</a><br>
            </blockquote>
            <span style="white-space:pre-wrap;display:block;width:98vw">> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a>
> Only members subscribed via the mailman list are allowed to post.
</span><br>
          </div>
          _______________________________________________<br>
          Haskell-Cafe mailing list<br>
          To (un)subscribe, modify options or view archives go to:<br>
          <a
            href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe"
            rel="noreferrer" target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
          Only members subscribed via the mailman list are allowed to
          post.</blockquote>
      </div>
      <br clear="all">
      <div><br>
      </div>
      <span class="gmail_signature_prefix">-- </span><br>
      <div dir="ltr" class="gmail_signature">
        <div dir="ltr">
          <div>
            <div dir="ltr">
              <div>brandon s allbery kf8nh</div>
              <div><a href="mailto:allbery.b@gmail.com" target="_blank"
                  moz-do-not-send="true" class="moz-txt-link-freetext">allbery.b@gmail.com</a></div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>