词法、语法、语义分析实验

本文详细探讨了词法分析、语法分析和语义分析的实验过程,涵盖了从源代码到可理解形式的关键步骤。

一、词法分析

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char *rwtab[6]={"begin","if","then","while","do","end"};
//syn:单词符号的种别码;
//token:单词符号的字符串
//sum:整数
char token[16];
int sum,syn;
char program[110],ch;//输入程序,单个字符
int p,m;//下标
void scanner(){
    //整数,字符(串),其他
    for(int i=0; i<16; i++) {
        token[i]=NULL;
    }
    ch=program[p++];
    while(ch==' '){
        ch=program[p];
        p++;
    }
    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
        m=0;
        while((ch>='a'&&ch<'z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')){
            token[m++]=ch;
            ch=program[p++];
        }
        token[m++]='\0';
        p--;
        syn=10;
        for(int i=0; i<6; i++) {
            if(strcmp(token, rwtab[i])==0) {
                syn=i+1;
                break;
            }
        }
    }
    else if(ch>='0' && ch<='9') {
        sum=0;
        while(ch>='0' && ch<='9') {
            sum=sum*10+ch-'0';
            ch=program[p++];
        }
        p--;
        syn=11;
        if(sum>65536)
            syn=-1;
    }
    else switch(ch) {
        case '+':syn=13; token[0]='+';  break;
        case '-':syn=14; token[0]='-';break;
        case '*':syn=15; token[0]='*'; break;
        case '/':syn=16; token[0]='/'; break;
        case ':':m=0; token[m++]=ch;
            ch=program[p++];
            if(ch=='=') {
                token[m++]=ch;
                syn=18;
            }
            else {
                syn=17;
                p--;
            }
            break;
        case '<':m=0; token[m++]=ch;
            ch=program[p++];
            if(ch=='>') {
                token[m++]=ch;
                syn=21;
            }
            else if(ch=='=') {
                token[m++]=ch;
                syn=22;
            }
            else {
                syn=20;
                p--;
            }
            break;
        case '>':m=0; token[m++]=ch;
            ch=program[p++];
            if(ch=='=') {
                token[m++]=ch;
                syn=24;
            }
            else {
                syn=23;
                p--;
            }
            break;
        case '=':syn=25; token[0]=ch;break;
        case ';':syn=26; token[0]=ch;break;
        case '(':syn=27; token[0]=ch;break;
        case ')':syn=28; token[0]=ch;break;
        case '#':syn=0; token[0]=ch;break;
        default: syn=-1;break;

    }
}
int main()
{
    p=0;
    printf("please input string:\n");
    do{
        ch=cin.get();
        program[p++]=ch;
    }while(ch!='#');
    p=0;
    do {
        scanner();
        switch(syn) {
            case 11:cout<<"<"<<syn<<","<<sum<<">"<<endl; break;
            case -1:cout<<"Error"<<endl; break;
            default:cout<<"<"<<syn<<","<<token<<">"<<endl; break;
        }
    }while(syn!=0);
    return 0;
}

二、语法分析

#include <iostream>
#include <cs
【问题描述】 请根据给定的文法设计并实现词法分析程序,从源程序中识别出单词,记录其单词类别和单词值,输入输出及处理要求如下: (1)数据结构和与语法分析程序的接口请自行定义;类别码需按下表格式统一定义; (2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output.txt(注意不要写错文件名),结果文件中每行按如下方式组织: 单词类别码 单词的字符/字符串形式(中间仅用一个空格间隔) 单词的类别码请统一按如下形式定义: 单词名称 类别码 单词名称 类别码 单词名称 类别码 单词名称 类别码 标识符 IDENFR else ELSETK - MINU = ASSIGN 整形常量 INTCON switch SWITCHTK * MULT ; SEMICN 字符常量 CHARCON case CASETK / DIV , COMMA 字符串 STRCON default DEFAULTTK < LSS ( LPARENT const CONSTTK while WHILETK GRE [ LBRACK char CHARTK scanf SCANFTK >= GEQ ] RBRACK void VOIDTK printf PRINTFTK == EQL { LBRACE main MAINTK return RETURNTK != NEQ } RBRACE if IFTK + PLUS : COLON 【输入形式】testfile.txt中的符合文法要求的测试程序。 【输出形式】要求将词法分析结果输出至output.txt中。 【特别提醒】(1)读取的字符串要原样保留着便于输出,特别是数字,这里输出的并不是真正的单词值,其实是读入的字符串,单词值需另行记录。 (2)本次作业只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。 (3)在今后的错误处理作业中,需要输出错误的行号,在词法分析的时候注意记录该信息。 (4)单词的类别和单词值以及其他关注的信息,在词法分析阶段获取后,后续的分析阶段会使用,请注意记录;当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。 【文法定义】请到“2020年文法定义(用于查看文法,不计入成绩)”作业中查看文法 【样例输入】 coNst int cONst1 = 001, const2 = -100; const char const3 = '_'; int change1; char change3; int gets1(int var1,int var2){ change1 = var1 + var2; return (change1); } void main(){ printf("Hello World"); printf(gets1(10, 20)); } 【样例输出】 CONSTTK coNst INTTK int IDENFR cONst1 ASSIGN = INTCON 001 COMMA , IDENFR const2 ASSIGN = MINU - INTCON 100 SEMICN ; CONSTTK const CHARTK char IDENFR const3 ASSIGN = CHARCON _ SEMICN ; INTTK int IDENFR change1 SEMICN ; CHARTK char IDENFR change3 SEMICN ; INTTK int IDENFR gets1 LPARENT ( INTTK int IDENFR var1 COMMA , INTTK int IDENFR var2 RPARENT ) LBRACE { IDENFR change1 ASSIGN = IDENFR var1 PLUS + IDENFR var2 SEMICN ; RETURNTK return LPARENT ( IDENFR change1 RPARENT ) SEMICN ; RBRACE } VOIDTK void MAINTK main LPARENT ( RPARENT ) LBRACE { PRINTFTK printf LPARENT ( STRCON Hello World RPARENT ) SEMICN ; PRINT
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值