0

我正在构建 LISP 解释器。我遇到的问题是我需要在遇到“(”时立即将整个子字符串发送到函数。例如,如果我有,

( begin  ( set x  2 ) (set y 3 ) )

那么我需要通过

begin  ( set x  2 ) (set y 3 ) )

当我再次遇到“(”时,我需要通过

set x  2 ) (set y 3 ) )

然后

set y 3 ) )

我尝试通过计算长度来使用 substr 这样做,但这并不完全奏效。如果有人可以提供帮助,那就太好了。

请求的代码

int a=0;
listnode *makelist(string t) //t is the substring 
{
     //some code
     istringstream iss(t); 
     string word;
     while(iss>>word){
         if(word=="(")//I used strcmp here. Just for the sake for time saving I wrote this
         //some operations
             int x=word.size();
     a=a+x;
     word=word.substr(a);
     p->down=makelist(word);//function called again and word here should be the substring
}}
4

3 回答 3

1

您是否考虑过使用中间表示?那么首先将所有整个字符串解析为一个数据结构然后执行它?毕竟 Lisps 具有传统的应用顺序,这意味着它们在调用函数之前首先评估参数。数据结构可能看起来类似于结构的行,该结构具有字符串的第一部分(即在您的示例中开始或设置)和字符串的其余部分作为第二个属性(如果需要,头部和休息)进行处理. 还要考虑通过递归比通过迭代更容易构造树,这里的基本情况是达到')'字符。

如果你对 Lisp 解释器和编译器感兴趣,你应该看看 Lisp in Small Pieces,物有所值。

于 2013-08-21T06:58:35.050 回答
0

我会想到这样的事情:

string str = "( begin  ( set x  2 ) (set y 3 ) )";

func(str);

...

void func(string s)
{
    int i = 0;
    while(s.size() > i)
    {
        if (s[i] == '(')
        {
           func(s.substr(i)); 
        }

        i++;
    }
}

会做的工作。[显然,你可能还想在里面做点别的事情!]

于 2013-08-20T19:01:24.350 回答
0

通常,lisp 解析是通过递归调用阅读器并让阅读器“消费”尽可能多的数据来完成的。如果您在字符串上执行此操作,通过引用传递相同的字符串并返回“这就是我阅读的内容”和“这是我完成阅读的地方”的元组可能会很方便。

所以像这样的事情(显然,在实际代码中,您可能希望将指针传递给偏移量而不是具有对结构并且需要处理它的内存管理,我省略了它以使代码更具可读性):

struct readthing {
  Node *data;
  int offset
}

struct readthing *read (char *str, int offset) {
  if (str[offset] == '(')
    return read_delimited(str, offset+1, ')'); /* Read a list, consumer the start */
  ...
}

struct readthing *read_delimited (char *str, int offset, char terminator) {
  Node *list  = NULL;
  offset = skip_to_next_token(str, offset);
  while (str[offset] != terminator) {
    struct readthing *foo = read(str, offset);
    offset = foo->offset;
    list = do_cons(foo->data, list);
  }
  return make_readthing(do_reverse(list), offset+1);
}
于 2013-08-22T14:33:25.440 回答