第1关:词法分析程序设计与实现(C语言版)

任务描述

本关任务:加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

编程要求

根据提示,在右侧编辑器补充代码标示符、数字符及其他字符符号的识别程序后,点击评测运行程序,系统会自动进行结果对比。

测试说明

平台会对你编写的代码进行测试:

测试输入:

using namespace std; int main() {
int year;
cout << “hello” << endl;
return 0; }

代码实现

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
char prog[1000], token[20];
char ch;
int syn, p, m = 0, n, row = 1, sum = 0;
// 扩充关键字表
const char* rwtab[10] = { "if","int","for","while","do","return","break","continue", "using", "namespace" };
const char* rwtab1[8] = { "main","a","b","c","d","e","f","g" };

void scaner()
{
    // 初始化token数组
    for (n = 0; n < 20; n++) token[n] = '\0';
    // 跳过空白字符
    while (p < strlen(prog) && (prog[p] == ' ' || prog[p] == '\t' || prog[p] == '\n'))
    {
        if (prog[p] == '\n')
            row++;
        p++;
    }
    if (p >= strlen(prog))
    {
        syn = 0;
        return;
    }
    ch = prog[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;
            if (p >= strlen(prog))
                break;
            ch = prog[p++];
        }
        token[m] = '\0';
        if (p < strlen(prog))
            p--;
        syn = 2;
        for (n = 0; n < 10; n++) // 更新关键字表长度
        {
            if (strcmp(token, rwtab[n]) == 0)
            {
                syn = 1;
                break;
            }
        }
    }
    // 进行数字的识别
    else if (ch >= '0' && ch <= '9')
    {
        sum = 0;
        while (ch >= '0' && ch <= '9')
        {
            sum = sum * 10 + (ch - '0');
            if (p >= strlen(prog))
                break;
            ch = prog[p++];
        }
        if (p < strlen(prog))
            p--;
        syn = 3;
    }
    // 进行其他字符的识别
    else
    {
        switch (ch)
        {
        case '<':
            m = 0;
            token[m++] = ch;
            if (p < strlen(prog) && prog[p] == '<')
            {
                token[m++] = prog[p++];
                syn = 4;
            }
            else
            {
                syn = 4;
                p--;
            }
            break;
        case '>':
            m = 0;
            token[m++] = ch;
            if (p < strlen(prog) && prog[p] == '=')
            {
                token[m++] = prog[p++];
                syn = 4;
            }
            else
            {
                syn = 4;
                p--;
            }
            break;
        case ':':
            m = 0;
            token[m++] = ch;
            if (p < strlen(prog) && prog[p] == '=')
            {
                token[m++] = prog[p++];
                syn = 4;
            }
            else
            {
                syn = 4;
                p--;
            }
            break;
        case '*':
            syn = 4;
            token[0] = ch;
            break;
        case '/':
            syn = 4;
            token[0] = ch;
            if (p < strlen(prog) && prog[p] == '/') {
                token[1] = '/';
                syn = 5; // 注释符号作为界符处理
                p++;
            }
            break;
        case '+':
            syn = 4;
            token[0] = ch;
            break;
        case '-':
            syn = 4;
            token[0] = ch;
            break;
        case '=':
            syn = 4;
            token[0] = ch;
            break;
        case ';':
            syn = 5;
            token[0] = ch;
            break;
        case ',':
            syn = 5;
            token[0] = ch;
            break;
        case '(':
            syn = 5;
            token[0] = ch;
            break;
        case ')':
            syn = 5;
            token[0] = ch;
            break;
        case '{':
            syn = 5;
            token[0] = ch;
            break;
        case '}':
            syn = 5;
            token[0] = ch;
            break;
        case '#':
            syn = 0;
            token[0] = ch;
            break;
        case '"':
            syn = 5;
            token[0] = ch;
            break;
        default:
            syn = -1;
            break;
        }
    }
}

int main()
{
    // 输入
    p = 0;
    cout << "Please input string:" << endl;
    do
    {
        cin.get(ch);
        prog[p++] = ch;
    } while (ch != '#');
    prog[p] = '\0';
    p = 0;

    // 输出
    do
    {
        scaner();
        switch (syn)
        {
        case 0:
            break;
        case 3:
            cout << "(" << syn << "," << sum << ")" << endl;
            break;
        case -1:
            cout << "Error in row " << row << "!" << endl;
            break;
        default:
            cout << "(" << syn << "," << token << ")" << endl;
            break;
        }
    } while (syn != 0);
    return 0;
}    

第1关:词法分析程序设计与实现(java版)

任务描述

本关任务:加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

编程要求

根据提示,在右侧编辑器Beign和End 之间依次补充标示符关键字 letterCheck、数字符digitCheck及其他字符符号symbolCheck的识别程序,点击评测,运行程序,系统会自动进行结果对比。

