词法分析
可识别内容:
标识符: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; 则会出现如下错误提示,指示了出错行数和行内偏移位置:
规则如下:
<StatementBlock> ::= '{'<StatementSequence>'}'
<StatementSequence> ::= {<NullStatement>|<CommonStatement>|<VariantStatement>}
<NullStatement> ::= ';'
<CommonStatement> ::= <AssignmentStatement>
<VariantStatement> ::= <ConditionStatement>| <LoopWhileStatement>
<AssignmentStatement> ::= ID=<Expression>
<ConditionStatement> ::= if(<Condition> <StatementBlock>
<LoopWhileStatement> ::= while(<Condition> <StatementBlock>
<Condition> ::= <Expression><RelationOperator><Expression>
<Expression> ::= <Item>{+<Item>|-<Item>}
<Item> ::= <Factor>{*<Factor>|/<Factor>}
<Factor> ::= ID|NUM|(<Expression>)
<RelationOperator> ::= <|<=|>=|>|==|!=
//非终结符的英文定义
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语句。
词法分析:
/**//*
支持内容:
标识符: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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "Constant.h"
extern void grammar_check();
// 注意:这里累计数目(最大值)不能大于32 (10 0000B)TOKEN
//enum {END=0,INT=1,CHAR,IF,ELSE,WHILE,DO,FOR,ARGAND,ARGOR,NUM,ID} ;
char index[][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 */
};
char input[10000] = ...{0};
char * instr = input;
char * const start_of_instr=input;
//string 包含gettoken最新得到的id等串
//gym包含 gettoken得到的内容的代号
//current_line 包含当前行号
char string[MAX_INDENT];
int sym;
int current_line = 1;
int start_pos_of_current_line;
char *strstart; //用于辅助识别num,id
int gettoken();
int _gettoken();
void error(char *cur);
char* getlinestring(int line,char *in_buf);
int nextline();
int getline();
int getcurrentpos();
int nextline() ...{ return ++current_line; }
int getline() ...{ return current_line; }
int getcurrentpos() ...{ return (int)instr; }
char* getlinestring(int line,char *in_buf)
...{
char * t = input;
int i = 1;
while(*t != 0 && i < line )...{
if( *t=='
' ) i++;
t++;
}
int len = 0;
while ( *t != '
' )...{
in_buf[len] = *t;
len++;
t++;
}
in_buf[len] = 0;
return in_buf;
}
void error(char *cur)
...{
printf("Spell Error found at line %d
",getline());
exit(0);
}
//语法分析
int main_grammar(char *filename)
...{
int i;
FILE *f;
if(!(f=fopen(filename,"r")))...{
printf("Fail to open source file %s!
",filename);
exit(0);
}
int k=0;
char c;
while((c=fgetc(f))!=EOF)
...{
input[k]=c;
k++;
}
input[k] = 0;
//打印出程序
printf("%s
",start_of_instr);
//开始语法检查
grammar_check();
printf("Success!
");
return 0;
}
// 词法分析
int main_spell(char *filename)
...{
int i;
FILE *f;
if(!(f=fopen(filename,"r")))...{
printf("Fail to open source file %s!
",filename);
exit(0);
}
int k=0;
char c;
while((c=fgetc(f))!=EOF)
...{
input[k]=c;
k++;
}
input[k] = 0;
printf("%s
",start_of_instr);
while((i=gettoken())!=