读取字符串
现在我们需要添加对字符串解析的支持。像往常一样,Lispy需要添加名称为string
的新语法规则到Lispy语法分析器中。
我们将要使用的字符串表示规则与C相同。这意味着字符串实质上是两个引号"
之间的一系列转义字符或普通字符组成。我们将下式指定为Lispy语法中字符串正则表达式。
string : /\"(\\\\.|[^\"])*\"/ ;
这个正则表达式看起来很复杂,但在某些方面更有助于理解。这个式子是这样理解的。该字符串是从"
字符开始,后面跟着零个或多个跟着任意字符.
的反斜杠\\
,或者非"
的任意字符[^\\"]
。最后,以"
收尾。
我们也需要在lval_read
函数中添加一个case来处理字符串读取。
if (strstr(t->tag, "string")) { return lval_read_str(t); }
因为字符串是以转义形式输入的,所以我们需要创建lval_read_str
函数来解决这个问题。 这个功能有点棘手,因为它必须解决以下问题。 首先,它必须剥离字符串两侧"
字符。然后必须对转义字符串进行解码,将一系列转义字符(如\n
)转换成实际编码字符。最后必须创建一个新的lval
并清理函数中使用过的内存。
lval* lval_read_str(mpc_ast_t* t) {
/* Cut off the final quote character */
t->contents[strlen(t->contents)-1] = '\0';
/* Copy the string missing out the first quote character */
char* unescaped = malloc(strlen(t->contents+1)+1);
strcpy(unescaped, t->contents+1);
/* Pass through the unescape function */
unescaped = mpcf_unescape(unescaped);
/* Construct a new lval using the string */
lval* str = lval_str(unescaped);
/* Free the string and return */
free(unescaped);
return str;
}
如果这一切都没有问题,我们应该能够在REPL中使用字符串。 接下来我们在函数中使用一下字符串。
lispy> "hello"
"hello"
lispy> "hello\n"
"hello\n"
lispy> "hello\""
"hello\""
lispy> head {"hello" "world"}
{"hello"}
lispy> eval (head {"hello" "world"})
"hello"
lispy>
当前内容版权归 NoahDragon 译 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 NoahDragon 译 .