zoukankan      html  css  js  c++  java
  • 实验二 递归下降语法分析

    一、实验目的:

    利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

    编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

    二、实验原理

    每个非终结符都对应一个子程序。

    该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

    • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
    • 每遇到一个非终结符,则调用相应的子程序

    三、实验要求说明

    输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

    例如:

    输入begin a:=9;x:=2*3;b:=a+x end #

    输出success

    输入x:=a+b*c  end #

    输出‘end' error

    四、实验步骤

    1.待分析的语言的语法(参考P90)

    2.将其改为文法表示,至少包含

    –语句

    –条件

    –表达式

    3. 消除其左递归

    4. 提取公共左因子

    5. SELECT集计算

    6. LL(1)文法判断

    7. 递归下降分析程序

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    using namespace std;
    char ch;
    char arr1[100], arr2[15],arr3[15];//arr1输入,arr2输出
    int syn, row, sum ; //syn为单词种别码,sum为整形常数。
    int p=0,m=0,n=0;
    int flag=0;
    char* words[6] = {"begin", "if", "then", "while", "do", "end"};
    void sca();
    void S();//解析语句
    void S1();
    void S2();
    void S3();
    void S4();
    void C();//解析条件
    void E();//解析表达式
    void E1();
    void T();//解析项
    void T1();
    void F();//解析因子
    void S(){
    if(flag != 0){
    if(syn == 10){ //<id>:=<表达式>
    sca();
    S1();
    }
    else if(syn == 2){ //if
    sca();
    S2();
    }
    else if(syn == 4){//while
    sca();
    S3();
    }
    else if(syn == 0){
    }
    else{
    printf("语句语法错误 ");
    exit(0);
    }
    }
    else{
    if(syn == 1){//begin
    sca();
    flag = 1;
    S4();
    }else{
    printf("error,缺少begin! ");
    exit(0);
    }
    }
    }
    void S1(){
    if(syn==18){
    sca();
    E();
    }
    else{
    printf("语句语法错误 ");
    exit(0);
    }
    }
    void S2(){//if
    C();
    if(syn== 3 ){
    sca();
    S();
    }
    else{
    printf("语句语法错误 ");
    exit(0);
    }
    }
    void S3(){//while
    C();
    if(syn== 5 ){
    sca();
    S();
    }
    else{
    printf("语句语法错误 ");
    exit(0);
    }
    }
    void S4(){//begin
    S();
    while(syn == 26){
    sca();
    S();
    }
    if(syn == 6){
    sca();
    if(syn == 0){
    printf("success!");
    }
    else{
    printf("语句语法错误 ");
    }
    }
    else{
    printf("error,缺少end ");
    exit(0);
    }
    }
    void C(){
    E();
    if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){
    sca();
    sca();
    }
    else{
    printf("条件语法错误 ");
    exit(0);
    }
    E();

    }
    void E(){
    T();
    E1();
    }


    void E1(){
    if(syn == 13 || syn == 14){
    sca();
    T();
    E1();
    }
    else if(syn == 28 || syn == 0){
    }
    }

    void T(){
    F();
    T1();
    }

    void T1(){
    if(syn == 15 || syn == 16){
    sca();
    F();
    T1();
    }
    else if(syn == 13 ||syn == 14 || syn == 28 || syn == 0){
    }
    }
    void F(){
    if(syn == 27){
    sca();
    E();
    if(syn == 28){
    sca();
    }
    else{
    printf("因子错误 ");
    exit(0);
    }
    }
    else if(syn == 10 || syn == 11){
    sca();

    }
    else{
    printf("因子错误");
    exit(0);
    }
    }

    int main()
    {
    p = 0;
    row = 1;
    cout << "请输入字符,以#号结束" << endl;

    do
    {
    cin.get(ch);
    arr1[p++] = ch;
    } while (ch != '#');

    p = 0;

    // do
    //
    // {
    //
    // sca();
    //
    // switch (syn)
    //
    // {
    //
    // case 11:
    //
    // cout << '(' << syn << "," << sum << ")" << endl;
    //
    // break;
    //
    // case -1:
    //
    // cout << "该符号“"<<arr3<<"”无种别码" << "!" << endl;
    //
    // break;
    //
    // case -2:
    //
    // ++row;
    //
    // break;
    //
    // default:
    //
    // cout << "(" << syn << "," << arr2 << ")" << endl;
    //
    // break;
    //
    // }
    //
    // } while (syn != 0);
    sca();
    S();
    }
    void sca()
    {
    for (n = 0; n < 8; n++)
    {
    arr2[n] = NULL;
    }
    ch = arr1[p++];

    while(ch == ' ')//空指针+1
    {
    ch = arr1[p];
    p++;
    }
    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
    {
    m = 0;
    while((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
    {
    arr2[m++] = ch;
    ch = arr1[p++];
    }
    arr2[m++] = '';
    --p;
    syn = 10;
    for (n = 0; n < 6; ++n)
    {
    if (strcmp(arr2, words[n]) == 0)
    {
    syn = n + 1;
    break;
    }
    }
    }
    else if ((ch >= '0' && ch <= '9'))
    {
    sum = 0;
    while (ch >= '0' && ch <= '9')
    {
    sum = sum * 10 + ch - '0';
    ch = arr1[p++];
    }
    --p;
    syn = 11;
    if (sum > 32767)
    {
    syn = -1;
    }
    }
    else switch (ch)
    {
    case '<':
    m = 0;
    arr2[m++] = ch;
    ch = arr1[p++];
    if (ch == '>')
    {
    syn = 21;
    arr2[m++] = ch;
    }
    else if (ch == '=')
    {
    syn = 22;
    arr2[m++] = ch;
    }
    else
    {
    syn = 23;
    --p;
    }
    break;
    case '>':
    m = 0;
    arr2[m++] = ch;
    ch = arr1[p++];
    if (ch == '=')
    {
    syn = 24;
    arr2[m++] = ch;
    }
    else
    {
    syn = 20;
    --p;
    }
    break;
    case ':':
    m = 0;
    arr2[m++] = ch;
    ch = arr1[p++];
    if (ch == '=')
    {
    syn = 18;
    arr2[m++] = ch;
    }
    else
    {
    syn = 17;
    --p;
    }
    break;
    case '*':
    syn = 13;
    arr2[0] = ch;
    break;
    case '/':
    syn = 14;
    arr2[0] = ch;
    break;
    case '+':
    syn = 15;
    arr2[0] = ch;
    break;
    case '-':
    syn = 16;
    arr2[0] = ch;
    break;
    case '=':
    syn = 25;
    arr2[0] = ch;
    break;
    case ';':
    syn = 26;
    arr2[0] = ch;
    break;
    case '(':
    syn = 27;
    arr2[0] = ch;
    break;
    case ')':
    syn = 28;
    arr2[0] = ch;
    break;
    case '#':
    syn = 0;
    arr2[0] = ch;
    break;
    case ' ':
    syn = -2;
    break;
    default:
    syn = -1;
    arr3[0]=ch;
    break;
    }
    }

  • 相关阅读:
    面试问题之C++语言:C++中指针和引用的区别
    手撕代码:最长回文子串
    手撕代码:求字符串最长回文子序列
    手撕代码:用宏来实现获取数组的大小
    手撕代码之线程:thread类简单使用
    面试问题之计算机网络:OSI七层网络模型及相关协议
    C++各种输入
    C printf格式化输出
    记一次mac 安装MySQL-python 的惨痛经历
    记一次tomcat程序运行慢的处理过程
  • 原文地址:https://www.cnblogs.com/chock/p/11957759.html
Copyright © 2011-2022 走看看