如何在没有解析器生成器的情况下用C或Objective-C编写解析器?

| 我正在尝试使用C或Objective-C制作一个可以接受字符串的计算器
8/2+4(3*9)^2
并返回答案2920。我不希望使用Lex或Yacc这样的生成器,因此我想从头开始对其进行编码。我应该怎么做呢?除了《龙书》之外,是否有涉及该主题的推荐文本?     
已邀请:
尝试这个: http://en.wikipedia.org/wiki/Shunting-yard_algorithm     
Dave DeLong的DDMathParser类可以为您节省大量时间和麻烦。     
如果我没记错的话,可以通过两个堆栈来解决此问题,一个堆栈用于运算符,另一个堆栈用于操作数。
// OPTR stack: store operators
// OPND stack: store operands
// OP: predefined set of operators
OperandType EvaluateExpression(){  

   InitStack(OPET);Push(OPTR,\'#\');  
   initStack(OPND);c=getchar();  
   while(c!=\'#\'||GetTop(OPTR)!=\'#\'){  
     if(!In(c,OP)){Push((OPND,c);c=getchar();} //Push to stack if not operator
     else 
       switch(Precede(GetTop(OPTR),c){
         //Top element in stack has a lower priority  
         case \'<\':
               Push(OPTR,c); c=getch();  
               break;
         case \'=\':
               Pop(OPTR,x); c=getch();  
               break;
         //Pop top element and push back the calculated result 
         case \'>\':
               Pop(OPTR,theta);  
               Pop(OPND,b); Pop(OPND,a);  
               Push(OPND,Operate(a,theta,b));  
               break;  
         } 
     } 
     return GetTop(OPND);
   }
    
已经提到过调车场算法。另一个经典的例子是简单的递归下降。这是我多年前写的一篇相当短的文章:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void expression(void);

void show(int ch) { 
    putchar(ch);
    putchar(\' \');
}

int token() { 
    int ch;
    while (isspace(ch=getchar()))
        ;
    return ch;
}

void factor() { 
    int ch = token();
    if (ch == \'(\') {
        expression();
        ch = token();
        if (ch != \')\') {
            fprintf(stderr, \"Syntax error. Expected close paren, found: %c\\n\", ch);
            exit(EXIT_FAILURE);
        }
    }
    else
        show(ch);
}

void term() { 
    int ch;
    factor();
    ch = token();
    if (ch == \'*\' || ch == \'/\') {
        term();
        show(ch);
    }
    else
        ungetc(ch, stdin);
}

void expression() {
    int ch;
    term();
    ch = token();
    if (ch == \'-\' || ch==\'+\') {
        expression();
        show(ch);
    }
    else 
        ungetc(ch, stdin);
}

int main(int argc, char **argv) {
    expression();
    return 0;
}
注意,这个特定的只是解析输入,并将其转换为RPN形式。如果您想解释结果,则可以替换为打印每个操作数/运算符,而实际上是评估表达式那部分的结果。     
我认为这接近您想要的: http://www.codeproject.com/KB/recipes/alxparser.aspx     
我在大学三年级的CSE340:编程语言介绍中做到了这一点。因此,如果您真的想从头开始编写解析器,请做好准备,使其成为“一个学期的项目”。 您需要标记化,解析,构建抽象表达式树,求值等。 我们使用了Louden的《编程语言:原理与实践》。我喜欢尽管它并没有带您完成整个实现过程,但是做得最好。 当然,这不只是“从头开始编写”。您需要制作语法,然后构建解析器来处理规则……除了学习活动之外,我不确定为什么你想这样做。     
使用Objective-C NSLinguisticTagger可能是一个很好的解决方案
- (void)enumerateTagsInRange:(NSRange)range 
                      scheme:(NSString *)tagScheme
                     options:(NSLinguisticTaggerOptions)opts 
                  usingBlock:(void (^)(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop))block
    

要回复问题请先登录注册