zoukankan      html  css  js  c++  java
  • 语义分析

    实验目的

    通过上机实验,加深对语法制导翻译的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

    实验内容

    对给定的程序通过语义分析器能够判断语句串是否正确。正确则输出三地址指令形式的四元式代码,错误则抛出错误信息。

    设计思想

    1)输入待分析的字符串。

    语法如下:

    a.关键字:begin,if,then,while,do,end.

    b.运算符和界符::= + - * / < <= > >= <> = ; ( ) #

    c.其他单词是标识符(ID)和整形常数(NUM):ID=letter(letter|digit)*,NUM=digitdigit*

    d.空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

    2)扫描字符串,采用递归向下进行分析。

    主要函数如下:

    a.scaner()//词法分析函数,char token[8]用来存放构成单词符号的字符串;

    b.parser()//语法分析,在语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。只对表达式、赋值语句进行翻译。

    c.emit(char *result,char *arg1,char *op,char *ag2)//该函数功能是生成一个三地址语句返回四元式表中。

    d.char *newtemp()//该函数返回一个新的临时变量名,临时变量名产生的顺序为T1,T2,…。

    【实验要求】

    四元式表的结构如下:

    struct {char result[8];

    char ag1[8];

    char op[8];

    char ag2[8];

    }quad[20];

    3)输出为三地址指令形式的四元式序列。

    例如:语句串begin  a:=2+3*4;x:=(a+b)/c;end#,

    输出的三地址指令如下:

    t1=3*4

    t2=2+t1

    a=t2

    t3=a+b

    t4=t3/c

    x=t4

     

    代码:

    #include "stdio.h"
    
    #include "string.h"
    
    char prog[100], token[8], ch;
    
    char *rwtab[6] = { "begin", "if", "then", "while", "do", "end" };
    
    int syn, p, m, n, sum, q;
    
    int kk;
    
    struct {
    
    char result1[8];
    
    char ag11[8];
    
    char op1[8];
    
    char ag21[8];
    
    } quad[20];
    
    char *factor();
    
    char *expression();
    
    int yucu();
    
    char *term();
    
    int statement();
    
    int lrparser();
    
    char *newtemp();
    
    scaner();
    
    emit(char *result, char *ag1, char*op, char *ag2);
    
     
    
    main()
    
    {
    
    int j;
    
    q = p = kk = 0;
    
    printf("
    **************************************");
    
    printf("
    please input a string (end with'#'): ");
    
    do
    
    {
    
    scanf_s("%c", &ch);
    
    prog[p++] = ch;
    
    } while (ch != '#');
    
    p = 0;
    
    scaner();
    
    lrparser();
    
    if (q>19)printf(" too longsentense!
    ");
    
    else for (j = 0; j<q; j++)printf("   %s = %s%s %s 
    
    ", quad[j].result1, quad[j].ag11, quad[j].op1, quad[j].ag21);
    
    getchar();
    
    }
    
     
    
    int lrparser()
    
    {
    
    int schain = 0;
    
    kk = 0;
    
    if (syn == 1)
    
    {
    
    scaner();
    
    schain = yucu();
    
    if (syn == 6)
    
    {
    
    scaner();
    
    if ((syn == 0) && (kk == 0)) printf("Success!
    ");
    
    }
    
    else {
    
    if (kk != 1)printf("short of 'end'!
    ");
    
    kk = 1;
    
    getchar();
    
    exit(0);
    
    }
    
    }
    
    else {
    
    printf("short of 'begin' !
    ");
    
    kk = 1;
    
    getchar();
    
    exit(0);
    
    }
    
    return (schain);
    
    }
    
     
    
    int yucu()
    
    {
    
    int schain = 0;
    
    schain = statement();
    
    while (syn == 26)
    
    {
    
    scaner();
    
    schain = statement();
    
    }
    
    return (schain);
    
    }
    
     
    
    int statement()
    
    {
    
    char tt[8], eplace[8];
    
    int schain = 0;
    
    if (syn == 10)
    
    {
    
    strcpy_s(tt, 255, token);
    
    scaner();
    
    if (syn == 18)
    
    {
    
    scaner();
    
    strcpy_s(eplace, 255, expression());
    
    emit(tt, eplace, "", "");
    
    schain = 0;
    
    }
    
    else {
    
    printf("short of sign ':='!
    ");
    
    kk = 1;
    
    getchar();
    
    exit(0);
    
    }
    
    return (schain);
    
    }
    
    }
    
     
    
    char *expression()
    
    {
    
    char *tp, *ep2, *eplace, *tt;
    
    tp = (char *)malloc(12);
    
    ep2 = (char *)malloc(12);
    
    eplace = (char *)malloc(12);
    
    tt = (char *)malloc(12);
    
    strcpy_s(eplace, 255, term());
    
    while ((syn == 13) || (syn == 14))
    
    {
    
    if (syn == 13)strcpy_s(tt, 255, "+");
    
    else strcpy_s(tt, 255, "-");
    
    scaner();
    
    strcpy_s(ep2, 255, term());
    
    strcpy_s(tp, 255, newtemp());
    
    emit(tp, eplace, tt, ep2);
    
    strcpy_s(eplace, 255, tp);
    
    }
    
    return (eplace);
    
    }
    
     
    
    char *term()
    
    {
    
    char *tp, *ep2, *eplace, *tt;
    
    tp = (char *)malloc(12);
    
    ep2 = (char *)malloc(12);
    
    eplace = (char *)malloc(12);
    
    tt = (char *)malloc(12);
    
    strcpy_s(eplace, 255, factor());
    
    while ((syn == 15) || (syn == 16))
    
    {
    
    if (syn == 15)strcpy_s(tt, 255, "*");
    
    else strcpy_s(tt, 255, "/");
    
    scaner();
    
    strcpy_s(ep2, 255, factor());
    
    strcpy_s(tp, 255, newtemp());
    
    emit(tp, eplace, tt, ep2);
    
    strcpy_s(eplace, 255, tp);
    
    }
    
    return (eplace);
    
    }
    
     
    
    char *factor()
    
    {
    
    char *fplace;
    
    fplace = (char *)malloc(12);
    
    strcpy_s(fplace, 255, "");
    
    if (syn == 10)
    
    {
    
    strcpy_s(fplace, 255, token);
    
    scaner();
    
    }
    
    else if (syn == 11)
    
    {
    
    itoa(sum, fplace, 10);
    
    scaner();
    
    }
    
    else if (syn == 27)
    
    {
    
    scaner();
    
    fplace = expression();
    
    if (syn == 28) scaner();
    
    else {
    
    printf("error on ')'!
    ");
    
    kk = 1;
    
    getchar();
    
    exit(0);
    
    }
    
    }
    
    else {
    
    printf("error on '(' !
    ");
    
    kk = 1;
    
    getchar();
    
    exit(0);
    
    }
    
    return (fplace);
    
    }
    
     
    
    char *newtemp()
    
    {
    
    char *p;
    
    char m[8];
    
    p = (char *)malloc(8);
    
    kk++;
    
    itoa(kk, m, 10);
    
    strcpy_s(p + 1, 255, m);
    
    p[0] = 't';
    
    return(p);
    
    }
    
     
    
    scaner()
    
    {
    
    sum = 0;
    
    for (m = 0; m<8; m++)token[m++] = NULL;
    
    m = 0;
    
    ch = prog[p++];
    
    while (ch == ' ')ch = prog[p++];
    
    if (((ch <= 'z') && (ch >= 'a')) || ((ch <= 'Z') && (ch >= 'A')))
    
    {
    
    while (((ch <= 'z') && (ch >= 'a')) || ((ch <= 'Z') && (ch >= 'A')) || ((ch >= '0') && (ch <= '9')))
    
    {
    
    token[m++] = ch;
    
    ch = prog[p++];
    
    }
    
    p--;
    
    syn = 10;
    
    token[m++] = '';
    
    for (n = 0; n<6; n++)
    
    if (strcmp(token, rwtab[n]) == 0)
    
    {
    
    syn = n + 1;
    
    break;
    
    }
    
    }
    
    else if ((ch >= '0') && (ch <= '9'))
    
    {
    
    while ((ch >= '0') && (ch <= '9'))
    
    {
    
    sum = sum * 10 + ch - '0';
    
    ch = prog[p++];
    
    }
    
    p--;
    
    syn = 11;
    
    }
    
    else switch (ch)
    
    {
    
    case '<':m = 0;
    
    ch = prog[p++];
    
    if (ch == '>')
    
    {
    
    syn = 21;
    
     
    
    }
    
    else if (ch == '=')
    
    {
    
    syn = 22;
    
    }
    
    else
    
    {
    
    syn = 20;
    
    p--;
    
    }
    
    break;
    
    case '>':m = 0;
    
    ch = prog[p++];
    
    if (ch == '=')
    
    {
    
    syn = 24;
    
    }
    
    else
    
    {
    
    syn = 23;
    
    p--;
    
    }
    
    break;
    
    case ':':m = 0;
    
    ch = prog[p++];
    
    if (ch == '=')
    
    {
    
    syn = 18;
    
    }
    
    else
    
    {
    
    syn = 17;
    
    p--;
    
    }
    
    break;
    
    case '+': syn = 13; break;
    
    case '-': syn = 14; break;
    
    case '*': syn = 15; break;
    
    case '/': syn = 16; break;
    
    case '(': syn = 27; break;
    
    case ')': syn = 28; break;
    
    case '=': syn = 25; break;
    
    case ';': syn = 26; break;
    
    case '#': syn = 0; break;
    
    default: syn = -1; break;
    
     
    
    }
    
    }
    
     
    
    emit(char *result, char *ag1, char*op, char *ag2)
    
    {
    
    strcpy_s(quad[q].result1, 255, result);
    
    strcpy_s(quad[q].ag11, 255, ag1);
    
    strcpy_s(quad[q].op1, 255, op);
    
    strcpy_s(quad[q].ag21, 255, ag2);
    
    q++;
    
    }
    

      

    运行截图:

  • 相关阅读:
    文本文件、二进制文件
    trunc()
    字符集、编码
    windows注册表:扫盲
    decode() & sign()
    移动前端工作的那些事前端制作之自适应制作篇
    css hack知识详解
    IE6兼容性大全
    JS正则匹配入门基础!
    [转载]Javascript中批量定义CSS样式 cssText属性
  • 原文地址:https://www.cnblogs.com/dixingchen/p/14201080.html
Copyright © 2011-2022 走看看