2

I'm going to build a Command-line-tool. I want user type a text/string ( the function/command). Then, My tool will convert these string into C++ function/variable.

[They will run my custom data-type, my own function , not run system-function]

Ex: User type

>> myVar = c(123,456,789)

My tool will know that myVar is the variable name. and c(123,456,789) is an array of integer. And It converts these string into something like this:

int myVar[] = {123,456,789};

and User can call a function too:

Input:

   >> myPrintf(myVar[0]);

Output

   << 123

And my solution: I will buil a class, which maybe like this:

public class cVariable
{
    public string varName; // the variable name
    private varType; // the variable data-type
    public string varData;  // the value of this variable
}

And I will use if/else Statements to know which data-type/function I have to run.

But I think this way is not good at all.

asheeshr
  • 4,088
  • 6
  • 31
  • 50
Hung Doan
  • 1,167
  • 12
  • 19
  • 1
    You're trying to build a compiler. Good luck. – SLaks Mar 08 '13 at 02:10
  • Your only actual question seems to be the title "how to convert input string to function()?". I recommend the `boost::spirit` library - it will be challenging for you to learn, but once you understand it you'll be able to improve your program more easily and further. If you want to get a quick start, using regular expressions could help you test for assignments versus function calls, extract argument values etc.. Even more basic, you could use `sscanf()`. "I think this way is not good at all" - if you explain your concerns people could comment. Most obvious comment is: use ruby/perl/etc. – Tony Delroy Mar 08 '13 at 02:13
  • 3
    @SLaks isnt it more like an interpretter? – Karthik T Mar 08 '13 at 02:13
  • http://sourceforge.net/projects/igcc/ – perreal Mar 08 '13 at 02:34
  • @TonyD thank for your suggestion . "I think this way is not good at all" . I mean : That way (create a class and use if/else statement to get data-type) is not good approach, because There is a lot of code, and It's not dynamic too. (sorry if my english is not good) – Hung Doan Mar 08 '13 at 06:49

3 Answers3

4

Summary: This is probably harder to do than it seems. If you have a small set of cases, and you want to have something working tonight (and this is mainly a learning exercise), then you might simply go with your first approach.

From your question it sounds like you want to create a custom language, interpret that language, and bind it to your compiled binary. In general, this is an enormous undertaking. You may get better answers or results if you narrow your scope.

If you familiarize yourself with the following topics you will have an idea of how many options are available to you:

  • Compilation & Linking
    • Dynamic Linking
  • Reflection
  • Scripting and Interpreted languages
    • Language Bindings
  • Code Generation

For your program to have knowledge of its own structure and identifiers the language requires a feature called Reflection. Standard C++ does not have this feature (while many others do). By the time the code is compiled there are no longer string identifiers for your functions, types or arguments.

See the following question for a discussion of reflection-like behavior in C/C++: How can I add reflection to a C++ application?

(Conventions for Dynamic Linking exist for C and C++ which provide a mapping from strings to locations in the compiled binary, but this would probably not be the most direct way to accomplish what you want.)

It sounds like what you want is to build an interpreted language that has bindings to your original source code. If you have a very isolated set of cases, you may consider using preprocessor tricks. (The above linked question refers to Qt's implementation of this, as well as Boost tools.)

If you are open to using an existing scripting language you can research generation of bindings to C++ code from said language. Here are some resources for Python, for example: http://wiki.python.org/moin/IntegratingPythonWithOtherLanguages.

Community
  • 1
  • 1
Jacob Foshee
  • 2,704
  • 2
  • 29
  • 48
  • Thanks for your keywords They are really helpful. I don't know much about Reflection,Dynamic Linking...I think I have to make a research about them now. Thank – Hung Doan Mar 08 '13 at 06:41
2

Writing your own language is quite a task if you actually intend on doing something that is relatively complete. Thousands of lines of code is definitely possible. I have been involved in various forms of this over my 30 years of professional and hobby life - from writing a simple parser for commands in a debugger or similar to a fairly well working "mini-basic" interpreter and a small Lisp interpreter. I've also produced a lot of "pseud-language", where a text-file is used as input for a program, but it's not a full-fledged programming language - there are only a limited set of variables.

Another thing that I've done quite a bit is "table-driven programming", where the actual "code" is built into the program in the form of tables.

In all these, there are various forms of "I have some input/data that I want to translate into an action in relation to some other object".

The basic mechanism, as you describe, is to store the name and some other data (such as the type) in a data-structure of some sort. std::map<std::string, cVariable> would be one way to relatively easily retrieve the data from a name (string) to the variable of that name.

You can clearly do the same thing for functions. You would of course also have some way to pass arguments into the function. Exactly how you solve that is something every language has had to solve, and usually it ends up being some sort of "stack".

You can certainly have a map<std::string, function> that translates from a name to a function - the function definition may contain some information about what number and types of arguments the function takes.

For "builtin" functions, you can also have a type of argc, argv[] type approach, where arguments are passed as cVariable [where one option is constant or expression], to allow for myPrint(myVar[0] + 100), which of course isn't a true variable, but the result of the content of a variable added to a constant.

If you haven't written something that acts like a calculator with variables, that would probably be a good starting point.

Many "script" type languages have a variables that are "polymorphic" - that is, the value can be used as a number or as a string without actually asking for the variable to be converted.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

as for the title "convert a string to a function()" you could achieve this with function pointers:

assign a function according to a value:

int (*p)(char*,...) = printf;

use your function pointer to call the function:

char* str = "hello function pointer";
p("say %s", str);

But this is only half of your problem, first you need to do a lexical analisis to parse your input and acording to defined rules determine what would be a token (the symbols that compose the language of your command line tool), like a DIGIT, BRACKETS, ASSIGNMENTS, etc. Then you need a syntactic analyzer that sets the rules for the meaning of the syntax in your commands. This is basically done with a state machines, but is a complex task and I think you don't want to implement that yourself? look at Flex and Bisson tools to automate the generation of a parser.

This gives you a general solution to a general command line tool which interprets any language that you want. If the syntax is vary simple you could do a parser yourself, maybe with some regex libs.

mvaldes
  • 11
  • 4