{- This module was generated from data in the Kate syntax
   highlighting file rust.xml, version 1.1, by  -}

module Text.Highlighting.Kate.Syntax.Rust
          (highlight, parseExpression, syntaxName, syntaxExtensions)
where
import Text.Highlighting.Kate.Types
import Text.Highlighting.Kate.Common
import Text.ParserCombinators.Parsec hiding (State)
import Control.Monad.State
import Data.Char (isSpace)
import qualified Data.Set as Set

-- | Full name of language.
syntaxName :: String
syntaxName = "Rust"

-- | Filename extensions for this language.
syntaxExtensions :: String
syntaxExtensions = "*.rs"

-- | Highlight source code using this syntax definition.
highlight :: String -> [SourceLine]
highlight input = evalState (mapM parseSourceLine $ lines input) startingState

parseSourceLine :: String -> State SyntaxState SourceLine
parseSourceLine = mkParseSourceLine (parseExpression Nothing)

-- | Parse an expression using appropriate local context.
parseExpression :: Maybe (String,String)
                -> KateParser Token
parseExpression mbcontext = do
  (lang,cont) <- maybe currentContext return mbcontext
  result <- parseRules (lang,cont)
  optional $ do eof
                updateState $ \st -> st{ synStPrevChar = '\n' }
                pEndLine
  return result

startingState = SyntaxState {synStContexts = [("Rust","Normal")], synStLineNumber = 0, synStPrevChar = '\n', synStPrevNonspace = False, synStContinuation = False, synStCaseSensitive = True, synStKeywordCaseSensitive = True, synStCaptures = []}

pEndLine = do
  updateState $ \st -> st{ synStPrevNonspace = False }
  context <- currentContext
  contexts <- synStContexts `fmap` getState
  st <- getState
  if length contexts >= 2
    then case context of
      _ | synStContinuation st -> updateState $ \st -> st{ synStContinuation = False }
      ("Rust","Normal") -> return ()
      ("Rust","Attribute") -> return ()
      ("Rust","Function") -> return ()
      ("Rust","Type") -> return ()
      ("Rust","String") -> return ()
      ("Rust","RawString") -> return ()
      ("Rust","RawHashed1") -> return ()
      ("Rust","RawHashed2") -> return ()
      ("Rust","Character") -> (popContext) >> pEndLine
      ("Rust","CharEscape") -> (popContext) >> pEndLine
      ("Rust","Commentar 1") -> (popContext) >> pEndLine
      ("Rust","Commentar 2") -> return ()
      _ -> return ()
    else return ()

withAttribute attr txt = do
  when (null txt) $ fail "Parser matched no text"
  updateState $ \st -> st { synStPrevChar = last txt
                          , synStPrevNonspace = synStPrevNonspace st || not (all isSpace txt) }
  return (attr, txt)

list_fn = Set.fromList $ words $ "fn"
list_type = Set.fromList $ words $ "type"
list_keywords = Set.fromList $ words $ "abstract alignof as become box break const continue crate do else enum extern final for if impl in let loop macro match mod move mut offsetof override priv proc pub pure ref return Self self sizeof static struct super trait type typeof unsafe unsized use virtual where while yield"
list_traits = Set.fromList $ words $ "AsSlice CharExt Clone Copy Debug Decodable Default Display DoubleEndedIterator Drop Encodable Eq Default Extend Fn FnMut FnOnce FromPrimitive Hash Iterator IteratorExt MutPtrExt Ord PartialEq PartialOrd PtrExt Rand Send Sized SliceConcatExt SliceExt Str StrExt Sync ToString"
list_types = Set.fromList $ words $ "bool int isize uint usize i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 float char str Option Result Self Box Vec String"
list_ctypes = Set.fromList $ words $ "c_float c_double c_void FILE fpos_t DIR dirent c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong size_t ptrdiff_t clock_t time_t c_longlong c_ulonglong intptr_t uintptr_t off_t dev_t ino_t pid_t mode_t ssize_t"
list_self = Set.fromList $ words $ "self"
list_constants = Set.fromList $ words $ "true false Some None Ok Err Success Failure Cons Nil"
list_cconstants = Set.fromList $ words $ "EXIT_FAILURE EXIT_SUCCESS RAND_MAX EOF SEEK_SET SEEK_CUR SEEK_END _IOFBF _IONBF _IOLBF BUFSIZ FOPEN_MAX FILENAME_MAX L_tmpnam TMP_MAX O_RDONLY O_WRONLY O_RDWR O_APPEND O_CREAT O_EXCL O_TRUNC S_IFIFO S_IFCHR S_IFBLK S_IFDIR S_IFREG S_IFMT S_IEXEC S_IWRITE S_IREAD S_IRWXU S_IXUSR S_IWUSR S_IRUSR F_OK R_OK W_OK X_OK STDIN_FILENO STDOUT_FILENO STDERR_FILENO"

