-1

CLI を作成していますが、次のようなコードの解析に問題があります。

io.print("Hello World!");

if ステートメントを乱用してコード char ごとに解析することなく、このようなものを解析するにはどうすればよいでしょうか?

コンソールにこれをウィンドウに出力させたい:

Hello World!
4

2 に答える 2

2

Technically this solves your problem as described:

std::map< std::string, std::function<void()> > program_map;

void define_programs() {
  program_map[ "io.print("Hello World!");\n" ] = []{
    std::cout << "Hello World!\n";
  };
  program_map[ "io.print("Goodbye World!");\n" ] = []{
    std::cout << "Goodbye World!\n";
  };
};

int main() {
  // load parser:
  define_programs();
  // read program from user:
  std::string s;
  std::cin >> s;
  // compile and execute:
  if (program_map.find( s ) != program_map.end()) {
    (*program_map.find( s ))();
  } else {
    std::cout << "ERROR: unknown program.\n";
  }
}

but it probably doesn't solve the problem you want solved.

In general, parsing a C or C++-like language is a lot of work. You can make your job easier by making an easier to parse language (LISP-like syntax is pretty darn easy to parse).

If you do want to parse a C/C++ like language, I'd advise you learn about grammars and lexers. There are entire undergrad courses that end with writing a compiler for a language simpler than C/C++ -- C++ in particular is a really hard to parse language, and generally you'd want to not follow its conventions exactly.

Designing your grammar and writing a lexer (or teaching a pre-written lexer) for your grammar should go hand in hand.

When I design toy languages, I generally make them LISP like, because LISP like languages are really easy to work with. So you have a command initializer (, a command, a list of arguments (which could be futher ('d), and the command executes when you reach the matching ).

So the equivalent of your code would be:

(io print "Hello World")

and now I have the io command (and object instances would be kinds of "commands") with a method print (which it reads from slot 2), and arguments to said method "Hello World". The result of that, if I was feeling functional, would be a program that printed Hello World -- if not, it would do that as a side effect and return either an error code or nothing.

I'd then write an environment around this that defines some commands (including "make object"), probably some kind of quoting syntax (so I could define lambdas), etc. I'd end up with a language that is a poorly designed, sub-optimal, restricted implementation of a small part of common lisp, which is traditional.

Only after I could do something like the above would I consider writing a parser for a harder to parse language like C/C++. And even then, I'd first rewrite the above toy language into some lexing/parsing framework, then write my C/C++ like language in the same framework.

于 2013-04-26T19:41:57.783 に答える
0

これは、C++ で HelloWorld を記述する方法です。

#include <iostream>

int main() {
  std::cout << "Hello World!";
  return 0;
}

文字列はコンパイル時に解析されるため、非効率的に出力されることを心配する必要はありません。

私があなたの質問を誤解していて (CLI が Command Line Interface の略であることしか知らない)、本当に C++ ソース コードを解析したい場合。yacc のようなツールに関するチュートリアルを読んで、オープン ソースの C 文法から始めることをお勧めします。

これは良い yacc チュートリアルです: http://www.ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

これは文法の良い出発点です: http://www.computing.surrey.ac.uk/research/dsrg/fog/CxxGrammar.y

于 2013-04-26T18:30:03.803 に答える