小C語言--詞法分析程式(編譯原理實驗一)

HowieLee59發表於2018-09-22

小C語言文法

  1. <程式>→(){<宣告序列><語句序列>}

  2. <宣告序列>→<宣告序列><宣告語句>|<宣告語句>|<空>

  3. <宣告語句>→<識別符號表>;

  4. <識別符號表>→<識別符號>,<識別符號表>|<識別符號>

  5. <語句序列>→<語句序列><語句>|<語句>

  6. <語句>→< if語句>|< while語句>|< for語句>|<複合語句>|<賦值語句>

  7. < if語句>→< if關鍵字>(<表示式>)<複合語句>|(<表示式>)<複合語句>< else關鍵字><複合語句>

  8. < while語句>→< while關鍵字>(<表示式>)<複合語句>

  9. < for語句>→< for關鍵字>(<表示式>;<表示式>;<表示式>)<複合語句>

  10. <複合語句>→{<語句序列>}

  11. <賦值語句>→<表示式>;

  12. <表示式>→<識別符號>=<算數表示式>|<布林表示式>

  13. <布林表示式>→<算數表示式> |<算數表示式><關係運算子><算數表示式>

  14. <關係運算子>→>|<|>=|<=|==|!=

  15. <算數表示式>→<算數表示式>+<項>|<算數表示式>-<項>|<項>

  16. <項>→<項>*<因子>|<項>/<因子>|<因子>

  17. <因子>→<識別符號>|<無符號整數>|(<算數表示式>)

  18. <識別符號>→<字母>|<識別符號><字母>|<識別符號><數字>

  19. <無符號整數>→<數字>|<無符號整數><數字>

  20. <字母>→a|b|…|z|A|B|…|Z

  21. <數字>→0|1|2|3|4|5|6|7|8|9

  22. < main關鍵字>→main

  23. < if關鍵字>→if

  24. < else關鍵字>→else

  25. < for關鍵字>→for

  26. < while關鍵字>→while

  27. < int關鍵字>→int

每行單詞數不超過10個
小C語言文法如上,現在我們對小C語言寫的一個源程式進行詞法分析,分析出關鍵字、自定義識別符號、整數、界符
和運算子。
關鍵字:main if else for while int
自定義識別符號:除關鍵字外的識別符號
整數:無符號整數
界符:{ } ( ) , ;
運算子:= + - * / < <= > >= == !=

Input
輸入一個小C語言源程式,源程式長度不超過2000個字元,保證輸入合法。

Output
按照源程式中單詞出現順序輸出,輸出二元組形式的單詞串。

(單詞種類,單詞值)

單詞一共5個種類:

關鍵字:用keyword表示
自定義識別符號:用identifier表示
整數:用integer表示
界符:用boundary表示
運算子:用operator表示

每種單詞值用該單詞的符號串表示。

Sample Input

main() 
{
	int a, b;
	if(a == 10)
	{
    	a = b;
	}
}

Sample Output

(keyword,main)
(boundary,()
(boundary,))
(boundary,{)
(keyword,int)
(identifier,a)
(boundary,,)
(identifier,b)
(boundary,;)
(keyword,if)
(boundary,()
(identifier,a)
(operator,==)
(integer,10)
(boundary,))
(boundary,{)
(identifier,a)
(operator,=)
(identifier,b)
(boundary,;)
(boundary,})
(boundary,})

由於Java卡空間,樣例過了但是沒有ac,程式碼呈上:

