=============
Simple regexp
=============

rule my_rule {
    strings:
        $regexp = /a/
    condition:
        true
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_char)
                        )
                    )
                )
            )
            (bool_literal)
        )
    )
)


================
Multiple regexes
================

rule my_rule {
    strings:
        $regexp = /a/
        $regexp2 = /b/
    condition:
        true
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_char)
                        )
                    )
                )
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_char)
                        )
                    )
                )
            )
            (bool_literal)
        )
    )
)


========================
Multiple regexes w flags
========================

rule my_rule {
    strings:
        $regexp = /ů/i
        $regexp = /í/s
        $regexp = /\n/is
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_char)
                        )
                        flags: (regexp_flags)
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_char)
                        )
                        flags: (regexp_flags)
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_esc_seq)
                        )
                        flags: (regexp_flags)
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


============================
Simple regexp with modifiers
============================

rule my_rule {
    strings:
        $regexp = /a/ nocase private
    condition:
        true
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_char)
                        )
                    )
                    (str_mod_list
                        (str_mod)
                        (str_mod)
                    )
                )
            )
            (bool_literal)
        )
    )
)


=============================
Simple regexp with quantifier
=============================

rule my_rule {
    strings:
        $regexp = /a*/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier)
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


============================================
Multiple regexes with various quantifiers #1
============================================

rule my_rule {
    strings:
        $regexp = /a*?/
        $regexp1 = /i?/
        $regexp2 = /á+/
        $regexp3 = /ů{1,4}/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier
                                    greedy: (regexp_rep_quantifier_greedy)
                                )
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier)
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier)
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier
                                    lower: (regexp_rep_quantifier_number
                                        (dec_uint_literal_value_imm)
                                    )
                                    upper: (regexp_rep_quantifier_number
                                        (dec_uint_literal_value_imm)
                                    )
                                )
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


============================================
Multiple regexes with various quantifiers #2
============================================

rule my_rule {
    strings:
        $regexp = /a*?a/
        $regexp1 = /i+?-/
        $regexp2 = /á??/
        $regexp3 = /aů{,4}/
        $regexp4 = /oů{4,}?/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_rep
                                    base: (regexp_char)
                                    quant: (regexp_rep_quantifier
                                        greedy: (regexp_rep_quantifier_greedy)
                                    )
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_rep
                                    base: (regexp_char)
                                    quant: (regexp_rep_quantifier
                                        greedy: (regexp_rep_quantifier_greedy)
                                    )
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_rep
                                base: (regexp_char)
                                quant: (regexp_rep_quantifier
                                    greedy: (regexp_rep_quantifier_greedy)
                                )
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_char)
                                (regexp_rep
                                    base: (regexp_char)
                                    quant: (regexp_rep_quantifier
                                        upper: (regexp_rep_quantifier_number
                                            (dec_uint_literal_value_imm)
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_char)
                                (regexp_rep
                                    base: (regexp_char)
                                    quant: (regexp_rep_quantifier
                                        lower: (regexp_rep_quantifier_number
                                            (dec_uint_literal_value_imm)
                                        )
                                        greedy: (regexp_rep_quantifier_greedy)
                                    )
                                )
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


================================
Simple regexp with concatenation
================================

rule my_rule {
    strings:
        $regexp = /abcd/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_char)
                                        (regexp_char)
                                    )
                                    (regexp_char)
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


===================
Trivial alternation
===================

rule my_rule {
    strings:
        $regexp = /a|c/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_alt
                                (regexp_char)
                                (regexp_char)
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


======================================
Alternation with concatenated operands
======================================

rule my_rule {
    strings:
        $regexp = /abc|d\nf/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_alt
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_char)
                                        (regexp_char)
                                    )
                                    (regexp_char)
                                )
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_char)
                                        (regexp_esc_seq)
                                    )
                                    (regexp_char)
                                )
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


================================================
Alternation with quantified elements as operands
================================================

rule my_rule {
    strings:
        $regexp = /a*|d+e*/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_alt
                                (regexp_rep
                                    base: (regexp_char)
                                    quant: (regexp_rep_quantifier)
                                )
                                (regexp_cat
                                    (regexp_rep
                                        base: (regexp_char)
                                        quant: (regexp_rep_quantifier)
                                    )
                                    (regexp_rep
                                        base: (regexp_char)
                                        quant: (regexp_rep_quantifier)
                                    )
                                )
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


========================
Class characters - range
========================

rule my_rule {
    strings:
        $regexp = /[A-Z0-9]/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_class_range
                                    from: (regexp_class_char)
                                    (hyphen)
                                    to: (regexp_class_char)
                                )
                                (regexp_class_range
                                    from: (regexp_class_char)
                                    (hyphen)
                                    to: (regexp_class_char)
                                )
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


================
Class characters
================

rule my_rule {
    strings:
        $regexp = /[\na\r\t]/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_esc_seq)
                                (regexp_class_char)
                                (regexp_esc_seq)
                                (regexp_esc_seq)
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


=======================
Negated character class
=======================

rule my_rule {
    strings:
        $regexp = /[^?*+|]/
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_class
                                neg: (regexp_class_neg)
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                            )
                        )
                    )
                )
            )
            condition: (bool_literal)
        )
    )
)


=========================================
Special characters inside character class
=========================================

rule test {
    strings:
        $str = /[$.?(a)]/
    condition:
        $str
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_class
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                                (regexp_class_char)
                            )
                        )
                    )
                )
            )
            (string_identifier)
        )
    )
)


