2011-05-20 7 views
0

私は基本的なインタプリタをC言語で作成しようとしています。数学計算のためのインタプリタから始めました。例えば、図2)。私の問題は、通訳者にいくつかのインプットの違いを見つける方法を知らないことです。例: 10 LET x = 10これは後で使用するために配列に格納する必要があります。 LET x = 10、これはすぐに実行する必要があります 10 + 1、これはすぐに実行する必要があります。どのように私の基本的なインタプリタをC言語で入力したかを知るために

これらのことを知るようにインタープリタを変更するにはどうすればよいですか?変更を加える場所はわかりませんが、パーサで作成する必要があるので、ここに投稿しています。他のコードを見たい場合は、ただ聞いてください。

//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); 

} 

答えて

0

最も簡単な方法は、行番号があるかどうかを確認するために見える文法を使用して解析する前にステップを実行することです(つまり、スペースが続く整数)、その後は削除されます(それはそうすることができます何であったか覚えてそれをあなたの配列に格納します)、残りの行をパーサに渡します。ほとんどのインタプリタでは、複数のパーサが動作しています。

関連する問題