编译器实践三 之 针对算术表达式的语法分析器

编译器实践三 之 针对算术表达式的语法分析器

大家好,又见面了,我是全栈君。

该算术表达式的上下文无关文法是:

E -> E + T

   | E – T

   | T

T -> T * F

   | T / F

   | F

F -> num

   | (E)

部分代码来自MOOC

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

void parse_F();
void parse_T();
void parse_E();
void error (char *want, char got);

int i;
char *str = 0;

void error (char *want, char got)
{
  fprintf (stderr, "Compling this expression:\n%s\n", str);
  int j = i;
  while (j--)
    fprintf (stderr, " ");
  fprintf (stderr, "^\n");
  fprintf (stderr, "Syntax error at position: %d\n"
           "\texpecting: %s\n"
           "\tbut got  : %c\n",
           i, want, got);
  exit (0);
  return;
}

void parse_F()
{
  char c = str[i];
  if (isdigit(c)){
    i++;
    return;
  }
  if (c=='('){
    i++;
    parse_E();
    c = str[i];
    if (c==')'){
      i++;
      return;
    }
    error ("\')\'", c);
    return;
  }
  error ("\'0-9\' or \'(\'", c);
  return;
}


void parse_T()
{
  parse_F();
  char c = str[i];
  while (c=='*' || c =='/'){
    i++;
    parse_F();
    c = str[i];
  }
  return;
}

void parse_E()
{
  parse_T();
  char c = str[i];
  while (c=='+' || c == '-'){
    i++;
    parse_T();
    c = str[i];
  }
  return;
}

void parse (char *e)
{
  str = e;
  i = 0;
  parse_E();
  if (str[i]=='\0')
    return;
  error ("\'+\' or '\\0\'", str[i]);
  return;
}
///////////////////////////////////////////////
// Your job:
// Add some code into the function parse_E() and
// parse_T to parse "-" and "/" correctly.
// When you finish your task, NO error message
// should be generated.
// Enjoy! :-P
int main (char argc, char **argv)
{
  // There are the following rules on an expression:
  //   1. Every expression is represented as a string;
  //   2. integers are non-negative;
  //   3. integers are between 0-9.
  char *e;

  e = "(2)";
  parse(e);

  e = "(3+4*5))";
  parse(e);

  e = "(8-2)*3";
  parse(e);

  e = "(8-2)/3";
  parse(e);
  
  return 0;
}


与君共勉

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116060.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月26日 下午4:00
下一篇 2022年1月26日 下午5:00


相关推荐

  • 微博开放平台api使用[通俗易懂]

    微博开放平台api使用[通俗易懂]前言:微博开放平台提供了微博数据的api接口,不仅可以直接通过api调用微博服务发布微博查询微博,更重要的是,可以在自己的网站上获得新浪微博api的授权,调用微博的某些内容,就好像我们再网站中看到好文

    2022年8月1日
    17
  • VLAD和MultiVLAD

    VLAD和MultiVLADVLAD 原理 1 原始的 VLAD 设有一个特征数据集为 每个特征向量 xi x i 都是 dd 维的向量 比如提取许多幅图像的 SIFT 特征 将这些 SIFT 特征组成上述集合 这里讲的词袋模型并不关心各幅图像中 SIFT 特征的个数及顺序 1 聚类 clustering 首先采用 K means 等聚类算法将 n 个 d 维的特征聚类成 k 类 保存得到的类中心向量集合 和每个特征向量 x i 所在的类别编号 assignme

    2026年3月17日
    2
  • 微信小程序中-[渲染层网络层错误] pages/card/card.wxss 中的本地资源图片无法通过 WXSS 获取-解决办法

    微信小程序中-[渲染层网络层错误] pages/card/card.wxss 中的本地资源图片无法通过 WXSS 获取-解决办法1、报错原由微信小程序使用background-image运行时报错pages/index/index.wxss中的本地资源图片无法通过WXSS获取,可以使用网络图片,或者base64,或者使用标签。小程序样式中不允许小程序路径2、解决方法1.使用图片的网络路径background:url(‘http://1812.img.pp.sohu.com.cn/images/blog/2009/11/18/18/8/125b6560a6ag214.jpg’);2.base64将图

    2022年6月24日
    48
  • Python代码缩进的使用方法_python退格快捷键

    Python代码缩进的使用方法_python退格快捷键和其它程序设计语言(如Java、C语言)采用大括号“{}”分隔代码块不同,Python采用代码缩进和冒号(:)来区分代码块之间的层次。在Python中,对于类定义、函数定义、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始,而缩进的结束则表示此代码块的结束。注意,Python中实现对代码的缩进,可以使用空格或者Tab键实现。但无论是手动敲空格,还是…

    2022年8月31日
    3
  • java 中鼠标事件_Java中的鼠标事件

    java 中鼠标事件_Java中的鼠标事件任何组件上都可以发生鼠标事件 如 鼠标进进组件 退出组件 在组件上方单击鼠标 拖动鼠标等都发生鼠标事件 也就是说 组件可以成为发生鼠标事件的事件源 1 使用 MouseListene 接口处理鼠标事件使用 MouseListene 接口可以处理 5 种操纵发生的鼠标事件 1 在事件源上按下鼠标键 mousePressed MouseEvent 2 在事件源上开释鼠标键 mouseRelease M

    2026年3月17日
    2
  • 请简述list,set,map类型的集合的各自特点_list与set的区别

    请简述list,set,map类型的集合的各自特点_list与set的区别List、Map、Set的区别与联系一、结构特点List和Set是存储单列数据的集合,Map是存储键值对这样的双列数据的集合;List中存储的数据是有顺序的,并且值允许重复;Map中存储的数据是无序的,它的键是不允许重复的,但是值是允许重复的;Set中存储的数据是无顺序的,并且不允许重复,但元素在集合中的位置是由元素的hashcode决定,即位置是固定的(Set集合是根据hashcod…

    2025年9月25日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号