(这解释了Spudd86暗示的想法)。
您需要实现一个有限状态机。主要有以下几种状态:
- 一般状态
- 中的文件名
- 里面的
&&
令牌
- 里面的
||
令牌
对于每一个国家和一个输入字符,你必须决定什么是下一个状态,以及是否输出令牌。例如:
- 当前状态:一般;字符:X =>下一个状态:内部文件名称
- 当前状态:内部文件名称; character:space => next state:General;输出令牌
- 当前状态:里面文件名; character:& => next state:inside- & &;输出令牌
- 当前状态:inside- & &;字符:& =>下一个状态:通用;输出令牌
- 当前状态:inside- & &;字符:x =>下一个状态:通用;语法错误
- ...(广告nauseum)
这是很多枯燥的工作,以制定出所有的规则(开始从中获得乐趣,当你必须调试生成的代码),所以大多数人使用的代码生成器做。
编辑:一些代码(抱歉,如果语法是混乱的;我通常程序C++)
enum state {
STATE_GENERAL,
STATE_IN_FILENAME,
...
};
// Many characters are treated the same (e.g. 'x' and 'y') - so use categories
enum character_category
{
CHAR_GENERAL, // can appear in filenames
CHAR_WHITESPACE = ' ',
CHAR_AMPERSAND = '&',
CHAR_PIPE = '|',
CHAR_EOF = EOF,
...
};
character_category translate(int c)
{
switch (c) {
case '&': return CHAR_AMPERSAND;
case ' ': case '\t': case '\n': return CHAR_WHITESPACE;
...
default: return CHAR_GENERAL;
}
}
void do_stuff()
{
character_category cat;
state current_state = STATE_GENERAL;
state next_state;
char token[100];
char token_length = 0;
do {
int c = getchar();
cat = translate(c);
// The following implements a switch on 2 variables
int selector = 1000 * current_state + cat;
switch (selector)
{
case 1000 * STATE_GENERAL + CHAR_GENERAL:
next_state = STATE_IN_FILENAME;
token[token_length++] = c; // append a character to a filename token
break;
case 1000 * STATE_GENERAL + CHAR_WHITESPACE:
next_state = STATE_GENERAL; // do nothing
break;
case 1000 * STATE_GENERAL + CHAR_PIPE:
next_state = STATE_IN_OR_TOKEN; // the first char in '||' or just '|'
break;
// Much repetitive code already; define a macro for the case constants?
// Have to cover all states and all character categories; good luck...
case 1000 * STATE_IN_FILENAME + EOF:
case 1000 * STATE_IN_FILENAME + CHAR_WHITESPACE:
next_state = STATE_GENERAL;
printf("Filename token: %s\n", token);
break;
default:
printf("Bug\n"); // forgot one of the cases?
}
current_state = next_state;
} while (cat != CHAR_EOF);
}
你有什么这么远吗?你卡在哪里? – Mat 2011-03-30 20:16:19
既然你把它标记为'plain C',听起来好像你应该通过重复调用'strchr(cmd,'')'或者其他类似的东西来对命令字符串进行循环。 – phooji 2011-03-30 20:20:06
'switch/case'状态机? – Spudd86 2011-03-30 20:52:20