C語言源程式詞法分析器(Java實現)
一. 介紹
詞法分析器,又稱掃描器,輸入源程式,進行詞法分析,輸出單詞符號。詞法分析僅僅是編譯程式工作中的一部分,編譯程式一般可以劃分為5個階段:詞法分析,語法分析,語義分析與中間程式碼產生,優化,目的碼生成。我們這裡編寫一個簡單的C語言源程式詞法分析器。
二. 目的
設計並實現一個包含預處理功能的詞法分析程式,加深對編譯中詞法分析過程的理解。
四. 要求
1、實現預處理功能
源程式中可能包含有對程式執行無意義的符號,要求將其剔除。
首先編制一個源程式的輸入過程,從鍵盤、檔案或文字框輸入若干行語句,依次存入輸入緩衝區(字元型資料);然後編制一個預處理子程式,去掉輸入串中的回車符、換行符和跳格符等編輯性文字;把多個空白符合併為一個;去掉註釋。
2、實現詞法分析功能
輸入:所給文法的源程式字串。
輸出:二元組(syn,token或sum)構成的序列。其中,
syn為單詞種別碼。
Token為存放的單詞自身字串。
Sum為整型常量。
具體實現時,可以將單詞的二元組用結構進行處理。
3、待分析的C語言子集的詞法
1)關鍵字
main if then while do static int double struct break else long switch case typedef char return const float short continue for void default sizeof do
所有的關鍵字都是小寫。
2)運算子和界符
+ - * / : := < <> <= > >= = ; ( ) #
3)其他標記ID和NUM
通過以下正規式定義其他標記:
ID→letter(letter|digit)*
NUM→digit digit*
letter→a|…|z|A|…|Z
digit→0|…|9…
4)空格由空白、製表符和換行符組成
空格一般用來分隔ID、NUM、專用符號和關鍵字,詞法分析階段通常被忽略。
4、各種單詞符號對應的種別碼
單詞符號 種別碼 單詞符號 種別碼
main 1 void 23
if 2 sizeof 24
then 3 ID 25
while 4 NUM 26
do 5 + 27
static 6 - 28
int 7 * 29
double 8 / 30
struct 9 ** 31
break 10 == 32
else 11 < 33
long 12 <> 34
switch 13 <= 35
case 14 > 36
typedef 15 >= 37
char 16 = 38
return 17 [ 39
const 18 ] 40
float 19 ; 41
short 20 ( 42
continue 21 ) 43
for 22 # 0
五. 原始碼
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class LexicalAnalyzer {
static String[] rwtab=new String[]{"main","if","then","while","do","static",
"int","double","struct","break","else",
"long","switch","case","typedef","char",
"return","const","float","short","continue",
"for","void","sizeof"}; //已經定義的24個關鍵字,種別碼從1開始
static String storage=""; //儲存源程式字串
static StringBuilder token=new StringBuilder(""); //儲存單詞自身組成的字串
static char ch;
static int index;
static int syn, sum=0, row;
//分析器
static void analyzer(){
token.delete(0, token.length()); //置空token物件,清除
ch=storage.charAt(index++);
while(ch==' '){
ch=storage.charAt(index++); //去除空格符號
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){ //可能是關鍵字或者自定義的識別符號
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
token.append(ch);
ch=storage.charAt(index++);
}
index--; //此次識別的最後一個字元未識別入,需要將標記退原處
syn=25; //預設為識別出的字串為自定義的識別符號,種別碼為25
String s=token.toString();
for(int i=0; i<rwtab.length; i++){
if(s.equals(rwtab[i])){
syn=i+1;
break; //識別出是關鍵字
}
}
}
else if((ch>='0'&&ch<='9')){
sum=0;
while((ch>='0'&&ch<='9')){
sum=sum*10+ch-'0';
ch=storage.charAt(index++);
}
index--;
syn=26;
}
else switch(ch){
case '<':
token.append(ch);
ch=storage.charAt(index++);
if(ch=='='){
token.append(ch);
syn=35;
}
else if(ch=='>'){
token.append(ch);
syn=34;
}
else{
syn=33;
index--;
}
break;
case '>':
token.append(ch);
ch=storage.charAt(index++);
if(ch=='='){
token.append(ch);
syn=37;
}
else{
syn=36;
index--;
}
break;
case '*':
token.append(ch);
ch=storage.charAt(index++);
if(ch=='*'){
token.append(ch);
syn=31;
}
else{
syn=13;
index--;
}
break;
case '=':
token.append(ch);
ch=storage.charAt(index++);
if(ch=='='){
syn=32;
token.append(ch);
}
else{
syn=38;
index--;
}
break;
case '/':
token.append(ch);
ch=storage.charAt(index++);
if(ch=='/'){
while(ch!=' '){
ch=storage.charAt(index++); //忽略掉註釋,以空格為界定
}
syn=-2;
break;
}
else{
syn=30;
index--;
}
break;
case '+':
syn=27;
token.append(ch);
break;
case '-':
syn=28;
token.append(ch);
break;
case ';':
syn=41;
token.append(ch);
break;
case '(':
syn=42;
token.append(ch);
break;
case ')':
syn=43;
token.append(ch);
break;
case '#':
syn=0;
token.append(ch);
break;
case '\n':
syn=-2;
token.append(ch);
break;
default:
syn=-1;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in));
index=0;
row=1;
String tempString;
System.out.println("請輸入C語言源程式字串(以#結尾):");
//輸入過程
try{
do{
tempString=stdin.readLine();
storage+=tempString;
ch=tempString.charAt(tempString.length()-1); //得到一行中最後一個字元
}while(ch!='#'); //輸入以#字元結尾
}catch(IOException e){
e.printStackTrace();
}
index=0;
//輸出過程
do{
analyzer();
switch(syn){
case 26:
System.out.println("("+syn+","+sum+")");
break;
case -1:
System.out.println("Error in row"+row+"!");
break;
case -2:
break;
default:
System.out.println("("+syn+","+token+")");
}
}while(syn!=0);
}
}
六. 執行結果
相關推薦
C語言源程式詞法分析器(Java實現)
一. 介紹 詞法分析器,又稱掃描器,輸入源程式,進行詞法分析,輸出單詞符號。詞法分析僅僅是編譯程式工作中的一部分,編譯程式一般可以劃分為5個階段:詞法分析,語法分析,語義分析與中間程式碼產生,優化,目的碼生成。我們這裡編寫一個簡單的C語言源程式詞法分析器。
c詞法分析程式(java實現)原始碼1
package wordanalyse; import java.io.*; public class InputFile { private String path=""; public InputFile(){ } /** * @author 楊武兵 *function:從鍵盤獲
1117-C語言實驗——求絕對值(選擇結構)-JAVA
C語言實驗——求絕對值(選擇結構) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 從鍵盤上輸入任意一個整數,然後輸
一個簡單C語言的詞法分析器
一個簡單C語言的詞法分析器 語言的詞法構成: 識別符號 id 同C語言識別符號 常量 num 數字 ch 字元 str 字串 關鍵字 kw_int int kw_char char kw_void void kw_if
表示數值的字符串(Java實現)
har str 表示 pre false div scan char log 請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數值。 但是"12e","1a3.14","
數據結構之中序遍歷轉興許遍歷(JAVA實現)(二)
百度 empty 表達 pty 中序 tor opera lin sem 算法流程: 主要分為四步: 1.當前字符為數字或者字母,則直接輸出 2.當前字符為)。則在棧中匹配輸出。一直匹配到),則停止輸出(就是將)及其
冒泡排序(JAVA實現)
[] string 個數 -1 out 進行 image args com 基本思想:在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沈,較小的往上冒。 即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就
查找算法(Java實現)
pac binary while n) println pub ret gin 需要 1、二分查找算法 package other; public class BinarySearch { /* * 循環實現二分查找算法arr 已排好序的數
排序算法入門之希爾排序(java實現)
入門 介紹 插入 一次 變化 shells ngx i++ ava 希爾排序是對插入排序的改進。插入排序是前面元素已經有序了,移動元素是一個一個一次往後移動,當插入的元素比前面排好序的所有元素都小時,則需要將前面所有元素都往後移動。希爾排序有了自己的增量,可以理
排序算法入門之快速排序(java實現)
大小 ava 相對 其余 時間 個數 技術分享 算法 元素交換 快速排序也是一種分治的排序算法。快速排序和歸並排序是互補的:歸並排序將數組分成兩個子數組分別排序,並將有序的子數組歸並以將整個數組排序,會需要一個額外的數組;而快速排序的排序方式是當兩個子數組都有序
求較大整數n的階乘,因為n較大時n的階乘超出了正常類型的表示範圍,采用數組進行操作(java實現)
階乘 大數字package net.yk.mlgorithm; /** * 求較大數的階乘 * @author Administrator * * @param <T> */ public class ArraysMul<T> { public static void
奇怪的表達式求值 (java實現)
name 所在 cas 生活 div img num rar java 題目參考:http://blog.csdn.net/fuxuemingzhu/article/details/68484749 問題描述; 題目描述: 常規的表達式求值,我們都會根據計算的優先級來計算。
棧的數組和鏈表實現(Java實現)
javascrip search 分享圖片 sys blog inter () 結果 length 我以前用JavaScript寫過棧和隊列,這裏初學Java,於是想來實現棧,基於數組和鏈表。 下面上代碼: 1 import java.io.*; 2 //用接口來
數據結構與算法—插入排序(Java實現)
數據結構 算法 Java 插入排序 [toc] 插入排序 程序代碼 package com.uplooking.bigdata.datastructure; import java.util.Arrays; public class InsertSort { public st
數據結構與算法—冒泡排序(Java實現)
數據結構 算法 Java 冒泡排序 [toc] 冒泡排序 程序代碼 package com.uplooking.bigdata.datastructure; import java.util.Arrays; public class BubbleSort { public st
2004: C語言實驗——數日子(數組)
我們 這一 post HR submit 某年 inpu 時間 ret 2004: C語言實驗——數日子 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 213 Solved: 111[Submit][Status][Web
C語言占位符(待完善)
tps %u c語言 語言 待完善 csdn 有效 article 指數 %c 讀入一個字符 %s 讀入一個字符串,遇到空格制表符或者換行符時結束。 %d 讀入一個十進制整數 %x或者%X 讀入一個十六進制整數 %o
數組中只出現一次的數字(java實現)
num 整型 根據 長度 問題 程序 oid [] 情況 問題描述 一個整型數組裏除了兩個數字之外,其他的數字都出現了偶數次。請寫程序找出這兩個只出現一次的數字。 解題思路 如果數組中只有一個數字出現奇數次,則將數組中所有的數字做異或可得該數字。 數組中有兩個數
軟件工程實踐項目-WC(Java實現)
ddb 使用 odin ace rup find sys tca sub 軟件工程實踐項目-WC(Java實現) 本文項目Github地址:https://github.com/MeiJinpen/wc 要求 基本要求 [x] -c 統計文件字符數 (實現) [x]
【模板小程序】任意長度十進制數轉化為二進制(java實現)
轉換 obi number 格式 bigint reverse com rev ole 媽媽再也不用擔心十進制數過大了233 import com.google.common.base.Strings; import java.math.BigInteger; impor