import java.util.Scanner;
public class one {
private static String a[] = {"keyword","identifier","integer","boundary","operator"};
private static String b[] = {"main","if","else","for","while","int"};
public static void main(String[] args) {
	// TODO Auto-generated method stub
	Scanner sc = new Scanner(System.in);
	StringBuilder ss = new StringBuilder();
	while(sc.hasNextLine()) {
		ss = new StringBuilder();
		ss.append(sc.next());
		char[] abc = ss.toString().toCharArray();
		StringBuilder aa = new StringBuilder();
		for(int i = 0 ; i < ss.length();i++) {
			if(abc[i] != ' ') {
				if(abc[i] == '=' || abc[i] == '+' || abc[i] == '-'||abc[i] == '*'|| abc[i] == '/' || abc[i] == '<' || abc[i] == '>' || abc[i] == '!') {
	            	if(aa.length() != 0) {
	            		decide(aa.toString());
	            	}
	            	aa = new StringBuilder();
	            	if(i + 1 < ss.length() && abc[i+1] == '=') {
	            		System.out.println("(" + a[4] + "," + abc[i] + abc[i+1]+")");
	            		i++;
	            	}else {
	            		System.out.println("(" + a[4] + "," + abc[i] + ")");
	            	}
	            }else if(abc[i] == '(' || abc[i] == ')' || abc[i] == '{'||abc[i] == '}'|| abc[i] == ',' || abc[i] ==';') {
	            	if(aa.length() != 0) {
	            		decide(aa.toString());
	            	}
	            	aa = new StringBuilder();
	            	System.out.println("(" + a[3] + "," + abc[i] + ")");
	            }else {
	            	aa.append(abc[i]);
	            }
			}
		}
    	if(aa.length() != 0) {
    		decide(aa.toString());
    	}
	}
	//System.out.println(ss);
	sc.close();
}
public static void decide(String ss) {
	char[] s = ss.toCharArray();
	if(s[0]>='0'&&s[0]<='9') 
    {
		System.out.println("(" + a[2] + "," + ss + ")");
    }
    else
    {
        int f=1;
        for(int i=0; i<6; i++)
        {
            if(ss == b[i])
            {
                f=0;
                System.out.println("(" + a[0] + "," + ss + ")");
                break;
            }
        }
        if(f==1)
        {
        	System.out.println("(" + a[1] + "," + ss + ")");
        }
    }
}
}

轉化為C++;

#include <iostream>
#include <string>
using namespace std;
string S[5]= {"keyword","identifier","integer","boundary","operator"};
string T[6]= {"main","if","else","for","while","int"};
void decide(string s)
{
 	if(s[0]>='0'&&s[0]<='9') //開頭是數字肯定就為數字
{
    cout<<"("<<S[2]<<","<<s<<")"<<endl;
}
else
{
    int f=1;
    for(int i=0; i<6; i++)
    {
        if(s==T[i])
        {
            f=0;
            cout<<"("<<S[0]<<","<<s<<")"<<endl;
            break;
        }
    }
    if(f==1)
    {
        cout<<"("<<S[1]<<","<<s<<")"<<endl;
    }
}
}
int main()
{
	string s;
	while(cin>>s)
	{
    	int len=s.length();
    	string temp="";
    	for(int i=0; i<len; i++)
   	 {
        //操作符
        if(s[i] == '=' || s[i] == '+' || s[i] == '-'||s[i] == '*'|| s[i] == '/' || s[i] == '<' || s[i] == '>' || s[i] == '!')
        {
            if(temp.length())
            {
                decide(temp);
            }
            temp="";
            if(i+1<len&&s[i+1]=='=')
            {
                cout<<"("<<S[4]<<","<<s[i]<<s[i+1]<<")"<<endl;
                i++;
            }
            else
            {
                cout<<"("<<S[4]<<","<<s[i]<<")"<<endl;
            }
        }
        //界符
        else if(s[i] == '(' || s[i] == ')' || s[i] == '{'||s[i] == '}'|| s[i] == ',' || s[i] ==';')
        {
            if(temp.length())
            {
                decide(temp);
            }
            temp="";
            cout<<"("<<S[3]<<","<<s[i]<<")"<<endl;
        }
        //不是界符也不是操作符,就存到臨時字串裡面,等待判斷
        else
        {
            temp=temp+s[i];

        }
    }
    if(temp.length())
    {
        decide(temp);
    }

}
return 0;
}

相關文章