DSLs in perl and python (Was sobering observation)
Rustom Mody
rustompmody at gmail.com
Thu Mar 17 13:47:17 EDT 2016
On Thursday, March 17, 2016 at 10:09:27 PM UTC+5:30, Charles T. Smith wrote:
> or something else ... you're in a "defend python at all costs!" mode.
Interesting that I see this now.
I was showing some finance-friends how to to convert one of the tables in
https://www.nyse.com/publicdocs/nyse/markets/amex-options/ArcaDirectAPISpecVersion4_1.pdf
[printed page 9 pdf pg 12 "Equities Symbology" ]
Since they were much more comfortable with perl than with python
I wrote the first version in perl (which I am not comfortable with!):
You try these by calling at command line with one argument
such as
IBM.A#
The perl and python versions are not matching in output behavior
but thats not really relevant; what we want is the exact recognition of that table (currently only a subset that I understand!)
--------------perl version
#!/usr/bin/perl
$string = $ARGV[0];
$string =~ /([A-Z]*)([.+-])?([A-Z]?)(#?)/;
%seriesmap = ('.' => "Plain",
'-' => "Preferred",
'+' => "Warrant"
);
print "(";
print "$1" . ", ";
print maybeize($2 , $seriesmap{$2}) . ", ";
print maybeize($3 , $3) . ", ";
print ((($4 =~ /#/) ? "True" : "False") . ")\n");
sub maybeize ($inp, $out) {
my ($inp, $out) = @_;
return (($inp eq "") ? "None" : ("Maybe." . $out));
}
----------- python version 1-----------------------
#!/usr/bin/python
# Using named captures and verbose (ie multiline readable) regexps
# Idea being that the regexp captures most of the DSL semantics
# ATM the DSL is no pretty (Thats another matter :-)
from sys import argv
import re
seriesmap = {'.':"Plain", '-':"Preferred", '+':"Warrant"}
string = argv[1]
rexp = r"""(?x) # Verbose re
# DSL for describing symbology
(?P<scrip> [A-Z]*) # The base scrip
(?P<serchar> [.+-])? # Series type char
(?P<series> [A-Z])? # Series
(?P<issuedc> [#])? # issued char indicator
"""
rec = re.compile(rexp)
m = rec.match(string)
if m:
g = m.group
# DSL -> Python
scrip, serchar, series, issuedc = g('scrip'), g('serchar'), g('series'), g('issuedc')
# Postprocessing
sertype = seriesmap[serchar]
issued = issuedc == '#'
print "scrip: %s\nsertype: %s\nseries: %s\nissued: %s" % (scrip, sertype, series, issued)
else:
print "match failed"
Finally separating the dsl into a separate file from the python driver:
--------- python driver
#!/usr/bin/python
# Symbology into a separated into file: "symbologydsl.txt"
# As of now file name hardwired and needs to be in same directory as this script
from sys import argv
import re
try:
# TODO Following needs to be added to dsl file
# (?=^.{1,}$) # There better be something >=1
dslfile = "symbologydsl.txt"
rexp = open(dslfile, "rU").read()
string = argv[1]
except IOError as i:
if i.errno == 2: # File not found
print ("No dsl file")
else:
print ("IOError: %s" % i.str)
exit()
except IndexError:
print ("No arg given?")
exit()
seriesmap = {'.':"Plain", '-':"Preferred", '+':"Warrant"}
m = re.search(rexp, string, re.VERBOSE)
if m:
g = m.group
# DSL -> Python
scrip, serchar, series, issuedc = g('scrip'), g('serchar'), g('series'), g('issuedc')
# Postprocessing: series, scrip are left as is
sertype = seriesmap[serchar] if serchar else "No Series Type"
issued = issuedc == '#'
print("scrip:\t%s\ntype:\t%s\nseries:\t%s\nissued:\t%s" %
(scrip, sertype, series, issued))
else:
print ("match failed")
----------- dsl file: symbologydsl.txt--------
# DSL (instantiation) for describing NYSE symbology
^
(?P<scrip> [A-Z]*) # The base scrip
(?P<serchar> [.+-])? # Series type char
(?P<series> [A-Z])? # Series
(?P<issuedc> [#])? # issued char indicator
$ # Thats all (there should be!)
------------------------------------
So now my questions:
How do you in perl make regexps readable like python's VERBOSE?
Can you do better in perl?
More information about the Python-list
mailing list