regex_0x'5b0'2d9a'2dfA'2dF'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex True "0x[0-9a-fA-F_]+([iu](8|16|32|64)?)?"
regex_0o'5b0'2d7'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex True "0o[0-7_]+([iu](8|16|32|64)?)?"
regex_0b'5b0'2d1'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex True "0b[0-1_]+([iu](8|16|32|64)?)?"
regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'5c'2e'5b0'2d9'5f'5d'2a'28'5beE'5d'5b'2b'2d'5d'3f'5b0'2d9'5f'5d'2b'29'3f'28f32'7cf64'7cf'29'3f = compileRegex True "[0-9][0-9_]*\\.[0-9_]*([eE][+-]?[0-9_]+)?(f32|f64|f)?"
regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f = compileRegex True "[0-9][0-9_]*([iu](8|16|32|64)?)?"
regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'3a'3a = compileRegex True "[a-zA-Z_][a-zA-Z_0-9]*::"
regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'21 = compileRegex True "[a-zA-Z_][a-zA-Z_0-9]*!"
regex_'27'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'28'3f'21'27'29 = compileRegex True "'[a-zA-Z_][a-zA-Z_0-9]*(?!')"
regex_x'5b0'2d9a'2dfA'2dF'5d'7b2'7d = compileRegex True "x[0-9a-fA-F]{2}"
regex_u'5c'7b'5b0'2d9a'2dfA'2dF'5d'7b1'2c6'7d'5c'7d = compileRegex True "u\\{[0-9a-fA-F]{1,6}\\}"
regex_u'5b0'2d9a'2dfA'2dF'5d'7b4'7d = compileRegex True "u[0-9a-fA-F]{4}"
regex_U'5b0'2d9a'2dfA'2dF'5d'7b8'7d = compileRegex True "U[0-9a-fA-F]{8}"
regex_'2e = compileRegex True "."

parseRules ("Rust","Normal") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_fn >>= withAttribute KeywordTok) >>~ pushContext ("Rust","Function"))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_type >>= withAttribute KeywordTok) >>~ pushContext ("Rust","Type"))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_keywords >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_types >>= withAttribute DataTypeTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_traits >>= withAttribute BuiltInTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_ctypes >>= withAttribute DataTypeTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_self >>= withAttribute KeywordTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_constants >>= withAttribute ConstantTok))
   <|>
   ((pKeyword " \n\t.():!+,-<=>%&*/;?[]^{|}~\\" list_cconstants >>= withAttribute ConstantTok))
   <|>
   ((pDetect2Chars False '/' '/' >>= withAttribute CommentTok) >>~ pushContext ("Rust","Commentar 1"))
   <|>
   ((pDetect2Chars False '/' '*' >>= withAttribute CommentTok) >>~ pushContext ("Rust","Commentar 2"))
   <|>
   ((pRegExpr regex_0x'5b0'2d9a'2dfA'2dF'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_0o'5b0'2d7'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_0b'5b0'2d1'5f'5d'2b'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'5c'2e'5b0'2d9'5f'5d'2a'28'5beE'5d'5b'2b'2d'5d'3f'5b0'2d9'5f'5d'2b'29'3f'28f32'7cf64'7cf'29'3f >>= withAttribute DecValTok))
   <|>
   ((pRegExpr regex_'5b0'2d9'5d'5b0'2d9'5f'5d'2a'28'5biu'5d'288'7c16'7c32'7c64'29'3f'29'3f >>= withAttribute DecValTok))
   <|>
   ((pDetect2Chars False '#' '[' >>= withAttribute AttributeTok) >>~ pushContext ("Rust","Attribute"))
   <|>
   ((pString False "#![" >>= withAttribute AttributeTok) >>~ pushContext ("Rust","Attribute"))
   <|>
   ((pRegExpr regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'3a'3a >>= withAttribute NormalTok))
   <|>
   ((pRegExpr regex_'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'21 >>= withAttribute PreprocessorTok))
   <|>
   ((pRegExpr regex_'27'5ba'2dzA'2dZ'5f'5d'5ba'2dzA'2dZ'5f0'2d9'5d'2a'28'3f'21'27'29 >>= withAttribute OtherTok))
   <|>
   ((pDetectChar False '{' >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '}' >>= withAttribute NormalTok))
   <|>
   ((pDetect2Chars False 'r' '"' >>= withAttribute StringTok) >>~ pushContext ("Rust","RawString"))
   <|>
   ((pString False "r##\"" >>= withAttribute StringTok) >>~ pushContext ("Rust","RawHashed2"))
   <|>
   ((pString False "r#\"" >>= withAttribute StringTok) >>~ pushContext ("Rust","RawHashed1"))
   <|>
   ((pDetectChar False '"' >>= withAttribute StringTok) >>~ pushContext ("Rust","String"))
   <|>
   ((pDetectChar False '\'' >>= withAttribute CharTok) >>~ pushContext ("Rust","Character"))
   <|>
   ((pDetectChar False '[' >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False ']' >>= withAttribute NormalTok))
   <|>
   ((pDetectIdentifier >>= withAttribute NormalTok))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Normal")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","Attribute") =
  (((pDetectChar False ']' >>= withAttribute AttributeTok) >>~ (popContext))
   <|>
   ((parseRules ("Rust","Normal")))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Attribute")) >> pDefault >>= withAttribute AttributeTok))

parseRules ("Rust","Function") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '(' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   ((pDetectChar False '<' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Function")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","Type") =
  (((pDetectSpaces >>= withAttribute NormalTok))
   <|>
   ((pDetectChar False '=' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   ((pDetectChar False '<' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   ((pDetectChar False ';' >>= withAttribute NormalTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Type")) >> pDefault >>= withAttribute NormalTok))

parseRules ("Rust","String") =
  (((pDetectChar False '\\' >>= withAttribute SpecialCharTok) >>~ pushContext ("Rust","CharEscape"))
   <|>
   ((pDetectChar False '"' >>= withAttribute StringTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","String")) >> pDefault >>= withAttribute StringTok))

parseRules ("Rust","RawString") =
  (((pDetectChar False '"' >>= withAttribute StringTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","RawString")) >> pDefault >>= withAttribute StringTok))

parseRules ("Rust","RawHashed1") =
  (((pDetect2Chars False '"' '#' >>= withAttribute StringTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","RawHashed1")) >> pDefault >>= withAttribute StringTok))

parseRules ("Rust","RawHashed2") =
  (((pString False "\"##" >>= withAttribute StringTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","RawHashed2")) >> pDefault >>= withAttribute StringTok))

parseRules ("Rust","Character") =
  (((pDetectChar False '\\' >>= withAttribute SpecialCharTok) >>~ pushContext ("Rust","CharEscape"))
   <|>
   ((pDetectChar False '\'' >>= withAttribute CharTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Character")) >> pDefault >>= withAttribute CharTok))

parseRules ("Rust","CharEscape") =
  (((pAnyChar "nrt\\'\"" >>= withAttribute SpecialCharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_x'5b0'2d9a'2dfA'2dF'5d'7b2'7d >>= withAttribute SpecialCharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_u'5c'7b'5b0'2d9a'2dfA'2dF'5d'7b1'2c6'7d'5c'7d >>= withAttribute SpecialCharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_u'5b0'2d9a'2dfA'2dF'5d'7b4'7d >>= withAttribute SpecialCharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_U'5b0'2d9a'2dfA'2dF'5d'7b8'7d >>= withAttribute SpecialCharTok) >>~ (popContext))
   <|>
   ((pRegExpr regex_'2e >>= withAttribute ErrorTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","CharEscape")) >> pDefault >>= withAttribute SpecialCharTok))

parseRules ("Rust","Commentar 1") =
  (currentContext >>= \x -> guard (x == ("Rust","Commentar 1")) >> pDefault >>= withAttribute CommentTok)

parseRules ("Rust","Commentar 2") =
  (((pDetectSpaces >>= withAttribute CommentTok))
   <|>
   ((pDetect2Chars False '*' '/' >>= withAttribute CommentTok) >>~ (popContext))
   <|>
   (currentContext >>= \x -> guard (x == ("Rust","Commentar 2")) >> pDefault >>= withAttribute CommentTok))


parseRules x = parseRules ("Rust","Normal") <|> fail ("Unknown context" ++ show x)
