25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Expr : let VAR ’=’ Expr in Expr { App (Lam $2 $6) $4 }<br />

| ’\\’ VAR ’->’ Expr { Lam $2 $4 }<br />

| Form { $1 }<br />

Form : Form ’+’ Form { Op Add $1 $3 }<br />

| Form ’-’ Form { Op Sub $1 $3 }<br />

| Form ’*’ Form { Op Mul $1 $3 }<br />

| Fact { $1 }<br />

Fact : Fact Atom { App $1 $2 }<br />

| Atom { $1 }<br />

Atom : ’(’ Expr ’)’ { $2 }<br />

| NUM { Lit (LInt $1) }<br />

| VAR { Var $1 }<br />

| true { Lit (LBool True) }<br />

| false { Lit (LBool True) }<br />

Syntax Errors<br />

Parsec’s default error reporting leaves a bit to be desired, but does in fact contain most of the information<br />

needed to deliver better messages packed inside the ParseError structure.<br />

showSyntaxError :: L.Text -> ParseError -> String<br />

showSyntaxError s err = L.unpack $ L.unlines [<br />

” ”,<br />

” ” lineContents,<br />

” ” ((L.replicate col ” ”) ”^”),<br />

(L.pack $ show err)<br />

]<br />

where<br />

lineContents = (L.lines s) !! line<br />

pos = errorPos err<br />

line = sourceLine pos - 1<br />

col = fromIntegral $ sourceColumn pos - 1<br />

Now when we enter an invalid expression the error reporting will point us directly to the adjacent lexeme<br />

that caused the problem as is common in many languages.<br />

> \x -> x +<br />

\x -> x +<br />

^<br />

”” (line 1, column 11):<br />

unexpected end of input<br />

expecting ”(”, character, literal string, ”[”, integer, ”if” or identifier<br />

133

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!