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