首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让我的C语言BASIC解释器知道输入的是什么?

如何让我的C语言BASIC解释器知道输入的是什么?
EN

Stack Overflow用户
提问于 2011-05-20 17:17:39
回答 1查看 839关注 0票数 0

我正在尝试用C语言创建一个基本的解释器。我从一个用于数学计算的解释器开始(就像计算器一样,除了这里我可以给变量X赋值2 )。我的问题是,我不知道如何让我的解释器找到一些输入之间的差异。例如: 10设x= 10,这应该存储在一个数组中以备后用。设x= 10,这应该立即执行10 +1,这应该立即执行。

我如何修改我的解释器,让它知道这些事情?我不知道在哪里做修改,但我认为它应该在解析器中进行,所以我在这里发布了它。如果你想看其他的代码,尽管问。

代码语言:javascript
复制
//diddi

    /*
     * File: parser.c
     * --------------
     * This file implements a version of ReadExp that uses
     * conventional precedence rules.  Thus, the expression
     *
     *        x = 2 * x + y
     *
     * is interpreted as if it had been written
     *
     *        x = ((2 * x) + y))
     *
     * This language can be parsed using the following ambiguous
     * grammar:
     *
     *       E  ->  T
     *       E  ->  E op E
     *
     *       T  ->  integer
     *       T  ->  identifier
     *       T  ->  ( E )
     *
     * Unfortunately, this grammar is not sufficient by itself.  The
     * parser must also provide some way to determine what operators
     * take precedence over others.  Moreover, it must avoid the
     * problem of going into an infinite recursion of trying to read
     * an expression by reading an expression, and so on forever.
     *
     * To solve these problems, this implementation passes a numeric
     * value to the ReadE function that specifies the precedence
     * level for the current subexpression.  As long as ReadE finds
     * operators with a higher precedence, it will read in those
     * operators along with the following subexpression.  If the
     *

 precedence of the new operator is the same or lower than
 * the prevailing precedence, ReadE returns to the next higher
 * level in the recursive-descent parsing and reads the operator
 * there.
 */

#include <stdio.h>
#include <ctype.h>
#include "genlib.h"
#include "strlib.h"
#include "simpio.h"
#include "scanadt.h"
#include "parsering.h"
#include "exp.h"
#include "cmddisp.c"

/*
 * Implementation notes: ParseExp
 * ------------------------------
 * This function just calls ReadE to read an expression and then
 * checks to make sure no tokens are left over.
 */

expressionADT ParseExp(scannerADT scanner)
{
    expressionADT exp;

    exp = ReadE(scanner, 0);
    if (MoreTokensExist(scanner)) {
        Error("ParseExp: %s unexpected", ReadToken(scanner));
    }
    return (exp);
}

/*
 * Implementation notes: ReadE
 * Usage: exp = ReadE(scanner, prec);
 * ----------------------------------
 * This function reads an expression from the scanner stream,
 * stopping when it encounters an operator whose precedence is
 * less that or equal to prec.
 */

expressionADT ReadE(scannerADT scanner, int prec)
{
    expressionADT exp, rhs;
    string token;
    int newPrec;

    exp = ReadT(scanner, 0);
    while (TRUE) {
        token = ReadToken(scanner);
        newPrec = Precedence(token);
        if (newPrec <= prec) break;
        rhs = ReadE(scanner, newPrec);
        exp = NewCompoundExp(token[0], exp, rhs);
    }
    SaveToken(scanner, token);
    return (exp);
}

/*
 * Function: ReadT
 * Usage: exp = ReadT(scanner);
 * ----------------------------
 * This function reads a single term from the scanner by matching
 * the input to one of the following grammatical rules:
 *
 *       T  ->  integer
 *       T  ->  identifier
 *       T  ->  ( E )
 *
 * In each case, the first token identifies the appropriate rule.
 */

expressionADT ReadT(scannerADT scanner, int prec)
{
    expressionADT exp, rhs;
    string token;
    int newPrec;

    exp = ReadF(scanner);
    while (TRUE) {
        token = ReadToken(scanner);
        newPrec = Precedence(token);
        if (newPrec <= prec) break;
        rhs = ReadT(scanner, newPrec);
        exp = NewCompoundExp(token[0], exp, rhs);
    }
    SaveToken(scanner, token);
    return (exp);
}

int Precedence(string token)
{
    if (StringLength(token) > 1) return (0);
    switch (token[0]) {
      case '=': return (1);
      case '+': case '-': return (2);
      case '*': case '/': return (3);
      default:  return (0);
    }
}

expressionADT ReadF(scannerADT scanner)
{
    expressionADT exp;
    string token;

    token = ReadToken(scanner);
    if (StringEqual(token, "(")) {
        exp = ReadE(scanner, 0);
        if (!StringEqual(ReadToken(scanner), ")")) {
            Error("Unbalanced parentheses");
        }
    } else if (isdigit(token[0])) {
        exp = NewIntegerExp(StringToInteger(token));
    } else if (isalpha(token[0])) {
        exp = NewIdentifierExp(token);
    } else {
        Error("Illegal term in expression");
    }
    return (exp);

}
EN

回答 1

Stack Overflow用户

发布于 2011-05-20 17:27:09

最简单的方法是使用语法在解析之前执行一个步骤,该语法查看是否有行号(即后面跟着一个空格的整数),然后删除(记住它是什么,以便您可以将其存储在数组中),并将该行的其余部分交给解析器。在大多数解释器中,都有不止一个解析器在工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6069835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档