gpt4 book ai didi

java - 实现词法分析器

转载 作者:行者123 更新时间:2023-12-01 05:20:12 26 4
gpt4 key购买 nike

我有一项任务是为 c-- 语言实现词法分析器。我们必须将 c-- 代码转换为一系列在内部表示为整数的标记,因为这样更容易操作。该语言的一些词汇约定是存在诸如 double、else、if、int、return、void 和 while 等关键字。还有特殊符号,如 + - */<<= >>= == != = ; , . ( ) [ ] { }/* *///.标识符可以以任何字母或下划线开头,后跟字母、数字和下划线的任意组合。空格分隔标记并被忽略。数字可以是整数或小数,并且允许使用注释行和 block 。

import java.io.*;
public class Lex {

public static boolean contains(char[] a, char b){
for (int i = 0; i < a.length; i++) {
if(b == a[i])
return true;
}
return false;
}
public static void main(String args[]) throws FileNotFoundException, IOException{

//Declaring token values as constant integers.
final int T_DOUBLE = 0;
final int T_ELSE = 1;
final int T_IF = 2;
final int T_INT = 3;
final int T_RETURN = 4;
final int T_VOID = 5;
final int T_WHILE = 6;
final int T_PLUS = 7;
final int T_MINUS = 8;
final int T_MULTIPLICATION = 9;
final int T_DIVISION = 10;
final int T_LESS = 11;
final int T_LESSEQUAL = 12;
final int T_GREATER = 13;
final int T_GREATEREQUAL = 14;
final int T_EQUAL = 16;
final int T_NOTEQUAL = 17;
final int T_ASSIGNOP = 18;
final int T_SMEICOLON = 19;
final int T_PERIOD = 20;
final int T_LEFTPAREN = 21;
final int T_RIGHTPAREN = 22;
final int T_LEFTBRACKET = 23;
final int T_RIGHTBRACKET = 24;
final int T_LEFTBRACE = 25;
final int T_RIGHTBRACE = 26;
final int T_ID = 27;
final int T_NUM = 28;
char[] letters_ = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D',
'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_'};
char[] numbers = {'0','1','2','3','4','5','6','7','8','9'};
char[] symbols = {'+','-','*','/','<','>','!','=',':',',','.','(',')','[',']','{','}'};
FileInputStream fstream = new FileInputStream("src\\testCode.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
BufferedWriter bw1 = new BufferedWriter(new FileWriter(new File("src\\output.txt"), true));
BufferedWriter bw2 = new BufferedWriter(new FileWriter(new File("src\\output2.txt"), true));
String scanner;String temp = "";
int n = 0;
while((scanner = br.readLine()) != null){
for (int i = 0; i < scanner.length(); i++) {
for (int j = 0; j < scanner.length(); j++) {
if(contains(letters_,scanner.charAt(i)) || contains(numbers,scanner.charAt(i)) || contains(symbols,scanner.charAt(i))){
j++;
n++;
if(scanner.charAt(j) == ' ' || scanner.charAt(j) == '\n' || scanner.charAt(j) == '\t'){

}
}

}

}
}

in.close();


}

}

这是我们的测试代码:

int fact(int x) {
// recursive factorial function
if (x>1)
return x * fact(x-1);
else return 1;
}

void main(void) {
/* CS 311 project 2
A lexical analyzer */
int x, y, z;
double _funny;
x = get_integer();
_Funny = get_double();
if (x>0)
print_line(fact(x));
else if (_funny != 3.14)
print_line(x*_funny);
}

这应该是我们的输出

3 27 21 3 27 22 25 2 21 27 13 28 22 4 27 9 27 21 27 8 28 22 18 1 4 28 18 26 5 27 21 5 22 25 3 27 19 27 19 27 18 0 27 18 27 17 27 21 22 18 27 17 27 21 22 18 2 21 27 13 28 22 27 21 27 21 27 22 22 18 1 2 21 27 12 28 22 27 21 27 9 27 22 18 26

INT id leftparen INT id rightparen leftbrace IF leftparen id greater num rightparen RETURN id multiplication id leftparen id minus num rightparen semicolon ELSE RETURN num semicolon rightbrace VOID id leftparen VOID rightparen leftbrace INT id comma id comma id semicolon DOUBLE id semicolon id assignop id leftparen rightparen semicolon id assignop id leftparen rightparen semicolon IF leftparen id greater num rightparen id leftparen id leftparen id rightparen rightparen semicolon ELSE IF leftparen id notequal num rightparen id leftparen id multiplication id rightparen semicolon rightbrace

好的,我根据用户约翰的建议编写了一些代码。我仍然对这将如何运作感到困惑。当我迭代第二个循环以查找空格或符号时,我如何知道符号 ws 之前出现的标记类型。我尝试将我跳过的字符放入字符串中,并使用 case 语句来确定它,但我认为它将整个文件写入字符串中,因此我的标记永远不会匹配。另外,方法如何找到注释并安全地忽略它们?

最佳答案

有几种不同的方法可以实现这个程序。在不编写代码的情况下,我将尝试解释您需要做什么。

来自您提交的示例。

您的讲师已为您提供了该计划的 key 。他已经给了你输出,你可以构建一个状态表。

您可以查看输出并手动执行此操作来检查您的答案,也可以创建一个小程序来为您执行此操作。

这是一个表格,左边是州号,右边是相应的单词。

         3  int,  
27 ID,
21 leftparen,
22 right paren,
25 left brace s,
2 if,
13 greater,

等等。

您需要创建一个输入缓冲区
2个输出缓冲器
2个循环,一外一内循环
1 个 case 语句对应状态表。

当你遍历输入缓冲区时,你初始化了外循环初始化内循环比较第一个字符并确定它是否是有效字符?如果不增加循环,直到找到有效字符

一旦找到有效字符,它就是标记的开始。然后通过查找空格或特殊符号来增加内部循环,从而找到标记的末尾。然后使用case语句输出第一个缓冲区中的数字和第二个缓冲区中对应的单词。

然后打印出数字缓冲区。然后打印出字缓冲区。

然后将外循环增加到内循环+1使内循环等于外循环

继续,直到找到文件末尾。如果它们与您老师的输出相符,您就完成了。如果不是,则有逻辑错误。然后检查哪个值无效,并查看程序的该部分。

伙计们,已经20年了。

关于java - 实现词法分析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10527143/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com