If you dig deeper you have two alternatives:<div><br></div><div>1) learn yecc (it's like bison/yacc etc.) Yacc grammers are</div><div>    easy (ish) to read (one you understand the syntax) but difficult  </div><div>   to debug if you get  them wrong.</div>
<div><br></div><div>2) Search for an EBNF/BNF/Peg grammar from Erlang</div><div><br></div><div>Of the two 1) is the quickest alternative. I have never ever seen</div><div>a complete type 2) grammar for Erlang - subsets yes - complete grammars no. It would take a considerable amount of work to</div>
<div>make a type 2) grammar for Erlang and even if you found one you would never know if the grammar described the same language</div><div>as a type 1) grammar - equivalence of grammars is undecidable</div><div>in general.</div>
<div><br></div><div>If you want to play with the parser the following function is</div><div>useful:</div><div><br></div><div><div>string2exprs(Str) -></div><div>    case erl_scan:tokens([], Str ++ ". ", 1) of</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>{done, {ok, Toks, _}, []} -></div><div><span class="Apple-tab-span" style="white-space:pre">      </span>    case erl_parse:parse_exprs(Toks) of</div><div><span class="Apple-tab-span" style="white-space:pre">              </span>{ok, Exprs} -></div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>    {ok, Exprs};</div><div><span class="Apple-tab-span" style="white-space:pre">             </span>{error,{Line,Mod,Arg}} -></div><div><span class="Apple-tab-span" style="white-space:pre">         </span>    EStr = io_lib:format("~s",[apply(Mod,format_error,[Arg])]),</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>    Msg = lists:flatten(EStr),</div><div><span class="Apple-tab-span" style="white-space:pre">               </span>    io:format("~n***PARSE ERROR in line:~w ~s~n", [Line,Msg]),</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>    io:format("Str=~s~n",[Str]),</div><div><span class="Apple-tab-span" style="white-space:pre">           </span>    error</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>    end;</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>Other -></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>    io:format("~n***SCAN ERROR:~p~n", [Other]),</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>    error</div>
<div>    end.</div></div><div><br></div><div>This is a very simple interface to the generated parser. So for example, if you add this to the module mymod you can run it like this:</div><div><br></div><div><div>> mymod:string2exprs("case foo(X) of 1 -> sqrt(Y) end"). </div>
<div>{ok,[{'case',1,</div><div>             {call,1,{atom,1,foo},[{var,1,'X'}]},</div><div>             [{clause,1,</div><div>                      [{integer,1,1}],</div><div>                      [],</div>
<div>                      [{call,1,{atom,1,sqrt},[{var,1,'Y'}]}]}]}]}</div></div><div><br></div><div>If you read the above code you'll see how to get from the</div><div>world of strings to tokens using erl_scan:tokens, and from tokens</div>
<div>to parse trees using erl_parse:parse_exprs.</div><div><br></div><div>the module erl_parse is automatically generated from the grammar.</div><div><br></div><div>The above term is generated by the mysterious right hand sides following the colons in the productions:</div>
<div><br></div><div>The appropriate line in the grammar that did this was lines</div><div>378-380 ie.</div><div><br></div><div><pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace; font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; line-height: 1.4; background-color: rgb(255, 255, 255); ">
<div class="line" id="LC379" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; background-color: transparent; ">
case_expr -> 'case' expr 'of' cr_clauses 'end' :</div><div class="line" id="LC380" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 1em; background-color: transparent; ">
        {'case',?line('$1'),'$2','$4'}.</div></pre></div><div><br></div><div>Have fun</div><div><br></div><div>/Joe</div><div>  </div><br><div class="gmail_quote">On Fri, Nov 11, 2011 at 9:56 PM, Ryan Molden <span dir="ltr"><<a href="mailto:ryanmolden@gmail.com">ryanmolden@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div>Great, thanks I will give the YRL a shot (ignoring 'everything to the right of the ':' may really be all that is needed, it wasn't clear to me if that was somehow essentially in expressing what the YRL was trying to represent).</div>

