canql 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.hound.yml +10 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +11 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +76 -0
- data/Rakefile +13 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/canql.gemspec +39 -0
- data/code_safety.yml +201 -0
- data/lib/canql.rb +5 -0
- data/lib/canql/constants.rb +10 -0
- data/lib/canql/grammars.rb +12 -0
- data/lib/canql/grammars/age.treetop +23 -0
- data/lib/canql/grammars/anomaly.treetop +19 -0
- data/lib/canql/grammars/batch_types.treetop +11 -0
- data/lib/canql/grammars/dates.treetop +39 -0
- data/lib/canql/grammars/e_base_records.treetop +82 -0
- data/lib/canql/grammars/main.treetop +86 -0
- data/lib/canql/grammars/patient.treetop +55 -0
- data/lib/canql/grammars/registry.treetop +124 -0
- data/lib/canql/grammars/test_result.treetop +19 -0
- data/lib/canql/nodes.rb +20 -0
- data/lib/canql/nodes/age.rb +34 -0
- data/lib/canql/nodes/anomaly.rb +23 -0
- data/lib/canql/nodes/batch_types.rb +17 -0
- data/lib/canql/nodes/dates.rb +60 -0
- data/lib/canql/nodes/e_base_records.rb +60 -0
- data/lib/canql/nodes/main.rb +12 -0
- data/lib/canql/nodes/patient.rb +64 -0
- data/lib/canql/nodes/registry.rb +16 -0
- data/lib/canql/nodes/test_result.rb +21 -0
- data/lib/canql/parser.rb +41 -0
- data/lib/canql/treetop/extensions.rb +53 -0
- data/lib/canql/version.rb +6 -0
- metadata +261 -0
data/lib/canql.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'treetop'
|
3
|
+
|
4
|
+
Treetop.load File.expand_path('grammars/age', File.dirname(__FILE__))
|
5
|
+
Treetop.load File.expand_path('grammars/dates', File.dirname(__FILE__))
|
6
|
+
Treetop.load File.expand_path('grammars/anomaly', File.dirname(__FILE__))
|
7
|
+
Treetop.load File.expand_path('grammars/batch_types', File.dirname(__FILE__))
|
8
|
+
Treetop.load File.expand_path('grammars/e_base_records', File.dirname(__FILE__))
|
9
|
+
Treetop.load File.expand_path('grammars/test_result', File.dirname(__FILE__))
|
10
|
+
Treetop.load File.expand_path('grammars/patient', File.dirname(__FILE__))
|
11
|
+
Treetop.load File.expand_path('grammars/registry', File.dirname(__FILE__))
|
12
|
+
Treetop.load File.expand_path('grammars/main', File.dirname(__FILE__))
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar Age
|
3
|
+
rule with_birth_date
|
4
|
+
born_keyword fuzzy_date <Nodes::Age::BirthDateNode>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule with_death_date
|
8
|
+
that_who_keyword? died_keyword fuzzy_date <Nodes::Age::DeathDateNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule that_who_keyword
|
12
|
+
space ('that' / 'who') word_break
|
13
|
+
end
|
14
|
+
|
15
|
+
rule born_keyword
|
16
|
+
space ('born' / 'delivered') word_break
|
17
|
+
end
|
18
|
+
|
19
|
+
rule died_keyword
|
20
|
+
space 'died' word_break
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar Anomaly
|
3
|
+
rule anomalies
|
4
|
+
and_keyword? existance_modifier:anomalies_no_keyword? natal_period:anomalies_natal_period? anomalies_keyword <Nodes::Anomaly::Exists>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule anomalies_no_keyword
|
8
|
+
space ('no' / 'some') word_break
|
9
|
+
end
|
10
|
+
|
11
|
+
rule anomalies_natal_period
|
12
|
+
(prenatal_keyword / postnatal_keyword)
|
13
|
+
end
|
14
|
+
|
15
|
+
rule anomalies_keyword
|
16
|
+
space 'anomalies' word_break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar Dates
|
3
|
+
rule fuzzy_date
|
4
|
+
date:(between_dates / on_dates) word_break <Nodes::FuzzyDateNode>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule on_dates
|
8
|
+
space ('on' / 'in') space date_fragment <Nodes::SpecificDateNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule between_dates
|
12
|
+
space 'between' space start:date_fragment space 'and' space finish:date_fragment <Nodes::FragmentedDateRangeNode>
|
13
|
+
end
|
14
|
+
|
15
|
+
rule date_fragment
|
16
|
+
fragment:(daterange / year_quarter / chronic_date) word_break <Nodes::DateFragmentNode>
|
17
|
+
end
|
18
|
+
|
19
|
+
rule daterange
|
20
|
+
day_or_month? day_or_month? year <Nodes::DateRangeNode>
|
21
|
+
end
|
22
|
+
|
23
|
+
rule day_or_month
|
24
|
+
[0-9] 1..2 ('.' / '/')
|
25
|
+
end
|
26
|
+
|
27
|
+
rule year
|
28
|
+
[0-9] 4..4
|
29
|
+
end
|
30
|
+
|
31
|
+
rule year_quarter
|
32
|
+
'q' [1-4] space year <Nodes::YearQuarterNode>
|
33
|
+
end
|
34
|
+
|
35
|
+
rule chronic_date
|
36
|
+
(!(space ('and' / 'at' / 'with' / 'who')) .)+ <Nodes::ChronicDateNode>
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar EBaseRecords
|
3
|
+
rule action_or_ebr
|
4
|
+
and_keyword? action_and_ebr / actions / e_base_records
|
5
|
+
end
|
6
|
+
|
7
|
+
rule action_and_ebr
|
8
|
+
actions and_keyword e_base_records
|
9
|
+
end
|
10
|
+
|
11
|
+
rule e_base_records
|
12
|
+
unprocessed_keyword types:batch_types? records_keyword <Nodes::EBaseRecordsNode>
|
13
|
+
end
|
14
|
+
|
15
|
+
rule batch_types
|
16
|
+
space allowed_types word_break <Nodes::BatchTypesNode>
|
17
|
+
end
|
18
|
+
|
19
|
+
rule allowed_types
|
20
|
+
batch_type types:more_types* <Nodes::AllowedTypesNode>
|
21
|
+
end
|
22
|
+
|
23
|
+
rule more_types
|
24
|
+
','? space? ('or' space)? batch_type <Nodes::MoreTypesNode>
|
25
|
+
end
|
26
|
+
|
27
|
+
rule with_keyword
|
28
|
+
space 'with' word_break
|
29
|
+
end
|
30
|
+
|
31
|
+
rule actions
|
32
|
+
action_type action_keyword action_provider? <Nodes::ActionsNode>
|
33
|
+
end
|
34
|
+
|
35
|
+
rule action_provider
|
36
|
+
space 'at' space provider:(action_provider_code / action_provider_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
rule action_type
|
40
|
+
space accepted_action word_break
|
41
|
+
end
|
42
|
+
|
43
|
+
rule accepted_action
|
44
|
+
'wait' / 'proforma' / 'transfer' / 'notes' / 'child' /
|
45
|
+
'qa' / 'tag' / 'qc' / 'query' /
|
46
|
+
'moreinfo' / 'search' / 'check' / 'gpsearch'
|
47
|
+
end
|
48
|
+
|
49
|
+
rule action_keyword
|
50
|
+
space 'action' word_break
|
51
|
+
end
|
52
|
+
|
53
|
+
rule at_keyword
|
54
|
+
space 'at' word_break
|
55
|
+
end
|
56
|
+
|
57
|
+
rule action_provider_code
|
58
|
+
provider_type space code:(!' ' .)+ <Nodes::ActionProviderCodeNode>
|
59
|
+
end
|
60
|
+
|
61
|
+
rule action_provider_name
|
62
|
+
short_desc:(!(space provider_type) .)+ space provider_type <Nodes::ActionProviderNameNode>
|
63
|
+
end
|
64
|
+
|
65
|
+
# TODO: support cancer network?
|
66
|
+
rule provider_type
|
67
|
+
'hospital'
|
68
|
+
end
|
69
|
+
|
70
|
+
rule unprocessed_keyword
|
71
|
+
space 'unprocessed' word_break
|
72
|
+
end
|
73
|
+
|
74
|
+
rule records_keyword
|
75
|
+
space 'records' word_break
|
76
|
+
end
|
77
|
+
|
78
|
+
rule and_keyword
|
79
|
+
space 'and' word_break
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
grammar Canql
|
2
|
+
include Registry
|
3
|
+
include Patient
|
4
|
+
include Anomaly
|
5
|
+
include TestResult
|
6
|
+
include Dates
|
7
|
+
include EBaseRecords
|
8
|
+
include BatchTypes
|
9
|
+
include Age
|
10
|
+
|
11
|
+
# The root grammar
|
12
|
+
rule query
|
13
|
+
#quantity:record_count? pre:preconditions* cases_keyword post:additional_conditions*
|
14
|
+
quantity:record_count? pre:preconditions* cases_keyword post:additional_conditions* with_clause?
|
15
|
+
end
|
16
|
+
|
17
|
+
rule word_break
|
18
|
+
!(!(' '/',') .)
|
19
|
+
end
|
20
|
+
|
21
|
+
rule space
|
22
|
+
' '+
|
23
|
+
end
|
24
|
+
|
25
|
+
rule comma
|
26
|
+
space? (',' / 'and') space?
|
27
|
+
end
|
28
|
+
|
29
|
+
rule number
|
30
|
+
[0-9]+
|
31
|
+
end
|
32
|
+
|
33
|
+
rule record_count
|
34
|
+
all_keyword
|
35
|
+
/
|
36
|
+
'first' space number <Nodes::RecordCountNode>
|
37
|
+
end
|
38
|
+
|
39
|
+
rule all_keyword
|
40
|
+
'all' word_break
|
41
|
+
end
|
42
|
+
|
43
|
+
rule cases_keyword
|
44
|
+
space subject:('cases' / 'babies') word_break
|
45
|
+
end
|
46
|
+
|
47
|
+
rule preconditions
|
48
|
+
registry / gender / outcome
|
49
|
+
end
|
50
|
+
|
51
|
+
rule additional_conditions
|
52
|
+
and_keyword? (expected / with_birth_date / with_death_date)
|
53
|
+
end
|
54
|
+
|
55
|
+
rule with_clause
|
56
|
+
with_keyword post:with_conditions+
|
57
|
+
end
|
58
|
+
|
59
|
+
rule with_keyword
|
60
|
+
space 'with' word_break
|
61
|
+
end
|
62
|
+
|
63
|
+
rule and_keyword
|
64
|
+
space 'and' word_break
|
65
|
+
end
|
66
|
+
|
67
|
+
rule existance_keyword
|
68
|
+
space ('missing' / ('field' 's'?) / 'populated') word_break
|
69
|
+
end
|
70
|
+
|
71
|
+
rule no_keyword
|
72
|
+
space 'no' word_break
|
73
|
+
end
|
74
|
+
|
75
|
+
rule prenatal_keyword
|
76
|
+
space 'prenatal' word_break
|
77
|
+
end
|
78
|
+
|
79
|
+
rule postnatal_keyword
|
80
|
+
space 'postnatal' word_break
|
81
|
+
end
|
82
|
+
|
83
|
+
rule with_conditions
|
84
|
+
anomalies / test_results / patient_field_existance / mother_conditions / action_or_ebr
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar Patient
|
3
|
+
rule gender
|
4
|
+
space gender:('male' / 'female') word_break <Nodes::Patient::GenderNode>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule outcome
|
8
|
+
space outcome:('stillborn' / 'liveborn' / 'miscarried' / 'terminated' / 'registrable' / 'non-registrable' ) word_break <Nodes::Patient::OutcomeNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule expected_keyword
|
12
|
+
space ('expected' / 'due') word_break
|
13
|
+
end
|
14
|
+
|
15
|
+
rule expected
|
16
|
+
expected_keyword fuzzy_date <Nodes::Patient::ExpectedDateRangeNode>
|
17
|
+
end
|
18
|
+
|
19
|
+
rule patient_field_existance
|
20
|
+
and_keyword? field_existance_modifier:existance_keyword patient_field_list:patient_field_list <Nodes::Patient::FieldExists>
|
21
|
+
end
|
22
|
+
|
23
|
+
rule patient_fields_keyword
|
24
|
+
space 'field' 's'? word_break
|
25
|
+
end
|
26
|
+
|
27
|
+
rule patient_field_list
|
28
|
+
space patient_field_names (comma patient_field_names)*
|
29
|
+
end
|
30
|
+
|
31
|
+
rule patient_field_names
|
32
|
+
patient_field_name:('date of birth' / 'dob' / 'nhs number' / 'postcode' / 'birth weight' / 'place of delivery' / 'sex' / 'outcome')
|
33
|
+
end
|
34
|
+
|
35
|
+
rule mother_conditions
|
36
|
+
and_keyword? space subject:'mother' word_break mother_additional_conditions mother_with_clause?
|
37
|
+
end
|
38
|
+
|
39
|
+
rule mother_additional_conditions
|
40
|
+
mother_age_conditions*
|
41
|
+
end
|
42
|
+
|
43
|
+
rule mother_age_conditions
|
44
|
+
and_keyword? (with_birth_date / with_death_date)
|
45
|
+
end
|
46
|
+
|
47
|
+
rule mother_with_clause
|
48
|
+
with_keyword? post:mother_with_conditions+
|
49
|
+
end
|
50
|
+
|
51
|
+
rule mother_with_conditions
|
52
|
+
patient_field_existance
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Canql
|
2
|
+
grammar Registry
|
3
|
+
rule registry
|
4
|
+
space registry:(registry_code / registry_abbr) <Nodes::RegistryNode>
|
5
|
+
end
|
6
|
+
|
7
|
+
rule registry_code
|
8
|
+
[0-9] 2..2 <Nodes::RegistryCodeNode>
|
9
|
+
end
|
10
|
+
|
11
|
+
rule registry_abbr
|
12
|
+
(england / east_mids / thames / east / yorkshire / north_east / north_west /
|
13
|
+
west_mids / south_west / wessex / london / limbo)
|
14
|
+
end
|
15
|
+
|
16
|
+
rule thames
|
17
|
+
('thames valley' / 'thames')
|
18
|
+
{
|
19
|
+
def to_registrycode
|
20
|
+
'68'
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
rule east_mids
|
26
|
+
('east mids' / 'east midlands and south yorkshire' / 'east midlands')
|
27
|
+
{
|
28
|
+
def to_registrycode
|
29
|
+
'72'
|
30
|
+
end
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
rule yorkshire
|
35
|
+
'yorkshire'
|
36
|
+
{
|
37
|
+
def to_registrycode
|
38
|
+
'93'
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
rule north_east
|
44
|
+
'north east'
|
45
|
+
{
|
46
|
+
def to_registrycode
|
47
|
+
'73'
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
rule north_west
|
53
|
+
'north west'
|
54
|
+
{
|
55
|
+
def to_registrycode
|
56
|
+
'94'
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
rule west_mids
|
62
|
+
('west mids' / 'west midlands')
|
63
|
+
{
|
64
|
+
def to_registrycode
|
65
|
+
'99'
|
66
|
+
end
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
rule south_west
|
71
|
+
'south west'
|
72
|
+
{
|
73
|
+
def to_registrycode
|
74
|
+
'84'
|
75
|
+
end
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
rule wessex
|
80
|
+
'wessex'
|
81
|
+
{
|
82
|
+
def to_registrycode
|
83
|
+
'70'
|
84
|
+
end
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
rule london
|
89
|
+
('london and south east' / 'london')
|
90
|
+
{
|
91
|
+
def to_registrycode
|
92
|
+
'95'
|
93
|
+
end
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
rule east
|
98
|
+
('east of england' / 'east')
|
99
|
+
{
|
100
|
+
def to_registrycode
|
101
|
+
'96'
|
102
|
+
end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
rule limbo
|
107
|
+
'limbo'
|
108
|
+
{
|
109
|
+
def to_registrycode
|
110
|
+
'01'
|
111
|
+
end
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
rule england
|
116
|
+
'england'
|
117
|
+
{
|
118
|
+
def to_registrycode
|
119
|
+
'00'
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|