On Wed, Jul 20, 2011 at 06:42:24AM +1200, Chris Cormack wrote:
> Hi
>
> Adding tests to xt/ to catch these would be awesome too, then it would stop
> more creeping in.
>
> I could add it as a step for jenkins, so if you wanted to share the parser
> that would be excellent, I have a koha-qa git repo we could add it to.
As said, the parser is in haskell language (exactly, ni literate haskell).
So before including in t/ , it should be refactoring (I have tried, but my
knowledge in perl is too bad, even for creating a simple stream parser).
The haskell parser is just a program which take on STDIN a file content, and
output:
- nothing : no problem found
- numbers separated by space : lines number where DIRECTIVE are found in TAG
- an error message in parentheses
For generate the log file, a used a couple of shell script (a wrapper around
'find', and a wrapper around the parser).
--
Frère Sébastien Marie
Abbaye Notre Dame de La Trappe
61380 Soligny-la-Trappe
Tél: 02.33.84.17.00
Fax: 02.33.34.98.57
Web: http://www.latrappe.fr/
This program is written in Literate Haskell.
All lines starting with '> ' are Haskell, others are comments.
Haskell is a lazy functional and pure language.
This program is not very optimized... it just work.
This program should be used as pipe:
- STDIN: template to check
- STDOUT:
- nothing: no problem found
- numbers separated by space : lines number where DIRECTIVE are found in TAG
- an error message in parentheses (generally when EOF in found inner not toplevel context)
First, the haskell module definition (mandatory).
> module Main where
Next, we create the entrypoint of the program: the 'main' funtion.
The function use 'interact' for interfacing with STDIN/STDOUT.
The argument of 'interact' is a function which take a list of Char (type String) and return a list of Char.
We start in the INITIAL context, with line number set to 1
> main :: IO ()
> main = interact $ inINITIALContext 1
All the context have the form:
an Integer argument : the line number position
a list of Char (the String) : the current position of STDIN
and return
a list of Char (type String) : STDOUT output
Functions are composed of:
- function signature (not mandatory [else infered], but good practice)
- the body, using Pattern Matching
In the INITIAL context:
- increment 'line' on newline
- if start with '<!--', go in COMMENT context
- if start with '<![CDATA[', go in CDATA context
- if start with '<', go in TAG context
- else, discard char
- EOF in INITIAL: so end
> inINITIALContext :: Integer -> String -> String
> inINITIALContext line ('\n':xs) = inINITIALContext (line+1) xs
> inINITIALContext line ('<':'!':'-':'-':xs) = inCOMMENTContext line xs
> inINITIALContext line ('<':'!':'[':'C':'D':'A':'T':'A':'[':xs) = inCDATAContext line xs
> inINITIALContext line ('<':xs) = inTAGContext line xs
> inINITIALContext line (_x:xs) = inINITIALContext line xs
> inINITIALContext _line [] = ""
In the COMMENT context:
- increment 'line' on newline
- go in INITIAL at end of comment '-->'
- discard char else
- EOF in COMMENT
> inCOMMENTContext :: Integer -> String -> String
> inCOMMENTContext line ('\n':xs) = inCOMMENTContext (line+1) xs
> inCOMMENTContext line ('-':'-':'>':xs) = inINITIALContext line xs
> inCOMMENTContext line (_x:xs) = inCOMMENTContext line xs
> inCOMMENTContext _line [] = "(EOF in COMMENT)"
In the CDATA context:
- increment 'line' on newline
- go in INITIAL at end of cdata ']]>'
- discard char else
- EOF in CDATA
> inCDATAContext :: Integer -> String -> String
> inCDATAContext line ('\n':xs) = inCDATAContext (line+1) xs
> inCDATAContext line (']':']':'>':xs) = inINITIALContext line xs
> inCDATAContext line (_xs:xs) = inCDATAContext line xs
> inCDATAContext _line [] = "(EOF in CDATA)"
In the TAG context:
- increment 'line' on newline
- go in STRING if '"' found
- go back in INITIAL if '>'
- found a DIRECTIVE TEMPLATE in TAG if '[%': output the line (with conversion Integer -> String using 'show'), append space, append the rest (keep in TAG context, continue parsing)
- EOF in TAG
> inTAGContext :: Integer -> String -> String
> inTAGContext line ('\n':xs) = inTAGContext (line+1) xs
> inTAGContext line ('"':xs) = inSTRINGContext line xs
> inTAGContext line ('>':xs) = inINITIALContext line xs
> inTAGContext line ('[':'%':xs) = show line ++ " " ++ inTAGContext line xs
> inTAGContext line (_x:xs) = inTAGContext line xs
> inTAGContext _line [] = "(EOF in TAG)"
In the STRING context:
- increment 'line' on newline
- skip \" (keep STRING context)
- go in TAG context at end of string
- discard else
- EOF in STRING context
> inSTRINGContext :: Integer -> String -> String
> inSTRINGContext line ('\n':xs) = inSTRINGContext (line+1) xs
> inSTRINGContext line ('\\':'"':xs) = inSTRINGContext line xs
> inSTRINGContext line ('"':xs) = inTAGContext line xs
> inSTRINGContext line (_x:xs) = inSTRINGContext line xs
> inSTRINGContext _line [] = "(EOF in STRING)"
_______________________________________________
Koha-devel mailing list
[email protected]
http://lists.koha-community.org/cgi-bin/mailman/listinfo/koha-devel
website : http://www.koha-community.org/
git : http://git.koha-community.org/
bugs : http://bugs.koha-community.org/