============================================
Character class with '-' without one operand
============================================

import "cuckoo"
rule test {
    condition:
        cuckoo.sync.mutex(/[_-]/)
}

---

(yara_file
    (import
        module: (string_literal
            str: (string_literal_str)
        )
    )
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            condition: (function_call
                id: (structure_access
                    struct: (structure_access
                        struct: (identifier)
                        member: (identifier)
                    )
                    member: (identifier)
                )
                args: (argument_list
                    (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_class_char)
                                (hyphen)
                            )
                        )
                    )
                )
            )
        )
    )
)


============================================
Character class with '-' and one operand '-'
============================================

import "cuckoo"
rule test {
    condition:
        cuckoo.sync.mutex(/[_--]/)
}

---

(yara_file
    (import
        module: (string_literal
            str: (string_literal_str)
        )
    )
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            condition: (function_call
                id: (structure_access
                    struct: (structure_access
                        struct: (identifier)
                        member: (identifier)
                    )
                    member: (identifier)
                )
                args: (argument_list
                    (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_class_range
                                    from: (regexp_class_char)
                                    (hyphen)
                                    to: (hyphen)
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)


==============================================
Character class with '-' and both operands '-'
==============================================

import "cuckoo"
rule test {
    condition:
        cuckoo.sync.mutex(/[---]/)
}

---

(yara_file
    (import
        module: (string_literal
            str: (string_literal_str)
        )
    )
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            condition: (function_call
                id: (structure_access
                    struct: (structure_access
                        struct: (identifier)
                        member: (identifier)
                    )
                    member: (identifier)
                )
                args: (argument_list
                    (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_class_range
                                    from: (hyphen)
                                    (hyphen)
                                    to: (hyphen)
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)


=================================================================
Character class with '-' and both operands '-' and with '-' after
=================================================================

import "cuckoo"
rule test {
    condition:
        cuckoo.sync.mutex(/[----]/)
}

---

(yara_file
    (import
        module: (string_literal
            str: (string_literal_str)
        )
    )
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            condition: (function_call
                id: (structure_access
                    struct: (structure_access
                        struct: (identifier)
                        member: (identifier)
                    )
                    member: (identifier)
                )
                args: (argument_list
                    (regexp
                        body: (regexp_body
                            (regexp_class
                                (regexp_class_range
                                    from: (hyphen)
                                    (hyphen)
                                    to: (hyphen)
                                )
                                (hyphen)
                            )
                        )
                    )
                )
            )
        )
    )
)


========================
Non meta curly braces #1
========================

rule test {
    strings:
        $str = /t{}/
    condition:
        $str
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_cat
                                (regexp_cat
                                    (regexp_char)
                                    (regexp_char)
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
            )
            (string_identifier)
        )
    )
)


========================
Non meta curly braces #2
========================

rule test {
    strings:
        $str = /h{,}/
    condition:
        $str
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_cat
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_char)
                                        (regexp_char)
                                    )
                                    (regexp_char)
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
            )
            (string_identifier)
        )
    )
)


==========================================
Non meta curly braces #3 - Only left brace
==========================================

rule test {
    strings:
        $str = /a{bc/
    condition:
        $str
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_cat
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_char)
                                        (regexp_char)
                                    )
                                    (regexp_char)
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
            )
            (string_identifier)
        )
    )
)


==========================================================
Non meta curly braces #4 - Combined with meta curly braces
==========================================================

rule test {
    strings:
        $str = /a{{2,}/
    condition:
        $str
}

---

(yara_file
    (rule
        (rule_head
            (identifier)
        )
        (rule_body
            (strings_list
                (string
                    (string_identifier)
                    (regexp
                        (regexp_body
                            (regexp_cat
                                (regexp_char)
                                (regexp_rep
                                    (regexp_char)
                                    (regexp_rep_quantifier
                                        (regexp_rep_quantifier_number
                                            (dec_uint_literal_value_imm)
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            )
            (string_identifier)
        )
    )
)


=========================================================
Non meta curly braces #5 - function call and chars inside
=========================================================

import "cuckoo"

rule test {
    condition:
        cuckoo.sync.mutex(/C:{abc}/)
}

---

(yara_file
    (import
        module: (string_literal
            str: (string_literal_str)
        )
    )
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            condition: (function_call
                id: (structure_access
                    struct: (structure_access
                        struct: (identifier)
                        member: (identifier)
                    )
                    member: (identifier)
                )
                args: (argument_list
                    (regexp
                        body: (regexp_body
                            (regexp_cat
                                (regexp_cat
                                    (regexp_cat
                                        (regexp_cat
                                            (regexp_cat
                                                (regexp_cat
                                                    (regexp_char)
                                                    (regexp_char)
                                                )
                                                (regexp_char)
                                            )
                                            (regexp_char)
                                        )
                                        (regexp_char)
                                    )
                                    (regexp_char)
                                )
                                (regexp_char)
                            )
                        )
                    )
                )
            )
        )
    )
)


==============================
Error - Whitespace before flag
==============================

rule my_rule {
    strings:
        $regexp = /a/  i
    condition:
        true
}

---

(yara_file
    (rule
        head: (rule_head
            id: (identifier)
        )
        body: (rule_body
            strings: (strings_list
                (string
                    id: (string_identifier)
                    value: (regexp
                        body: (regexp_body
                            (regexp_char)
                        )
                    )
                )
            )
            (ERROR
                (identifier)
            )
            condition: (bool_literal)
        )
    )
)
