2016-07-01 9 views
0

Я пишу консольное приложение на C++, и мне нужно, чтобы пользовательская командная система, подобная оболочке, настраивала параметры в приложениях. Например, пользователь может написать что-то вроде этого:Как проанализировать дерево команд в C++?

регистраимя

соединениеоткрыт[телнет | SSH]

соединениепереключательтелнет

отправитьтекст

соединениепереключательSSH

отправитьтекст

... и так далее ...


Таким образом, очевидно, что мы имеем некоторое дерево команд, в приведенном выше примере мы имеем:

--register 
| 
--connetion 
|   |--open 
|   |--switch 
| 
--send 

Каждая команда может иметь различное количество параметров.


ВОПРОС:

  • Как разобрать такое дерево команд?

Теперь я разбираю его с помощью регулярных выражений, но это решение действительно уродливое. Я читал о YACC и LEX, но я не уверен, что это действительно хорошая идея.

Есть ли широко используемый подход к дереву команд синтаксического анализа? Я не классный в теории лексического анализа, поэтому я был бы признателен, если вы ответите не академично.

+0

Предложение: использовать государственную машину, которая имеет (состояние, символ) -> (состояние, опция <станд :: функция >) функция перехода. – lorro

ответ

0

This - хороший ресурс с несколькими вариантами, если вы можете использовать библиотеку GNU C.

В конце вы захотите переключить каждый аргумент, и вам может потребоваться отслеживать какое-либо состояние для ваших вложенных команд.

Использование примера ARG дерево:

switch (arg) 
{ 
    case "register": 
    { 
     register = 1; 
     break; 
    } 
    case "connection": 
    { 
     connection = 1; 
     break; 
    } 
    case "open": 
    { 
     if (previousCommand == "connection") 
      connectionOpen = 1; 
     else 
      //error 
     break; 
    } 
    case "switch": 
    { 
     if (previousCommand == "connection") 
      connectionSwitch = 1; 
     else 
      //error 
     break; 
    } 
    case "send": 
    { 
     send = 1; 
     break; 
    } 
    previousCommand = arg; 
} 
+2

Я уверен, что вы не можете использовать строки для операторов 'case'. – Galik

+0

Спасибо за ваш ответ, но я думаю, что не так хорошо использовать состояния для каждой команды. Особенно, когда дерево команд довольно большое. –

+0

@ Галик, конечно, мы не можем. Но не так большая проблема для преобразования строк в уникальные значения enum. –