词法分析
可识别内容:
标识符:id
数字:num
关键字:int,char,if,else,while,do,for
标号:, , . , ;
算术运算符号:=,+,-,*,/,&,!,|,&&,||
关系运算符:=,>,==,!=
注释://
内码定义:
单个符号,如{,+,*,> 等,均使用其ascii码做内码,占双或多个字节的符号(包括保留字,标号,数字,运算符等)为其取名如下:
Enum { END=0,INT,CHAR,IF,ELSE,WHILE=5,
DO,FOR,ARGAND,ARGOR,NUM=10,
ID,LESSEQUAL,EQUAL,GREATEQUAL,NOTEQUAL=15 };
其中NUM代表数字,ID代表标识符.
测试程序1-1的词法分析结果如下:内码表
123 {
11 X
61 =
10 12
43 +
43 +
11 b
47 /
10 13
45 -
10 5
42 *
10 4
42 *
10 9
59 ;
11 Y
61 =
10 4
42 *
10 1024
59 ;
3 if
40 (
11 X
14 >=
11 Y
41 )
123 {
3 if 40 (
11 i
13 ==
11 i
41 )
123 {
11 X
61 =
11 Y
125 }
125 }
59 ;
59 ;
59 ;
59 ;
5 while
40 (
11 X
60 <
11 Y
41 )
123 {
11 X
61 =
11 X
43 +
10 1
59 ;
125 }
125 }
语法分析
C语言子集,可支持
语句块,语句,条件语句,While循环语句,赋值语句,基本算术表达式等。例如:
{
// Comment Supported : This is only a Test ^_^
X = 12 + b / 13 - 5 * 4 * 9; // A AssignmentStatement
Y = 4 * 1024;
if( X >= Y){
if( i == i){ // This is nested if Statement
X=Y;
}
}
;;;; // This is Null Statement
while( X < Y){ // This is while Statement
X = X +1;
}
}
测试程序1-1
支持错误检测,如将上面例子中X = 12 + b / 13 - 5 * 4 * 9;
故意修改为:X = 12 ++ b / 13 - 5 * 4 * 9; 则会出现如下错误提示,指示了出错行数和行内偏移位置:
规则如下:
::= '{''}'
::= {||}
::= ';'
::=
::= |
::= ID=
::= if(
::= while(
::=
::= {+|-}
::= {*|/}
::= ID|NUM|()
::= =|>|==|!=
//非终结符的英文定义
void StatementBlock(); //语句块
void StatementSequence(); //语句串
// XxxxxStatement() 为三类语句
void NullStatement(); //空语句--仅仅含有一个;号
void CommonStatement(); //语句
void VariantStatement(); //变种语句--包括 if(){},while{},他们都不以;结尾
// 下面的属于CommonStatement
void AssignmentStatement(); //赋值语句
// 下面两种属于VariantStatement
void ConditionStatement(); //条件语句
void LoopWhileStatement(); //while循环语句
void Condition(); //条件
void Expression(); //表达式
void Item(); //项
void Factor(); //因子
void RelationOperator(); //关系运算符
不能支持的主要方面:函数调用的识别,逗号表达式,for循环,switch语句。
词法分析:
//LexAly.cpp :C子集词法分析程序
/**//*
支持内容:
标识符:id
关键字: int,char,if,else,while,do,for
标号: ,, ., ;
算术运算符号: =,+,-,&,!,|,&&,||
全局字符串:
instr 记录待解析的字符串
string 存贮当前被解析到的ID
接口:
gettoken();
Sample:
输入:
instr =
for(i=0;i<10;i++){
j=i+10;
printf("%d",j);
}
输出:
for
(
i
……
}
注意:
要记得处理程序中未显示出来的符号,如空白(' '),回车(' '),值表符(' ')
*/
#include"stdafx.h"
#include
#include
#include
#include"Constant.h"
externvoidgrammar_check();
//注意:这里累计数目(最大值)不能大于32 (10 0000B)TOKEN
//enum {END=0,INT=1,CHAR,IF,ELSE,WHILE,DO,FOR,ARGAND,ARGOR,NUM,ID} ;
charindex[][20]=...{
...{"END OF File"},/**//*0 END*/
...{"int"},/**//*1 INT*/
...{"char"},/**//*2 CHAR*/
...{"if"},/**//*3 IF*/
...{"else"},/**//*4 ELSE*/
...{"while"},/**//*5 WHILE*/
...{"do"},/**//*6 DO*/
...{"for"},/**//*7 FOR*/
...{"&&"},/**//*8 ARGAND*/
...{"||"},/**//*9 ARGOR*/
...{""},/**//*10 NUM*/
...{""},/**//*11 ID*/
...{"<="},/**//*12 LESSEQUAL*/
...{"=="},/**//*13 EQUAL*/
...{">="},/**//*14 GREATEQUAL*/
...{"!="},/**//*15 NOTEQUAL*/
...{""}/**//*16 ID*/
};
charinput[10000]=...{0};
char*instr=input;
char*conststart_of_instr=input;
//string 包含gettoken最新得到的id等串
//gym包含 gettoken得到的内容的代号
//current_line 包含当前行号
charstring[MAX_INDENT];
intsym;
intcurrent_line=1;
intstart_pos_of_current_line;
char*strstart;//用于辅助识别num,id
intgettoken();
int_gettoken();
voiderror(char*cur);
char*getlinestring(intline,char*in_buf);
intnextline();
intgetline();
intgetcurrentpos();
intnextline()...{return++current_line; }
intgetline()...{returncurrent_line; }
intgetcurrentpos()...{return(int)instr; }
char*getlinestring(intline,char*in_buf)
...{
char*t=input;
inti=1;
while(*t!=0&&i
if(*t=='') i++;
t++;
}
intlen=0;
while(*t!='')...{
in_buf[len]=*t;
len++;
t++;
}
in_buf[len]=0;
returnin_buf;
}
voiderror(char*cur)
...{
printf("Spell Error found at line %d",getline());
exit(0);
}