<div> </div><font color="#888888"><div>Ryan<br><br></div></font><div><div></div><div class="h5"><div class="gmail_quote">On Fri, Nov 11, 2011 at 12:38 PM, Joe Armstrong <span dir="ltr"><<a href="mailto:erlang@gmail.com" target="_blank">erlang@gmail.com</a>></span> wrote:<br>
<blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204, 204, 204);border-left-width:1px;border-left-style:solid" class="gmail_quote">
I don't think there are any BNF/EBNF grammars for erlang<div>there might be grammars for subsets of the language but not the</div><div>entire language.  The problem with NBF/EBNF/PEG grammars</div><div>is that decent error reporting is very difficult. In practice</div>


<div>virtual all languages use hand written recursive descent parsers</div><div>or LALR(1) parsers for which acceptable error recovery strategies exist.</div><div><br></div><div>The official grammar is: (official means this is the actual grammar used by the erlang compiler and all tools) </div>


<div><br></div><div><a href="https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_parse.yrl" target="_blank">https://github.com/erlang/otp/blob/master/lib/stdlib/src/erl_parse.yrl</a><br><br></div><div>It you look at the productions they are very similar to yacc</div>


<div>productions:</div><div><br></div><div>For example a tuple is defined like this (line 330,331)</div><div><br></div><div><pre style="padding:0px;line-height:1.4;font-family:"Bitstream Vera Sans Mono", Courier, monospace;font-size:12px;margin-top:0px;margin-bottom:0px;background-color:rgb(255, 255, 255)">
<div style="margin:0px;padding:0px 0px 0px 1em">tuple -> '{' '}'       : {tuple,?line('$1'),[]}.</div>
<div style="margin:0px;padding:0px 0px 0px 1em">tuple -> '{' exprs '}' : {tuple,?line('$1'),'$2'}.</div>
<div><br></div><div>If you forget about the stuff after the ':' this</div><div>reads</div><div><br></div><div>   tuple -> '{' '}'</div><div>   tuple -> {' exprs '}'</div><div><br>


</div><div>ie a tuple is either {} or { exprs }</div><div><br></div><div>The part after the ':' define the parse tree that</div><div>is returned if the expression is recognised.</div><div><br></div><div>A production like:</div>


<div><br></div><div>a -> b c d : {something, '$2'}</div><div><br></div><div>means is we match an 'a' then the parse</div><div>tree we want returned is {something, '$2'}</div><div><br></div><div>


'$1' is the parse tree of b, '$2' is the parse tree </div><div>of c etc.</div><div><br></div><div>and exprs (line 445/446) is defined</div><div><br></div><div><pre style="padding:0px;line-height:1.4;font-family:"Bitstream Vera Sans Mono", Courier, monospace;margin-top:0px;margin-bottom:0px">
<div style="margin:0px;padding:0px 0px 0px 1em">exprs -> expr           : ['$1'].</div>
<div style="margin:0px;padding:0px 0px 0px 1em">exprs -> expr ',' exprs : ['$1' | '$3'].</div>
</pre></div><div><br></div><div>ie exprs is an expr or a comma separated</div><div>sequence of expr's</div><div><br></div><div>In the original yacc this would be written</div><div>something like</div><div><br></div><div>


exprs: expr           {$$ = $1}</div><div>     | expr ',' exprs {$$ = [$1|$3]}</div><div><br></div><div>The yecc manual is at <a href="http://www.erlang.org/doc/man/yecc.html" target="_blank">http://www.erlang.org/doc/man/yecc.html</a></div>


<div><br></div><div>the command</div><div><br></div><div>> erlc erlang.yecc</div><div><br></div><div>compiles the grammar into a beam file</div><div><br></div><div>Cheers</div><div><br></div><font color="#888888"><div>

/Joe</div><div><br></div>
<div><br></div><div><br></div><div><br></div></font></pre></div><div><div class="gmail_quote"><div>On Fri, Nov 11, 2011 at 5:08 PM, Ryan Molden <span dir="ltr"><<a href="mailto:ryanmolden@gmail.com" target="_blank">ryanmolden@gmail.com</a>></span> wrote:<br>


</div><blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204, 204, 204);border-left-width:1px;border-left-style:solid" class="gmail_quote"><div>Howdy fellow Erlangeers.  I was wondering if anyone knew of a BNF/EBNF grammar for Erlang?  Joe Armstrong pointed me at the YRL grammar at github; unfortunately, I am YRL illiterate so it looked mostly like gibberish to me.<div>



<br></div><font color="#888888"><div>Ryan</div>
</font><br></div><div>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></div></blockquote></div><br></div>
</blockquote></div><br>
</div></div></blockquote></div><br>