- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在开发一个 shell,一个类似 bash 的小 shell,没有脚本(if while ...)我必须手工制作词法分析器/解析器 (LL)。
因此词法分析器会将命令(char *cmd)转换为链表(t_list *list)。LL 解析器会将链表 (t_list *list) 转换为具有 grammar 的 AST(二叉树 t_btree *root)
所以,我知道如何制作 LL 解析器,但我不知道如何标记我的命令。
例如:ps | grep ls >> 文件;制作 && ./a.out
=> 'ps' '|' 'grep' 'ls' '>>' '文件' ';' ''make '&&' './a.out'
谢谢。
(我不想使用任何生成器)
最佳答案
(这解释了 Spudd86 暗示的想法)。
您需要实现一个有限状态机。有以下几种状态:
&&
token 中||
token 中对于每个状态和下一个输入字符,您必须决定下一个状态是什么,以及是否输出 token 。例如:
制定所有规则是一项非常无聊的工作(当您必须调试生成的代码时乐趣才开始),因此大多数人使用代码生成器来完成这项工作。
编辑:一些代码(抱歉,如果语法搞砸了;我通常用 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);
}
关于c - 如何手工编写(shell)词法分析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5491775/
我想学习如何手工计算散列(比如用纸和铅笔)。这可行吗?任何有关从哪里了解这一点的指示都将不胜感激。 最佳答案 这取决于你想做的散列。您可以非常轻松地手动执行一个非常简单的散列——例如,一个简单的散列是
我正在为 IDA Pro 编写脚本使用 idapython 在 Python 中进行反汇编插入。使用它,我能够填补 IDA 自动分析不足的空白。 让我感到难过的一个领域是用(需要一个更好的术语)“漂亮
我找到了一个展示如何手动计算 LCC 的示例(见图)。 如何在 R 中复制这些步骤?重点是找到“邻居之间的实际链接数”(中间步骤) 我最好手动计算一下 *igraph包有提供这个数字吗? 示例邻接矩阵
我正在尝试像 Apple 的 TextSizingExample 那样手动组装 NSTextView 并发现一个无聊的错误。如果您运行 TextSizingExample 并选择“环绕滚动文本”模式,
我想手动制作 TLS 客户端 Hello 消息或至少使用 OkHttp 客户端指定下一个值: TLS 版本 密码 扩展 椭圆曲线 椭圆曲线点格式 可能吗? 最佳答案 见 https://square.
我是一名优秀的程序员,十分优秀!