As I understand it, in Ruby there are some tricky things you can do with function calls that don't require parentheses:
x y
In Ruby, that could be a function call where function x
is called with y
for the argument.
Well, in Python, we don't have those tricks; if you are calling a function, you need parentheses after the function name. So, I don't think you will have much luck trying to play games with eval()
for this.
Better is just to write a parser that parses the language for you and figures out what the language is trying to do. For that, Python has a particularly good library: pyparsing
http://pyparsing.wikispaces.com/
P.S. Just doing a Google search for "Python domain specific language" finds some good links, many in StackOverflow. Here is the best one I found:
Mini-languages in Python
EDIT: Okay, you asked for an example and here you go. This is my first-ever program in PyParsing and it was pretty easy. I didn't even read the documentation; I just worked from the examples in a presentation I found on the web.
Here's the URL of the presentation: http://www.ptmcg.com/geo/python/confs/TxUnconf2008Pyparsing.html
from pyparsing import *
def give_desired_output(s):
return "desired"
TAKE_THIS = Suppress("take_this") + Suppress(Word(printables))
AND_PROC = Suppress("and_process_it")
AND_GIVE = Keyword("and_give_me_the_output")
AND_GIVE.setParseAction(give_desired_output)
LANGUAGE_LINE = TAKE_THIS | AND_PROC | AND_GIVE
LANGUAGE = ZeroOrMore(LANGUAGE_LINE)
def parse_language(text):
lst = LANGUAGE.parseString(text)
assert len(lst) == 1 # trivial language returns a single value
return lst[0]
if __name__ == "__main__":
from_a_dsl_file = \
"""
take_this 'abc'
and_process_it
and_give_me_the_output
"""
print(parse_language(from_a_dsl_file)) # prints the word: desired