    {- This module was generated from data in the Kate syntax highlighting file sql-mysql.xml, version 1.09,
       by  Shane Wright (me@shanewright.co.uk) -}

    module Text.Highlighting.Kate.Syntax.SqlMysql ( highlight, parseExpression, syntaxName, syntaxExtensions ) where
    import Text.Highlighting.Kate.Definitions
    import Text.Highlighting.Kate.Common
    import Text.ParserCombinators.Parsec
    import Data.List (nub)
    import Data.Map (fromList)
    import Data.Maybe (fromMaybe)

    -- | Full name of language.
    syntaxName :: String
    syntaxName = "SQL (MySQL)"

    -- | Filename extensions for this language.
    syntaxExtensions :: String
    syntaxExtensions = "*.sql;*.SQL"

    -- | Highlight source code using this syntax definition.
    highlight :: String -> Either String [SourceLine]
    highlight input =
      case runParser parseSource startingState "source" input of
        Left err     -> Left $ show err
        Right result -> Right result

    -- | Parse an expression using appropriate local context.
    parseExpression :: GenParser Char SyntaxState LabeledSource
    parseExpression = do
      st <- getState
      let oldLang = synStLanguage st
      setState $ st { synStLanguage = "SQL (MySQL)" }
      context <- currentContext <|> (pushContext "Normal" >> currentContext)
      result <- parseRules context
      updateState $ \st -> st { synStLanguage = oldLang }
      return result

    parseSource = do
      lineContents <- lookAhead wholeLine
      updateState $ \st -> st { synStCurrentLine = lineContents }
      result <- manyTill parseSourceLine eof
      return $ map normalizeHighlighting result

    startingState = SyntaxState {synStContexts = fromList [("SQL (MySQL)",["Normal"])], synStLanguage = "SQL (MySQL)", synStCurrentLine = "", synStCharsParsedInLine = 0, synStCaseSensitive = False, synStKeywordCaseSensitive = False, synStCaptures = []}

    parseSourceLine = manyTill parseExpressionInternal pEndLine

    pEndLine = do
      newline <|> (eof >> return '\n')
      context <- currentContext
      case context of
        "Normal" -> return ()
        "String" -> return ()
        "String2" -> return ()
        "Name" -> return ()
        "SingleLineComment" -> (popContext >> return ())
        "MultiLineComment" -> return ()
        "Preprocessor" -> (popContext >> return ())
        _ -> return ()
      lineContents <- lookAhead wholeLine
      updateState $ \st -> st { synStCurrentLine = lineContents, synStCharsParsedInLine = 0 }

    withAttribute attr txt = do
      if null txt
         then fail "Parser matched no text"
         else return ()
      let style = fromMaybe "" $ lookup attr styles
      st <- getState
      let oldCharsParsed = synStCharsParsedInLine st
      updateState $ \st -> st { synStCharsParsedInLine = oldCharsParsed + length txt }
      return (nub [style, attr], txt)

    styles = [("Normal Text","Normal"),("Keyword","Keyword"),("Operator","Normal"),("Function","Function"),("Data Type","DataType"),("Decimal","DecVal"),("Float","Float"),("String","String"),("Name","String"),("String Char","Char"),("Comment","Comment"),("Symbol","Char"),("Preprocessor","Others")]

    parseExpressionInternal = do
      context <- currentContext
      parseRules context <|> (pDefault >>= withAttribute (fromMaybe "" $ lookup context defaultAttributes))

    defaultAttributes = [("Normal","Normal Text"),("String","String"),("String2","String"),("Name","Name"),("SingleLineComment","Comment"),("MultiLineComment","Comment"),("Preprocessor","Preprocessor")]

    parseRules "Normal" =
      do (attr, result) <- (((pRegExpr (compileRegex "SET(?=\\s*\\()") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "\\bCHARACTER SET\\b") >>= withAttribute "Keyword"))
                            <|>
                            ((pKeyword " \n\t(),%&;?[]{}\\" ["ACCESS","ADD","ALL","ALTER","ANALYZE","AND","AS","ASC","AUTO_INCREMENT","BDB","BERKELEYDB","BETWEEN","BOTH","BY","CASCADE","CASE","CHANGE","CHARSET","COLUMN","COLUMNS","CONSTRAINT","CREATE","CROSS","CURRENT_DATE","CURRENT_TIME","CURRENT_TIMESTAMP","DATABASE","DATABASES","DAY_HOUR","DAY_MINUTE","DAY_SECOND","DEC","DEFAULT","DELAYED","DELETE","DESC","DESCRIBE","DISTINCT","DISTINCTROW","DROP","ELSE","ENCLOSED","ESCAPED","EXISTS","EXPLAIN","FIELDS","FOR","FOREIGN","FROM","FULLTEXT","FUNCTION","GRANT","GROUP","HAVING","HIGH_PRIORITY","IF","IGNORE","IN","INDEX","INFILE","INNER","INNODB","INSERT","INTERVAL","INTO","IS","JOIN","KEY","KEYS","KILL","LEADING","LEFT","LIKE","LIMIT","LINES","LOAD","LOCK","LOW_PRIORITY","MASTER_SERVER_ID","MATCH","MRG_MYISAM","NATURAL","NATIONAL","NOT","NULL","NUMERIC","ON","OPTIMIZE","OPTION","OPTIONALLY","OR","ORDER","OUTER","OUTFILE","PARTIAL","PRECISION","PRIMARY","PRIVILEGES","PROCEDURE","PURGE","READ","REFERENCES","REGEXP","RENAME","REPLACE","REQUIRE","RESTRICT","RETURNS","REVOKE","RIGHT","RLIKE","SELECT","SET","SHOW","SONAME","SQL_BIG_RESULT","SQL_CALC_FOUND_ROWS","SQL_SMALL_RESULT","SSL","STARTING","STRAIGHT_JOIN","STRIPED","TABLE","TABLES","TERMINATED","THEN","TO","TRAILING","TRUNCATE","TYPE","UNION","UNIQUE","UNLOCK","UNSIGNED","UPDATE","USAGE","USE","USER_RESOURCES","USING","VALUES","VARYING","WHEN","WHERE","WITH","WRITE","XOR","YEAR_MONTH","ZEROFILL"] >>= withAttribute "Keyword"))
                            <|>
                            ((pKeyword " \n\t(),%&;?[]{}\\" ["+","-","*","/","||","=","!=","<>","<","<=",">",">=","~=","^=",":=","=>","**",".."] >>= withAttribute "Operator"))
                            <|>
                            ((pKeyword " \n\t(),%&;?[]{}\\" ["ASCII","ORD","CONV","BIN","OCT","HEX","CHAR","CONCAT","CONCAT_WS","LENGTH","OCTET_LENGTH","CHAR_LENGTH","CHARACTER_LENGTH","BIT_LENGTH","LOCATE","POSITION","INSTR","LPAD","RPAD","LEFT","RIGHT","SUBSTRING","SUBSTRING_INDEX","MID","LTRIM","RTRIM","TRIM","SOUNDEX","SPACE","REPLACE","REPEAT","REVERSE","INSERT","ELT","FIELD","FIND_IN_SET","MAKE_SET","EXPORT_SET","LCASE","LOWER","UCASE","UPPER","LOAD_FILE","QUOTE","ABS","SIGN","MOD","FLOOR","CEILING","ROUND","EXP","LN","LOG","LOG2","LOG10","POW","POWER","SQRT","PI","COS","SIN","TAN","ACOS","ASIN","ATAN","ATAN2","COT","RAND","LEAST","GREATEST","DEGREES","RADIANS","DAYOFWEEK","WEEKDAY","DAYOFMONTH","DAYOFYEAR","MONTH","DAYNAME","MONTHNAME","QUARTER","WEEK","YEAR","YEARWEEK","HOUR","MINUTE","SECOND","PERIOD_ADD","PERIOD_DIFF","DATE_ADD","DATE_SUB","ADDDATE","SUBDATE","EXTRACT","TO_DAYS","FROM_DAYS","DATE_FORMAT","TIME_FORMAT","CURDATE","CURRENT_DATE","CURTIME","CURRENT_TIME","NOW","SYSDATE","CURRENT_TIMESTAMP","UNIX_TIMESTAMP","FROM_UNIXTIME","SEC_TO_TIME","TIME_TO_SEC","CAST","CONVERT","BIT_COUNT","DATABASE","USER","SYSTEM_USER","SESSION_USER","PASSWORD","ENCRYPT","ENCODE","DECODE","MD5","SHA1","SHA","AES_ENCRYPT","AES_DECRYPT","DES_ENCRYPT","DES_DECRYPT","LAST_INSERT_ID","FORMAT","VERSION","CONNECTION_ID","GET_LOCK","RELEASE_LOCK","IS_FREE_LOCK","BENCHMARK","INET_NTOA","INET_ATON","MASTER_POS_WAIT","FOUND_ROWS","COUNT","AVG","MIN","MAX","SUM","STD","STDDEV","BIT_OR","BIT_AND"] >>= withAttribute "Function"))
                            <|>
                            ((pKeyword " \n\t(),%&;?[]{}\\" ["CHAR","CHARACTER","VARCHAR","BINARY","VARBINARY","TINYBLOB","MEDIUMBLOB","BLOB","LONGBLOB","TINYTEXT","MEDIUMTEXT","TEXT","LONGTEXT","ENUM","BIT","BOOL","BOOLEAN","TINYINT","SMALLINT","MEDIUMINT","MIDDLEINT","INT","INTEGER","BIGINT","FLOAT","DOUBLE","REAL","DECIMAL","DEC","FIXED","NUMERIC","LONG","SERIAL","DATE","DATETIME","TIME","TIMESTAMP","YEAR"] >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%bulk_exceptions\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%bulk_rowcount\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%found\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%isopen\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%notfound\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%rowcount\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%rowtype\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pRegExpr (compileRegex "%type\\b") >>= withAttribute "Data Type"))
                            <|>
                            ((pFloat >>= withAttribute "Float"))
                            <|>
                            ((pInt >>= withAttribute "Decimal"))
                            <|>
                            ((pDetectChar False '\'' >>= withAttribute "String") >>~ pushContext "String")
                            <|>
                            ((pDetectChar False '"' >>= withAttribute "String") >>~ pushContext "String2")
                            <|>
                            ((pDetectChar False '`' >>= withAttribute "Name") >>~ pushContext "Name")
                            <|>
                            ((pDetectChar False '#' >>= withAttribute "Comment") >>~ pushContext "SingleLineComment")
                            <|>
                            ((pDetect2Chars False '-' '-' >>= withAttribute "Comment") >>~ pushContext "SingleLineComment")
                            <|>
                            ((pDetect2Chars False '/' '*' >>= withAttribute "Comment") >>~ pushContext "MultiLineComment")
                            <|>
                            ((pColumn 0 >> pRegExpr (compileRegex "rem\\b") >>= withAttribute "Comment") >>~ pushContext "SingleLineComment")
                            <|>
                            ((pAnyChar ":&" >>= withAttribute "Symbol"))
                            <|>
                            ((pColumn 0 >> pRegExpr (compileRegex "/$") >>= withAttribute "Symbol"))
                            <|>
                            ((pColumn 0 >> pRegExpr (compileRegex "@@?[^@ \\t\\r\\n]") >>= withAttribute "Preprocessor") >>~ pushContext "Preprocessor")
                            <|>
                            ((pDetectChar False '.' >>= withAttribute "String Char")))
         return (attr, result)

    parseRules "String" =
      do (attr, result) <- (((pLineContinue >>= withAttribute "String") >>~ (popContext >> return ()))
                            <|>
                            ((pHlCStringChar >>= withAttribute "String Char"))
                            <|>
                            ((pDetectChar False '&' >>= withAttribute "Symbol"))
                            <|>
                            ((pDetectChar False '\'' >>= withAttribute "String") >>~ (popContext >> return ())))
         return (attr, result)

    parseRules "String2" =
      do (attr, result) <- (((pLineContinue >>= withAttribute "String") >>~ (popContext >> return ()))
                            <|>
                            ((pHlCStringChar >>= withAttribute "String Char"))
                            <|>
                            ((pDetectChar False '&' >>= withAttribute "Symbol"))
                            <|>
                            ((pDetectChar False '"' >>= withAttribute "String") >>~ (popContext >> return ())))
         return (attr, result)

    parseRules "Name" =
      do (attr, result) <- (((pLineContinue >>= withAttribute "Name") >>~ (popContext >> return ()))
                            <|>
                            ((pHlCStringChar >>= withAttribute "String Char"))
                            <|>
                            ((pDetectChar False '`' >>= withAttribute "Name") >>~ (popContext >> return ())))
         return (attr, result)

    parseRules "SingleLineComment" =
      pzero

    parseRules "MultiLineComment" =
      do (attr, result) <- (((pLineContinue >>= withAttribute "Comment") >>~ (popContext >> return ()))
                            <|>
                            ((pDetect2Chars False '*' '/' >>= withAttribute "Comment") >>~ (popContext >> return ())))
         return (attr, result)

    parseRules "Preprocessor" =
      pzero

    parseRules x = fail $ "Unknown context" ++ x