lisp c ruby java,用 Ruby 进行简单的 lisp 表达式的解析

def parse(line)

s = line.scan(/\(|\)|"(?:\\.|[^"])*"|[^()" \n]+/)

f = ->(t=nil){

case x = t || s.shift

when ?(

y = []

while x = s.shift

return y if x==?)

y << f[x]

end

fail ")?"

when nil

nil

when /^#(.*)$/

{?t=>true,?f=>false}[$~[1]]

when /\d+/

x.to_i

when /^\"(.*)\"$/m

$~[1].gsub(/\\./,'\n'=>"\n","\\\\"=>"\\","\\\""=>'"')

else

x.to_sym

end

}

f[]

end

$tests = {

"" => nil,

"1" => 1,

"(a b)" => [:a,:b],

"(1 2(2 3))" => [1,2,[2,3]],

'(a"b"c"d"(ef))' => [:a,"b",:c,"d",[:ef]],

'("a b" (c d-e))' => ["a b",[:c,:"d-e"]],

"(\"a\nb\"\nb\nc (d))" => ["a\nb",:b,:c,[:d]],

' "a\nb"' => "a\nb",

'"a\\"b"'=>'a"b',

"\"\\\\\""=> "\\",

"(#t #f)" => [true,false],

"(define (f x) (if (zero? x) 0 (+ x (f (- x 1)))))" =>

[:define,[:f,:x],[:if,[:zero?,:x],0,[:+,:x,[:f,[:-,:x,1]]]]],

}

p $tests.all?{|x,y|parse(x)==y}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 C 语言中实现 Lisp 达式求值的话,需要用到栈和逆波兰达式的思想。 首先,我们需要将 Lisp 达式转化为逆波兰达式。逆波兰达式是一种无需括号的达式示方法,它将操作符放在操作数的后面,例如: Lisp 达式:(+ 1 2) 逆波兰达式:1 2 + Lisp 达式:(sqrt (* x x)) 逆波兰达式:x x * sqrt 转化为逆波兰达式后,我们就可以通过栈来计算达式的值了。具体的实现步骤如下: 1. 对逆波兰达式进行遍历,遇到数字则压入栈中; 2. 遇到操作符则从栈中弹出相应数目的数字,进行运算,并将结果压入栈中; 3. 遍历完后,栈中剩下的数字就是达式的值。 以下是一个简单的 C 语言实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define STACK_SIZE 100 // 栈结构体 typedef struct stack { double data[STACK_SIZE]; int top; } Stack; // 初始化栈 void init(Stack *s) { s->top = -1; } // 判断栈是否为空 int is_empty(Stack *s) { return s->top == -1; } // 判断栈是否已满 int is_full(Stack *s) { return s->top == STACK_SIZE - 1; } // 入栈 void push(Stack *s, double num) { if (is_full(s)) { printf("Stack is full!\n"); exit(1); } s->data[++s->top] = num; } // 出栈 double pop(Stack *s) { if (is_empty(s)) { printf("Stack is empty!\n"); exit(1); } return s->data[s->top--]; } // 计算逆波兰达式的值 double eval(char **tokens, int size) { Stack s; init(&s); double num1, num2; for (int i = 0; i < size; i++) { if (strcmp(tokens[i], "+") == 0) { num2 = pop(&s); num1 = pop(&s); push(&s, num1 + num2); } else if (strcmp(tokens[i], "-") == 0) { num2 = pop(&s); num1 = pop(&s); push(&s, num1 - num2); } else if (strcmp(tokens[i], "*") == 0) { num2 = pop(&s); num1 = pop(&s); push(&s, num1 * num2); } else if (strcmp(tokens[i], "/") == 0) { num2 = pop(&s); num1 = pop(&s); push(&s, num1 / num2); } else if (strcmp(tokens[i], "sqrt") == 0) { num1 = pop(&s); push(&s, sqrt(num1)); } else { push(&s, atof(tokens[i])); } } return pop(&s); } // 将 Lisp 达式转化为逆波兰达式 void parse(char *expr, char **tokens, int *size) { char *token = strtok(expr, "()"); *size = 0; while (token != NULL) { tokens[(*size)++] = token; token = strtok(NULL, "()"); } } int main() { char expr[] = "(+ 1 2)"; char *tokens[STACK_SIZE]; int size; parse(expr, tokens, &size); double result = eval(tokens, size); printf("%s = %lf\n", expr, result); char expr2[] = "(sqrt (* x x))"; char *tokens2[STACK_SIZE]; int size2; parse(expr2, tokens2, &size2); double result2 = eval(tokens2, size2); printf("%s = %lf\n", expr2, result2); return 0; } ``` ### 回答2: C语言是一种面向过程、结构化的编程语言,而Lisp是一种基于列操作的函数式编程语言。要在C语言中实现对Lisp达式的求值,可以采用递归的方式来处理列。 首先,我们需要定义达式的数据结构。可以使用结构体来达式,包括两个属性:类型和值。类型可以用枚举类型来示,可以包括数字、运算符、变量等。值则根据类型的不同,有不同的示方式,比如数字类型可以用浮点数来示,运算符可以用字符串示。 接下来,定义一个递归的函数来求值达式。首先判断达式的类型,如果是数字类型,则直接返回该数字。如果是运算符类型,则根据运算符对达式的其他部分进行求值,并进行相应的运算。如果是变量类型,则返回相应的变量值。 在求值过程中,需要注意处理列的情况。如果达式是一个嵌套的列,则可以用递归的方式对列的元素进行求值。例如,对于达式 (+ 1 2),可以先求解 (+ 1 2) 子达式,然后再对子达式进行求值。 在C语言中实现Lisp达式求值需要考虑到Lisp的特性,比如函数的递归和列的嵌套。通过合理的数据结构和递归算法,可以实现对Lisp达式的求值。 ### 回答3: C语言是一种广泛应用于系统和应用程序开发的编程语言,它的语法和语义相对较为简单Lisp(即LISt Processing的简称)则是一种基于列的编程语言,它以达式为基本单位进行计算和求值。 在C语言中,处理Lisp达式的过程通常需要通过编写相应的解释器或编译器来完成。解释器的主要任务是逐个解析Lisp达式,并根据达式的结构和规则进行计算和求值。编译器则将Lisp达式转换为机器语言的形式,以便于直接执行。 要求值一个Lisp达式,我们可以分为以下几个步骤: 1. 解析达式:首先需要将Lisp达式分解为基本元素,如运算符、操作数和括号等。这可以通过递归方式来实现,从而逐层解析达式的嵌套结构。 2. 构建语法树:将解析后的达式构建成语法树,以便于后续的计算和求值操作。语法树由节点和边组成,每个节点代一个达式的元素,边示元素之间的关系。 3. 遍历语法树:通过深度优先搜索算法遍历语法树,从根节点开始依次对子节点进行计算和求值,直至到达叶子节点。 4. 计算和求值:根据不同的运算符和操作数,执行相应的计算和求值操作。这可能涉及到数值运算、逻辑运算、条件判断等。 5. 返回结果:根据达式的结果,将最终的计算结果返回给调用者或打印在屏幕上。 需要注意的是,C语言自身并没有原生支持Lisp达式求值的功能,因此我们需要通过自己编写相关的代码来实现。幸运的是,由于C语言的灵活性和强大的达能力,我们可以利用其丰富的数据结构和算法特性来实现一个简单Lisp达式求值器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值