一道大学编译原理实验题,20点交,马上要交了,帮一下

img

扫描器可识别的单词包括:关键字、界符、标识符和常数(常数包括如:123  123.567  0.567   12.34e+23
要求常整数输出按十进制输出(测试数据中只有16进制与10进制整数),浮点数考虑到精度问题按输入格式输出(测试数据只有10进制浮点数)。同时使用科学计数法的数字都是浮点数。为降低难度,样例3给出一种边界情况供大家调试。
界符匹配按照从左向右贪心匹配最长界符的策略进行匹配。
判断字符常量及字符串常量单词,将字符和字符串常量分别保存进单独的常量表CT、ST。例如’a’、”OK”;同时字符串与字符常量均不考虑转义字符(""和带""的都不考虑)。
可以识别尚未定义的单词等。
    其中关键字表、界符表、标识符表、常整数表、常实数表、字符表、字符串表如下:(表中除关键词与界符表的表都可以接着编号继续扩展)

虽然说你是昨天晚上八点要交,但是,个人认为你可以把这个题目好好的研究一下,看到楼上那一大长串的代码,不知道是copy过来的还是自己写的。但总而言之,他是懂这个东西的,有什么不懂的可以去问一下楼上那个贴代码的大佬。然后在网上去找一找这种题目的解题思路,肯定会有原题的,现在的搜索引擎很强大,获人以鱼不如获人以渔。把这个题目搞明白,加油

卧槽 枯了,错亿,等等楼上的代码输出有问题嘛?我这边运行感觉没问题呀

可参考

https://www.renrendoc.com/paper/155334699.html

这个……楼上说的对

20点过了。。。

从左往右依次读取字符
然后与关键字等目标字符串进行比较

数字判断有问题,没有考虑16进制、浮点数和指数

数值类型需要考虑16进制、浮点数和指数


#include<bits/stdc++.h>
using namespace std;

//构造结构体---二元组
struct Two_tuples
{
  string type;//词法分析的类型
  string value;//词法分析的值
};

string input;//全局变量定义输入
Two_tuples result[200];//存放词法分析二元组
int k = 0;//输入二元组时访问下标
bool ans = true;//存放判断结果
int fh[101],zt[101];//符号栈,状态栈

bool target_judge(string input , string str) //判断是否和目标串匹配
{
  //首先匹配长度,看长度是否一致
  if(input.length()!=str.length()) return false;
  //长度一致,逐个匹配字符
  else
  {
    for(unsigned int i=0;i<str.length();i++)
    {
      if(input[i]!=str[i]) return false;
    }
    return true;
  }
} 

void input_cf() //输入词法分析的二元组
{
  string str;
  while(cin>>str)
  {
    //定义指针访问
    const char *d = "(),";
    char *p;
    //临时存放字符串,便于分割处理
    char buf[101];
    strcpy(buf,str.c_str()); //字符串转成数组
    //开始处理每个二元组
    p = strtok(buf,d);
    int i = 0;
    //把输入的二元组存储到结构体中
    while(p)
    {
      if(i%2==0) result[k].type = p;
      else result[k].value = p;
      i++;
      p = strtok(NULL,d);
    }
    k++;
  }
  result[k].type = "#";
}
 

//在LR分析表中判断是哪个目标串(0--8)
int chart(string str)
{
  if(target_judge("plus",str)) return 0;
  else if(target_judge("minus",str)) return 1;
  else if(target_judge("times",str)) return 2;
  else if(target_judge("slash",str)) return 3;
  else if(target_judge("lparen",str)) return 4;
  else if(target_judge("rparen",str)) return 5;
  else if(target_judge("ident",str)) return 6;
  else if(target_judge("number",str)) return 7;
  else if(target_judge("#",str)) return 8;
  else return -1;
} 

//ETF归约(9--11)
int gy_1(int num)
{
  //E---表达式
  if(num - 100 == 1) return 9;
  else if(num - 100 == 2) return 9;
  else if(num - 100 == 3) return 9;
  //T---项
  else if(num - 100 == 4) return 10;
  else if(num - 100 == 5) return 10;
  else if(num - 100 == 6) return 10;
  //F---因子
  else if(num - 100 == 7) return 11;
  else if(num - 100 == 8) return 11;
  else if(num - 100 == 9) return 11; 
  else return -1;
} 

//gy_1中规约后约几项
int gy_2(int num)
{
  //E---表达式
  if(num - 100 == 1) return 1;
  else if(num - 100 == 2) return 3;
  else if(num - 100 == 3) return 3;
  //T---项
  else if(num - 100 == 4) return 1;
  else if(num - 100 == 5) return 3;
  else if(num - 100 == 6) return 3;
  //F---因子
  else if(num - 100 == 7) return 3;
  else if(num - 100 == 8) return 1;
  else if(num - 100 == 9) return 1; 
  else return -1;
} 

int main()
{
  input_cf(); //输入词法分析结果
  //LR分析表,其中大于100为归,小于100为移进
  int LR_chart[17][12]={{0,0,0,0,4,0,5,6,0,1,2,3},
                        {7,8,0,0,0,0,0,0,100,0,0,0},
                        {101,101,9,10,0,1,0,0,101,0,0,0},
                        {104,104,104,104,0,104,0,0,104,0,0,0},
                        {0,0,0,0,4,0,5,6,0,11,2,3},
                        {108,108,108,108,0,108,0,0,108,0,0,0},
                        {109,109,109,109,0,109,0,0,109,0,0,0},
                        {0,0,0,0,4,0,5,6,0,0,12,3},
                        {0,0,0,0,4,0,5,6,0,0,13,3},
                        {0,0,0,0,4,0,5,6,0,0,0,14},
                        {0,0,0,0,4,0,5,6,0,0,0,15},
                        {7,8,0,0,0,16,0,0,0,0,0,0},
                        {102,102,9,10,0,102,0,0,102,0,0,0},
                        {103,103,9,10,0,103,0,0,103,0,0,0},
                        {105,105,105,105,0,105,0,0,105,0,0,0},
                        {106,106,106,106,0,106,0,0,106,0,0,0},
                        {107,107,107,107,0,107,0,0,107,0,0,0}}; 
  int i = 0 , j = 0; //访问栈下标
  fh[0] = 8 , zt[0] = 0;//初值
  while(LR_chart[zt[j]][chart(result[i].type)]!=100)
  {
    //判断错误
    if(LR_chart[zt[j]][chart(result[i].type)]==0)
    {
      ans = false;
      break;
    }
    //移进
    else if(LR_chart[zt[j]][chart(result[i].type)]<100)
    {
      j++;
      zt[j] = LR_chart[zt[j-1]][chart(result[i].type)];
      fh[j] = chart(result[i].type);
      i++;
    }
    //归约
    else
    {
      int res = LR_chart[zt[j]][chart(result[i].type)];
      j -= gy_2(res);
      j++;
      //移入符号栈,状态栈
      fh[j] = gy_1(res);
      zt[j] = LR_chart[zt[j-1]][gy_1(res)];
      //判断错误
      if(zt[j]==0)
      {
        ans = false;
        break;
      }
    }
  }
  if(ans == true) cout<<"Yes,it is correct."<<endl;
  else cout<<"No,it is wrong."<<endl;
  return 0;
}

直接喷老师学的都是什么年代的技术 ,还不用python

编译原理主要是要理解如何把高级语言翻译为机器语言,重在翻译,高级语言有它的语法、语义、时序规则,机器语言同样是这三者,掌握方法而不是题目本身,学习没有捷径可走,回答者尽量不要问者问啥就给出啥答案,可以给出解题思路,而不是代码,代码老师会讲
本题的两个关键点,一个是识别,对输入的字符串进行扫描,然后分类,根据题目规则赋予其相应含义
第二个段建点是理解变量值如何存储,又如何转化为原来的输入
切记不要抓小放大,仅仅局限于题目的解答。

要求常整数输出按十进制输出(测试数据中只有16进制与10进制整数),浮点数考虑到精度问题按输入格式输出(测试数据只有10进制浮点数)。
16进制浮点数与十进制的转化步骤:
对于大小为32-bit的浮点数(32-bit为单精度,64-bit浮点数为双精度,80-bit为扩展精度浮点数),
1、其第31 bit为符号位,为0则表示正数,反之为复数,其读数值用s表示;
2、第30~23 bit为幂数,其读数值用e表示;
3、第22~0 bit共23 bit作为系数,视为二进制纯小数,假定该小数的十进制值为x;
则按照规定,该浮点数的值用十进制表示为:= (-1)^s * (1 + x) * 2^(e - 127)


#include <stdio.h>
#include <math.h>
//十六进制数转浮点数通用方法
float Hex2Float(unsigned long number)
{
    unsigned int sign = (number & 0x80000000) ? -1 : 1;//三目运算符
    unsigned int exponent = ((number >> 23) & 0xff) - 127;//先右移操作,再按位与计算,出来结果是30到23位对应的e
    float mantissa = 1 + ((float)(number & 0x7fffff) / 0x7fffff);//将22~0转化为10进制,得到对应的x
    return sign * mantissa * pow(2, exponent);
}
//测试用例
int main()
{
    
    unsigned long a = 0x404FC593;//16进制404FC593
    float result = Hex2Float(a);
 
    printf("result = %f \n", result);
    return 0;
}

你能告诉我你那个学校的么?