haskell.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. // Haskell scanner.
  3. // We do not yet support TemplateHaskell because it looks INSANE.
  4. /*
  5. * TODO: Some contextual awareness would be great, Kate seems to highlight
  6. * things differently depending on whether they're in [..] or (...) blocks,
  7. * but I don't understand Haskell enough to embark on that right now.
  8. *
  9. * It would also be nice to distinguish between some different classes of
  10. * operator.
  11. */
  12. require_once(dirname(__FILE__) . '/include/haskell.php');
  13. class LuminousHaskellScanner extends LuminousSimpleScanner {
  14. // handles comment nesting of multiline comments.
  15. function comment_override() {
  16. $this->nestable_token('COMMENT', '/\\{-/', '/-\\}/');
  17. }
  18. function init() {
  19. // import from ./include/
  20. global $luminous_haskell_functions;
  21. global $luminous_haskell_types;
  22. global $luminous_haskell_values;
  23. global $luminous_haskell_keywords;
  24. $this->add_identifier_mapping('KEYWORD', $luminous_haskell_keywords);
  25. $this->add_identifier_mapping('TYPE', $luminous_haskell_types);
  26. $this->add_identifier_mapping('FUNCTION', $luminous_haskell_functions);
  27. $this->add_identifier_mapping('VALUE', $luminous_haskell_values);
  28. // shebang
  29. $this->add_pattern('COMMENT', '/^#!.*/');
  30. // Refer to the sections in
  31. // http://www.haskell.org/onlinereport/lexemes.html
  32. // for the rules implemented here.
  33. // 2.4
  34. $this->add_pattern('TYPE', '/[A-Z][\'\w]*/');
  35. $this->add_pattern('IDENT', '/[_a-z][\'\w]*/');
  36. // http://www.haskell.org/onlinereport/prelude-index.html
  37. $this->add_pattern('FUNCTION', '/
  38. (?: !!|\\$!?|&&|\\|{1,2}|\\*{1,2}|\\+{1,2}|-(?!-)|\\.|\\/=?|<=?|==|=<<|>>?=?|\\^\\^? )
  39. /x');
  40. $op_chars = '\\+%^\\/\\*\\?#<>:;=@\\[\\]\\|\\\\~\\-!$@%&\\|=';
  41. // ` is used to make a function call into an infix operator
  42. // CRAZY OR WHAT.
  43. $this->add_pattern('OPERATOR', '/`[^`]*`/');
  44. // some kind of function, lambda, maybe.
  45. $this->add_pattern('FUNCTION', "/\\\\(?![$op_chars])\S+/");
  46. // Comments are hard!
  47. // http://www.mail-archive.com/[email protected]/msg09019.html
  48. // According to this, we can PROBABLY, get away with checking either side
  49. // for non-operator chars followed by at least 2 dashes, but I could well
  50. // be wrong. It'll do for now.
  51. $this->add_pattern('COMMENT', "/(?<![$op_chars])---*(?![$op_chars]).*/");
  52. // nested comments are easy!
  53. $this->add_pattern('NESTED_COMMENT', '/\\{-/');
  54. $this->overrides['NESTED_COMMENT'] = array($this, 'comment_override');
  55. $this->rule_tag_map['NESTED_COMMENT'] = 'COMMENT';
  56. $this->add_pattern('OPERATOR', "/[$op_chars]+/");
  57. // FIXME: the char type is way more discriminating than this
  58. $this->add_pattern('STRING', LuminousTokenPresets::$DOUBLE_STR_SL);
  59. $this->add_pattern('CHARACTER', LuminousTokenPresets::$SINGLE_STR_SL);
  60. // 2.5
  61. $this->add_pattern('NUMERIC', '/
  62. 0[oO]\d+ #octal
  63. |
  64. 0[xX][a-fA-F\d]+ #hex
  65. |
  66. # decimal and float can be done at once, according to the grammar
  67. \d+ (?: (?:\.\d+)? (?: [eE][+-]? \d+))?
  68. /x');
  69. }
  70. public static function guess_language($src, $info) {
  71. $p = 0.0;
  72. // comments
  73. if (preg_match('/\\{-.*\\-}/', $src)) $p += 0.05;
  74. // 'import qualified' seems pretty unique
  75. if (preg_match('/^import\s+qualified/m', $src)) $p += 0.05;
  76. // "data SomeType something ="
  77. if (preg_match('/data\s+\w+\s+\w+\s*=/', $src)) $p += 0.05;
  78. return $p;
  79. }
  80. }