Skip to content

Instantly share code, notes, and snippets.

@Araq
Created January 17, 2019 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Araq/daf3e6aa4dde850bfe9cddcb7e0edee7 to your computer and use it in GitHub Desktop.
Save Araq/daf3e6aa4dde850bfe9cddcb7e0edee7 to your computer and use it in GitHub Desktop.
# The 'lexer' macro generates not only the lexing proc but also
# the relevant 'Token' type, including a TokenKind enum that is
# extracted from the actions via the 'token Kind()' syntax.
# There are two special TokenKind values always available:
# Error and Eof.
# '_' refers to the matched string.
lexer:
"[A-Za-z][A-Za-z0-9]*":
# 'keywords' is a special construct. We want to map the pattern
# to the 'Identifier' token kind, unless it is a keyword. Every
# keyword is mapped to its own TokenKind enum value.
keywords("""
if else for while case of
""", token Identifier(_))
"[0-9]+": token Float(_)
",": token Comma()
"+": token Plus()
"{.": token PragmaLe()
".}": token PragmaRi()
"{": token CurlyLe()
"}": token CurlyRi()
".*": token SomethingElse(_)
# Likewise the 'parser' macro generates a 'Tree' type, including a
# NodeKind enum that is extracted from the actions via
# the 'node Kind(...)' syntax.
# There is one special NodeKind value always available: Error.
# it[i] refers to the i-th parsed subtree. 'it' refers to all parsed
# subtree as a seq, '_' to the current token.
parser:
expr "expr ParLe expr *^ Comma ParRi":
# 'a *^ sep' is a shortcut for (a (sep a)*)?
node Call(it)
expr "Identifier":
node Ident(_)
expr "expr Plus expr":
node Add(it)
stmt "expr":
discard "every expression is a statement"
stmt "If expr Colon expr Else expr":
node IfStmt(it)
stmt "PragmaLe stmt (CurlyRi|PragmaRi)":
# There is no 'or' operator beyond "token or" because it is not
# clear what parse tree to attach to an 'or'.
node Pragma(it[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment