nanopass-0.0.3.0: Create compilers using small passes and many intermediate representations.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Nanopass.Internal.Parser

Description

This module contains functions that translate Haskell quasiquotes into internal representations of languages and passes as defined in Nanopass.Internal.Representation. This is done by first parsing an s-expression with Text.SExpression, and then recursively recognizing the components of that s-expression.

The primary entry points are parseLanguage and TODO parsePass. Other recognizers are exported to serve as the promary source for documentation about the grammar used in these quasiquotes.

Synopsis

Recognizers

type ParseResult Source #

Arguments

 = Either (Language 'Unvalidated UpName) LangMod

modifications to a language

parseLanguage :: (Loc, String) -> Either Error ParseResult Source #

Language ::= <BaseLang> | <LangMod>

Base Languages

parseBaseLanguage :: String -> SExpr -> Either Error (Language 'Unvalidated UpName) Source #

BaseLang ::=
  (<LangLHS>        language name and type variables
      <string…>     documentation
      <Nonterm…>)   syntactic categories

parseNonterm :: SExpr -> Either Error (Nonterm 'Unvalidated) Source #

Nonterm ::=
  (<UpCase>             type name
      <string…>         documentation
      <Production…>)    constructor arguments

parseProduction :: SExpr -> Either Error (Production 'Unvalidated) Source #

Production ::=
  (<UpCase>        constructor name
      <string…>    documentation
      <Type…>)     constructor arguments

Language Modification

parseLangMod :: String -> SExpr -> Either Error LangMod Source #

LangMod ::=
  (<LangLHS>             new language name and type variables
        'from'           keyword
        <UpColon>        base language name
      <string…>          documentation
      <NontermsEdit…>)   changes to the base language's syntactic categories

parseNontermsEdit :: SExpr -> Either Error NontermsEdit Source #

NontermsEdit
  ::= ('+'                       add a syntactic category
          <UpCase>                 new non-terminal name
          <string…>                documentation
          <Production…>)           constructors
   |  ('-' <UpCase>)             remove a syntactic category by name
   |  ('*'                       modify a syntactic category's productions
          <UpCase name>            name of non-terminal to edit
          <ProductionsEdit…>)      changes to the base language's non-terminal

parseProductionsEdit :: SExpr -> Either Error ProductionsEdit Source #

ProductionsEdit
  ::= ('+'              add a production
          <UpCase>        new constructor name
          <string…>       documentation
          <Type…>)        constructor arguments
   |  ('-' <UpCase>)    remove a production by name

Shared Recognizers

parseLangLHS :: SExpr -> Either Error (UpName, [LowName]) Source #

LangLHS ::= <UpCase>                 language name, zero type variables
         |  (<UpCase> <LowCase…>)    language name, type variables

parseNontermBody :: UpName -> [SExpr] -> Either Error (Nonterm 'Unvalidated) Source #

Separated out from parseNonterm because it is useful in parseNontermsEdit as well.

parseProductionBody :: UpName -> [SExpr] -> Either Error (Production 'Unvalidated) Source #

Separated out from parseProduction because it is useful in parseProductionsEdit as well.

parseType :: SExpr -> Either Error (TypeDesc 'Unvalidated) Source #

Type ::= <lowCase name>                 type parameter
      |  <UpColonName>                  plain Haskell type (kind *)
                                        or non-terminal (language parameters already applied)
      |  (<UpColonName> <Type…>)        plain Haskell type application
      |  ('?' <Type>)                   Maybe type
      |  ('*' <Type>)                   List type
      |  ('+' <Type>)                   NonEmpty type
      |  () | ('&')                     unit type
      |  ('&' <Type>)                   Only type TODO
      |  ('&' <Type> <Type> <Type…>)    tuple types

Passes

parsePass :: (Loc, String) -> Either Error Pass Source #

Pass
  ::= ('from' <UpColonCase>    source lagnuage name
       'to' <UpColonCase>      target lagnuage name
         <string…>               documentation

S-Expressions

getSexpr :: (Loc, String) -> Either Error SExpr Source #

This serves as an adapter between Template Haskell and whatever s-expression parser I decide to use.

data Loc Source #

This is a location type that should be sufficient to describe the start of a Template Haskell quasiquote. It is used in getSexpr so that it can report errors from the actual source code location.

Constructors

Loc 

Fields

toUpColonName :: String -> Maybe UpDotName Source #

Since sexprs don't allow dot in names, we use colon instead. We just immediately translate it over into dots.

That is, accept strings matching [A-Z][a-zA-Z0-9_](:[A-Z][a-zA-Z0-9_])*, and alter them with s/\./:/.