syntax/regexps.ss
(module regexps mzscheme
  (require (lib "lex.ss" "parser-tools")
           "abstract-regexps.ss"
           "../config.ss")

  (define-abstract-regexps
    [octal (range #\0 #\7)]
    [decimal (range #\0 #\9)]
    [positive (range #\1 #\9)]
    [hex (union (range #\0 #\9) (range #\A #\F) (range #\a #\f))]
    [exponent (union #\e #\E)]
    [sign (union #\- #\+)]
    [floatA (sequence (kleene+ decimal)
                      #\.
                      (kleene* decimal)
                      (maybe exponent sign (kleene+ decimal)))]
    [floatB (sequence (kleene+ decimal)
                      (maybe #\. (kleene* decimal))
                      exponent (maybe sign) (kleene+ decimal))]
    [floatC (sequence #\. (kleene+ decimal)
                      (maybe exponent (maybe sign) (kleene+ decimal)))]
    [float (union floatA floatB floatC)]
    [intH (sequence #\0 (union #\x #\X) (kleene+ hex))]
    [intO (sequence #\0 (kleene+ octal))]
    [intD (union #\0 (sequence positive (kleene* decimal)))]
    [integer (union intH intO intD)]
    [letter (union (range #\a #\z) (range #\A #\Z))]
    [unicode-escape (sequence #\\ #\u hex hex hex hex)]
    [identifier-start (union #\$ #\_ letter unicode-escape)]
    [identifier (sequence identifier-start (kleene* (union identifier-start decimal)))]
    [single-string (sequence #\'
                             (save (kleene* (union (sequence #\\ (any))
                                                   (complement #\'))))
                             #\')]
    [double-string (sequence #\"
                             (save (kleene* (union (sequence #\\ (any))
                                                   (complement #\"))))
                             #\")]
    [string-literal (union single-string double-string)]
    [re-pattern (kleene* (union (sequence #\\ #\/)
                                (complement #\/ #\return #\newline)))]
    [regexp-literal (sequence #\/ (save re-pattern) #\/ (maybe (save (union (sequence #\g (maybe #\i))
                                                                            (sequence #\i (maybe #\g))))))]
    ;; NOTE: prefixes must go AFTER longer patterns
    [assignment-operator (union "|=" "^=" "&=" "<<=" ">>=" ">>>=" "+=" "-=" "*=" "/=" "%=" "=")]
    [operator (union ";" "," "?" ":" "||" "&&" "|" "^" "&" "==="
                     "==" "=" "!==" "!=" "<<" "<=" "<" ">>>" ">>"
                     ">=" ">" "++" "--" "+" "-" "*" "/" "%" "!"
                     "~" "." "[" "]" "{" "}" "(" ")")]
    [line-comment (sequence "//" (kleene* (complement #\return #\newline)))]
    [block-comment (sequence "/*"
                             (kleene* (union (complement #\*)
                                             (sequence #\* (complement #\/))))
                             "*/")]
    [comment (union line-comment block-comment)]
    [ws (kleene+ (union #\tab #\return #\newline #\space #\vtab))]
    [empty (kleene+ (union ws comment))])

  (define-lex-abbrevs
    [lex:float (make-lex float)]
    [lex:integer (make-lex integer)]
    [lex:regexp (make-lex regexp-literal)]
    [lex:string (make-lex string-literal)]
    [lex:assignment-operator (make-lex assignment-operator)]
    [lex:operator (make-lex operator)]
    [lex:identifier (make-lex identifier)]
    [lex:line-comment (make-lex line-comment)]
    [lex:block-comment (make-lex block-comment)]
    [lex:comment (make-lex comment)]
    [lex:whitespace (make-lex ws)]
    [lex:empty (make-lex empty)])

  (define rx:float (make-rx float))
  (define rx:integer (make-rx integer))
  (define rx:regexp (make-rx regexp-literal))
  (define rx:string (make-rx string-literal))
  (define rx:operator (make-rx operator))
  (define rx:assignment-operator (make-rx assignment-operator))
  (define rx:identifier (make-rx identifier))
  (define rx:line-comment (make-rx line-comment))
  (define rx:block-comment (make-rx block-comment))
  (define rx:comment (make-rx comment))
  (define rx:whitespace (make-rx ws))
  (define rx:empty (make-rx empty))

  (provide (all-defined)))