간이 계산기(3) - 확장(괄호 및 음수 지원)
5574 단어 수필.
#ifndef _LEX_H
#define _LEX_H
typedef enum {
TOKEN_BAD,
TOKEN_NUM,
TOKEN_OP_ADD,
TOKEN_OP_SUB,
TOKEN_OP_MUL,
TOKEN_OP_DIV,
TOKEN_OP_PAREN_LEFT,
TOKEN_OP_PAREN_RIGHT,
TOKEN_LINE_END,
} TokenKind;
#define MAX_TOKEN_SIZE (100)
typedef struct {
TokenKind kind;
double value;
char str[MAX_TOKEN_SIZE];
} Token;
void SetLine(char *file);
void GetToken(Token *token);
#endif
Parser에서.c의 ParsePrimaryExp 함수에는 해석 음수와 괄호 논리 parser가 추가됩니다.c
#include "parser.h"
static Token stLookAheadTok;
static int stLookAheadTokExist;
static void MyGetToken(Token *tok)
{
if (stLookAheadTokExist) {
*tok = stLookAheadTok;
stLookAheadTokExist = 0;
} else {
GetToken(tok);
}
}
static void UngetToken(Token *tok)
{
stLookAheadTok = *tok;
stLookAheadTokExist = 1;
}
static double ParsePrimaryExp()
{
Token tok;
double val = 0.0;
int minusFlag = 0;
MyGetToken(&tok);
// negative NUM
if (tok.kind == TOKEN_OP_SUB) {
minusFlag = 1;
} else {
UngetToken(&tok);
}
MyGetToken(&tok);
if (tok.kind == TOKEN_NUM) {
val = tok.value;
} else if (tok.kind == TOKEN_OP_PAREN_LEFT) { // Support ( )
val = ParseExp();
MyGetToken(&tok);
if (tok.kind != TOKEN_OP_PAREN_RIGHT) {
fprintf(stderr, "missing ')' error.
");
exit(1);
}
} else {
// fprintf(stderr, "syntax error.
");
// exit(1);
// return 0.0; // make compiler happy
UngetToken(&tok);
}
return minusFlag ? (-val) : val;
}
static double ParseTerm()
{
double v1;
double v2;
Token tok;
v1 = ParsePrimaryExp();
for (;;) {
MyGetToken(&tok);
if (tok.kind != TOKEN_OP_MUL
&& tok.kind != TOKEN_OP_DIV) {
UngetToken(&tok);
break;
}
v2 = ParsePrimaryExp();
if (tok.kind == TOKEN_OP_MUL) {
v1 *= v2;
} else if (tok.kind == TOKEN_OP_DIV) {
v1 /= v2;
}
}
return v1;
}
double ParseExp()
{
double v1;
double v2;
Token tok;
v1 = ParseTerm();
for (;;) {
MyGetToken(&tok);
if (tok.kind != TOKEN_OP_ADD
&& tok.kind != TOKEN_OP_SUB) {
UngetToken(&tok);
break;
}
v2 = ParseTerm();
if (tok.kind == TOKEN_OP_ADD) {
v1 += v2;
} else if (tok.kind == TOKEN_OP_SUB) {
v1 -= v2;
} else {
UngetToken(&tok);
}
}
return v1;
}
double ParseLine()
{
double val;
stLookAheadTokExist = 0;
val = ParseExp();
return val;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
피폴라치 수열=>다양한 방법의 비교(분치, 귀속, 동적 기획/추이)이렇게 하면 피폴라치 수열에는 여러 가지 해법이 있을 수 있다. 일반적인 귀속 방법에는 많은 중복 계산이 존재한다.효율은 자연히 매우 낮다.예를 들어 f(n-1)를 계산할 때 이미 f(n-2)를 계산해 냈지만 귀환은...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.