测试说明

平台会对你编写的代码进行测试:

测试输入:

public class Hello{
public static void main(String args[]){
System.out.println(“Hello World”);
} }

代码实现

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class ex1 {
    /*
     * 1表示关键字
     * 2表示标识符
     * 3表示常数
     * 4表示运算符
     * 5表示界符
     * 6表示字符串
     * */

    //关键字
    static String[] keyWord = {"private", "protected", "public", "abstract", "class", "extends", "final", "implements",
            "interface", "native", "new", "static", "strictfp", "break", "continue", "return", "do", "while", "if", "else", "for",
            "instanceof", "switch", "case", "default", "boolean", "byte", "char", "double", "float", "int", "long", "short",
            "String", "null", "true", "false", "void", "this", "goto"};
    //运算符
    static String[] operation = {"+", "-", "*", "/", "%", "++", "--", "-=", "*=", "/=", "&", "|", "^", "~", "<<", ">>", ">>>", "==", "!=",
            ">", "<", "=", ">=", "<=", "&&", "||", "!", "."};
    //界符
    static String[] symbol = {",", ";", ":", "(", ")", "{", "}"};
    static ArrayList<String> keyWords = null;
    static ArrayList<String> operations = null;
    static ArrayList<String> symbols = null;

    //指向当前所读到字符串的位置的指针
    static int p, lines;


    public static void main(String[] args) throws FileNotFoundException {
        init();
        File file = new File("/data/workspace/myshixun/input.txt");
        lines = 1;
        try (Scanner input = new Scanner(file)) {
            while (input.hasNextLine()) {
                String str = input.nextLine();
                analyze(str);
                lines++;
            }
        }

    }

    //初始化把数组转换为ArrayList
    public static void init() {
        keyWords = new ArrayList<>();
        operations = new ArrayList<>();
        symbols = new ArrayList<>();
        Collections.addAll(keyWords, keyWord);
        Collections.addAll(operations, operation);
        Collections.addAll(symbols, symbol);
    }

    public static void analyze(String str) {

        p = 0;
        char ch;
        str = str.trim();
        for (; p < str.length(); p++) {
            ch = str.charAt(p);
            if (Character.isDigit(ch)) {
                digitCheck(str);
            } else if (Character.isLetter(ch) || ch == '_') {
                letterCheck(str);
            } else if (ch == '"') {
                stringCheck(str);
            } else if (ch == ' ') {
                continue;
            } else {
                symbolCheck(str);
            }
        }
    }

    /*数字的识别*/
    public static void digitCheck(String str) {
        StringBuilder token = new StringBuilder();
        char ch;
        for (; p < str.length(); p++) {
            ch = str.charAt(p);
            if (Character.isDigit(ch)) {
                token.append(ch);
            } else {
                p--;
                break;
            }
        }
        System.out.println("(" + 3 + "," + token + ")");
    }

    //标识符,关键字的识别
    public static void letterCheck(String str) {
        StringBuilder token = new StringBuilder();
        char ch;
        for (; p < str.length(); p++) {
            ch = str.charAt(p);
            if (Character.isLetterOrDigit(ch) || ch == '_') {
                token.append(ch);
            } else {
                p--;
                break;
            }
        }
        String tokenStr = token.toString();
        if (keyWords.contains(tokenStr)) {
            System.out.println("(" + 1 + "," + tokenStr + ")");
        } else {
            System.out.println("(" + 2 + "," + tokenStr + ")");
        }
    }

    //符号的识别
    public static void symbolCheck(String str) {
        String token = String.valueOf(str.charAt(p));
        if (operations.contains(token)) {
            System.out.println("(" + 4 + "," + token + ")");
        } else if (symbols.contains(token)) {
            System.out.println("(" + 5 + "," + token + ")");
        } else {
            if (p + 1 < str.length()) {
                String twoCharToken = token + str.charAt(p + 1);
                if (operations.contains(twoCharToken)) {
                    System.out.println("(" + 4 + "," + twoCharToken + ")");
                    p++;
                    return;
                }
            }
            System.out.println(lines + "line: " + token + " is wrong");
        }
    }

    //字符串检查
    public static void stringCheck(String str) {
        String token = String.valueOf(str.charAt(p++));
        char ch;
        for (; p < str.length(); p++) {
            ch = str.charAt(p);
            token += ch;
            if (ch == '"') {
                break;
            }
        }
        if (token.charAt(token.length() - 1) != '"') {
            System.out.println(lines + "line: " + token + " is wrong");
        } else {
            System.out.println("(" + 6 + "," + token + ")");
        }
    }
}    

测试结果

叮咚!任务完成!恭喜玩家成功通过本关!(●’◡’●)👍
在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