Skip to content

Instantly share code, notes, and snippets.

@thejefflarson
Created December 19, 2013 20:22
Show Gist options
  • Save thejefflarson/8045606 to your computer and use it in GitHub Desktop.
Save thejefflarson/8045606 to your computer and use it in GitHub Desktop.
%%{
machine records;
access @;
variable p @p;
variable pe @pe;
action offender_number_prefix {
@person = @cur = Person.new;
emit("offender_number_prefix");
}
action create_conviction {
@cur = @cur.respond_to?(:convictions) ? @cur.convictions.last : (@person.convictions << Conviction.new).last;
emit("offender_number_prefix");
}
action mark { mark; }
action error {
warn "error #{@line_no}: #{@data}, #{@last_emit}";
p @person
raise
}
action check_offender_number {
emit("offender_number")
if @person.offender_number != @cur.offender_number
@person.convictions.pop
@p = 0
fhold; fgoto Person;
end
}
action output {
if /(2907.241)/.match(@cur.offense_code)
[:offender_number_prefix, :offender_number, :last_name,
:first_name, :middle_initial, :admission_date, :race, :sex, :date_of_birth].each do |i|
print "#{@person.send(i)},"
end
puts [:offender_number_prefix,
:offender_number,
:committing_county,
:offense_code,
:offense_description,
:definite_years,
:minimum_years,
:maximum_years].map {|i| "#{@cur.send(i)}" }.join(',')
end
}
alpha_space=any;
offender_number_prefix=[ARW];
offender_number=digit{8};
last_name=alpha_space{15} >mark %{ emit("last_name") };
first_name=alpha_space{15} >mark %{ emit("first_name") };
middle_initial=alpha_space >mark %{ emit("middle_initial") };
race=alpha_space{15} >mark %{ emit("race") };
sex=[MFO] >mark %{ emit("sex") };
institution_name=alpha_space{40} >mark %{ emit("institution_name") };
admission_date=digit{8} >mark %{ emit("admission_date") };
release_date=digit{8} >mark %{ emit("release_date") };
date_of_birth=digit{8} >mark %{ emit("date_of_birth") };
activity_flag=[IPR] >mark %{ emit("activity_flag") };
committing_county=alpha_space{4} >mark %{ emit("committing_county") };
offense_code=alpha_space{10} >mark %{ emit("offense_code") };
offense_description=any{40} >mark %{ emit("offense_description") };
gun_time_years=digit{2} >mark %{ emit("gun_time_years") };
five=digit{5};
definite_years=five >mark %{ emit("definite_years") };
minimum_years=five >mark %{ emit("minimum_years") };
maximum_years=five >mark %{ emit("maximum_years") };
life_indicator=[LDB]? >mark %{ emit("life_indicator") };
newline='\r\n';
records = (
start:
Person: (offender_number_prefix >mark %offender_number_prefix
offender_number >mark %{ emit("offender_number") }
last_name
first_name
middle_initial
race
sex
institution_name
admission_date
release_date
date_of_birth
activity_flag
newline) -> Conviction,
Conviction: (offender_number_prefix >mark %create_conviction
offender_number >mark %check_offender_number
committing_county
offense_code
offense_description
gun_time_years
definite_years
minimum_years
maximum_years
life_indicator
' '*
newline) @output -> Conviction
) $!error;
main := records;
}%%
class Person
attr_accessor :offender_number_prefix, :offender_number, :last_name,
:first_name, :middle_initial, :race, :sex, :institution_name,
:admission_date, :release_date, :date_of_birth, :activity_flag,
:convictions
def initialize
@convictions = [Conviction.new]
end
end
class Conviction
attr_accessor :offender_number_prefix,
:offender_number,
:committing_county,
:offense_code,
:offense_description,
:gun_time_years,
:definite_years,
:minimum_years,
:maximum_years,
:life_indicator
end
class Parser
def initialize
@s = 0
%% write data;
@f = File.open("./press2.TXT")
@data = @f.readline
@f.rewind
@line_no = 0
%% write init;
parse
end
def mark
@s = @p
end
def emit(thing)
@last_emit = thing
@cur.send(thing + "=", @data[@s...@p].rstrip)
end
def parse
while !@f.eof?
@line_no += 1
@data = @f.readline
@p, @pe = 0, @data.length
eof = -1
%% write exec;
end
end
end
Parser.new.parse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment