I have two languages (A and B). My goal is to write a program that changes the syntax equivalent to one in B. Currently my solution has been to use Haskell's Parsac to perform this task. As a person who is new to Haskell and there is functional programming for that matter, however, Parssey is hard to find only a simple example. The examples I have found on the web are either incomplete examples (disappointment for new Haskell programmers) or have been removed too much from my goal
So, did anyone have a surprisingly slight to use parssey? And can provide specific examples? Or maybe some tutorials that explain my goal equally.
Thanks
Consider the following simple grammar of a CSV document (in ABNF ):
csv = * Crow Crow = * (ccell ',') ccell cccel = "'" * (alpha / digit) "'" < P> We want to write a converter that converts this grammar into a TSV (tabular-separated value) document: tsv = * trow trow = * (tcell HTAB) tcell CR tcell = DQUOTE * (alpha / digit) duquite First of all, let's get an algebraic data Make Rkar which describes our abstract syntax tree. Understand synonyms synonyms:
data for XSV = [row] type line = [cell] type cell = string A parser for this Writing grammar is very simple We write a parser, as if we would describe ABNF:
csv :: Parser XSV csv = XSV & lt; $ & Gt; Many Crow Crow :: Parser Row Crow = Cells & lt; - ccell `sepBy` (four ',') newline return cells ccell :: parser cell ccell = do char '\' 'content & lt; - Many (digits> | 'return content') this parser do - uses a After , the order of the statements is as follows. For parrs, these statements are only other parsers. To bind the result of any parser, & lt; - In this way, chains of many small parsers make a big parser. To get interesting effects, a special combination (such as a | b , which either parses a or b Does it) or too many , which reads as much as possible a s) Please keep in mind that Parsec defaults to background does not do. If a parser fails after taking the character, give it a prefix with try to enable back tracking for an example try slow parsing. The result is a parser csv which parses our CSV document in an abstract syntax tree. Now it's easy to convert it to another language (such as TSV): xsvToTSV :: XSV -> The string xsvToTSV xst = unlines (to map toLines xst) where toLines = intersperse '\ t' Adding both of these things becomes a conversion function:
< Code> csvToTSV :: string - & gt; Probably string csvToTSV document = case pars CSV "" Left _ document - & gt; Nothing is right xsv - & gt; XsvToTSV xsv And all this is! There are several other functions of Parssey to create highly sophisticated parsons. There is a good lesson about parsing in the book, but it is a little old, though most of it still is true, though. If you have more questions, do not hesitate to ask.
Comments
Post a Comment