Skip to content

Instantly share code, notes, and snippets.

@smpallen99
Created October 17, 2015 16:22
Show Gist options
  • Save smpallen99/fa022283fc491ea4d211 to your computer and use it in GitHub Desktop.
Save smpallen99/fa022283fc491ea4d211 to your computer and use it in GitHub Desktop.
Parsing Elixir with leex and yecc
iex(13)> :leex.file('list_lexer.xrl') ; c("list_lexer.erl")
[:list_lexer]
iex(14)> source = "[one: 1, two: 2, :three, 4]"
"[one: 1, two: 2, :three, 4]"
iex(15)> {:ok, tokens, _} = source |> String.to_char_list |> :list_lexer.string
{:ok,
[{:"[", 1}, {:key, 1, :one}, {:int, 1, 1}, {:",", 1}, {:key, 1, :two},
{:int, 1, 2}, {:",", 1}, {:atom, 1, :three}, {:",", 1}, {:int, 1, 4},
{:"]", 1}], 1}
iex(16)> c("helpers.ex")
helpers.ex:1: warning: redefining module Helpers
[Helpers]
iex(17)> r Helpers
helpers.ex:1: warning: redefining module Helpers
{:reloaded, Helpers, [Helpers]}
iex(18)> :yecc.file('list_parser.yrl');c("list_parser.erl")
[:list_parser]
iex(19)> :list_parser.parse(tokens)
{:ok, [{:one, 1}, {:two, 2}, :three, 4]}
defmodule Helpers do
def extract_token({_token, _line, value}), do: value
def to_atom(':' ++ atom), do: List.to_atom(atom)
end
Definitions.
INT = [0-9]+
ATOM = :[a-z_]+
WHITESPACE = [\s\t\n\r]
Rules.
{INT} : {token, {int, TokenLine, list_to_integer(TokenChars)}}.
{ATOM} : {token, {atom, TokenLine, to_atom(TokenChars)}}.
[a-z_]+: : {token, {key, TokenLine, list_to_atom(lists:sublist(TokenChars, 1, TokenLen - 1))}}.
\[ : {token, {'[', TokenLine}}.
\] : {token, {']', TokenLine}}.
, : {token, {',', TokenLine}}.
{WHITESPACE}+ : skip_token.
Erlang code.
to_atom(Atom) ->
'Elixir.Helpers':to_atom(Atom).
Nonterminals list elems elem key_elem.
Terminals '[' ']' ',' int atom key.
Rootsymbol list.
list -> '[' ']' : [].
list -> '[' elems ']' : '$2'.
key_elem -> elem elem : {'$1', '$2'}.
elems -> elem : ['$1'].
elems -> key_elem : ['$1'].
elems -> key_elem ',' elems : ['$1'|'$3'].
elems -> elem ',' elems : ['$1'|'$3'].
elem -> int : 'Elixir.Helpers':extract_token('$1').
elem -> atom : 'Elixir.Helpers':extract_token('$1').
elem -> key : 'Elixir.Helpers':extract_token('$1').
elem -> list : '$1'.
Erlang code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment