git @ Cat's Eye Technologies Sbeezg / master src / sbeezg_parser.yrl
master

Tree @master (Download .tar.gz)

sbeezg_parser.yrl @masterraw · history · blame

%%% -grammar(sbeezg_parser).
%%% -vsn('2002.0317').
%%% -author('cpressey@gmail.com').
%%% -copyright('This work is in the public domain; see UNLICENSE for more info').

%%% BEGIN sbeezg_parser.yrl %%%

Nonterminals vlist val nlist name alist appl.
Terminals '=' '*' '(' ')' '{' '|' '}' ',' ';' atom integer.
Rootsymbol alist.

%%% EBNF:
%%% Appl ::= Name "=" Val "(" Val  {"," Val} ")".
%%% Val  ::= Name | "*" Const | "{" Name {"," Name} "|" Appl {";" Appl} "|" Name "}".

%%% Recursive Version (no {}'s):
%%% Appl  ::= Name "=" Val ["(" Vlist ")"].
%%% Vlist ::= Val ["," Vlist].
%%% Val   ::= Name | "*" Name | "{" Nlist "|" Alist "|" Name "}".
%%% Nlist ::= Name ["," Nlist].
%%% Alist ::= Appl [";" Alist].

appl  -> name '=' val '(' vlist ')'       : new_name('$1'), {assign, '$1', '$3', '$5'}.
appl  -> name '=' val                     : new_name('$1'), {assign, '$1', '$3'}.
vlist -> val ',' vlist                    : {vlist, '$1', '$3'}.
vlist -> val                              : {vlist, '$1', nil}.
val   -> '{' nlist '|' alist '|' name '}' : {lambda, '$2', '$4', '$6'}.
val   -> '*' atom                         : {lit, '$2'}.
val   -> integer                          : {lit, '$1'}.
val   -> name                             : existing_name('$1'), '$1'.
nlist -> name ',' nlist                   : new_name('$1'), {nlist, '$1', '$3'}.
nlist -> name                             : new_name('$1'), {nlist, '$1', nil}.
alist -> appl ';' alist                   : {alist, '$1', '$3'}.
alist -> appl                             : {alist, '$1', nil}.
name  -> atom                             : {name, '$1'}.

Erlang code.

new_name({name,{atom,Line,Name}}=A) ->
  case get(A) of
    defn ->
      return_error(0, io_lib:format("Name '~w' already defined", [Name]));
    _ ->
      put(A, defn)
  end.

existing_name({name,{atom,Line,Name}}=A) ->
  case get(A) of
    undefined ->
      return_error(0, io_lib:format("Name '~w' is not yet defined", [Name]));
    _ ->
      ok
  end.

%%% END of sbeezg_parser.yrl %%%