本文资源:语法分析器代码和报告
设计、编写、调试一个具体的语法分析程序,加深对语法分析原理的理解。
编译器的实现通常分成几个阶段来完成,本次实验,是为根据给定的文法实现一个小型编译器的语法分析阶段要完成的任务。请根据给定的文法设计并实现语法分析程序(推荐自顶向下的递归子程序分析方法),基于词法分析实验所识别出的单词,进一步识别出各类语法成分,输入输出及处理要求如下:
(1)需按文法规则,用递归子程序法对文法中定义的所有种语法成分进行分析;
(2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output.txt(注意不要写错文件名),结果文件中包含如下两种信息:
1)按词法分析识别单词的顺序,按行输出每个单词的信息(要求同词法分析作业,对于预读的情况不能输出)。
2)在下列高亮显示的语法分析成分分析结束前,另起一行输出当前语法成分的名字,形如“<常量说明>”(注:未要求输出的语法成分仍需要分析)
[文法定义]:
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<关系运算符> ::= <|<=|>|>=|!=|==
<字母> ::= _|a|...|z|A|...|Z
<数字> ::= 0|<非零数字>
<非零数字> ::= 1|...|9
<字符> ::= ‘<加法运算符>’|’<乘法运算符>’|’<字母>’|’<数字>’
<字符串> ::= “{十进制编码为32,33,35-126的ASCII字符}”
<程序> ::= [<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
<常量说明> ::= const<常量定义>;{ const<常量定义>;}
<常量定义> ::= int<标识符>=<整数>{,<标识符>=<整数>}
| char<标识符>=<字符>{,<标识符>=<字符>}
<无符号整数> ::= <非零数字>{<数字>}| 0
<整数> ::= [+|-]<无符号整数>
<标识符> ::= <字母>{<字母>|<数字>}
<声明头部> ::= int<标识符> |char<标识符>
<变量说明> ::= <变量定义>;{<变量定义>;}
<变量定义> ::= <类型标识符>(<标识符>|<标识符>’[‘<无符号整数>’]‘){,(<标识符>|<标识符>’[‘<无符号整数>’]’ )}
//<无符号整数>表示数组元素的个数,其值需大于0
<类型标识符> ::= int | char
<有返回值函数定义> ::= <声明头部>’(‘<参数表>’)’ ‘{‘<复合语句>’}’
<无返回值函数定义> ::= void<标识符>’(‘<参数表>’)‘’{‘<复合语句>’}’
<复合语句> ::= [<常量说明>][<变量说明>]<语句列>
<参数表> ::= <类型标识符><标识符>{,<类型标识符><标识符>}| <空>
<主函数> ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
<表达式> ::= [+|-]<项>{<加法运算符><项>} //[+|-]只作用于第一个<项>
<项> ::= <因子>{<乘法运算符><因子>}
<因子> ::= <标识符>|<标识符>’[‘<表达式>’]‘|’(‘<表达式>’)‘|<整数>|<字符>|<有返回值函数调用语句>
<语句> ::= <条件语句>|<循环语句>| ‘{‘<语句列>’}’| <有返回值函数调用语句>;
|<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<空>;|<返回语句>;
<赋值语句> ::= <标识符>=<表达式>|<标识符>’[‘<表达式>’]'=<表达式>
<条件语句> ::= if ‘(‘<条件>’)‘<语句>[else<语句>]
<条件> ::= <表达式><关系运算符><表达式> //整型表达式之间才能进行关系运算
|<表达式> //表达式为整型,其值为0条件为假,值不为0时条件为真
<循环语句> ::= while ‘(‘<条件>’)‘<语句>| do<语句>while ‘(‘<条件>’)’ |for’(‘<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>’)‘<语句>
<步长>::= <无符号整数>
<有返回值函数调用语句> ::= <标识符>’(‘<值参数表>’)’
<无返回值函数调用语句> ::= <标识符>’(‘<值参数表>’)’
<值参数表> ::= <表达式>{,<表达式>}|<空>
<语句列> ::= {<语句>}
<读语句> ::= scanf ‘(‘<标识符>{,<标识符>}’)’
<写语句> ::= printf ‘(’ <字符串>,<表达式> ‘)’| printf ‘(‘<字符串> ‘)’| printf ‘(‘<表达式>’)’
<返回语句> ::= return[’(‘<表达式>’)’]
(3)输入形式:testfile.txt中的符合文法要求的测试程序。
(4)输出形式:要求将语法分析结果输出至output.txt中,中文字符的编码格式要求是UTF-8。
特别提醒:
(1)本次实验只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。
(2)当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。
将词法分析得到的类别码存起来,在语法分析时按照语法文法进行匹配输出。
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
test
const int _begini = 0, _endi = +18, testfg = -6;
void main(){
int a, b, i;
scanf(i);
a = i;
printf(a);
}
output
CONSTTK const
INTTK int
IDENFR _begini
ASSIGN =
INTCON 0
<无符号整数>
<整数>
COMMA ,
IDENFR _endi
ASSIGN =
PLUS +
INTCON 18
<无符号整数>
<整数>
COMMA ,
IDENFR testfg
ASSIGN =
MINU -
INTCON 6
<无符号整数>
<整数>
<常量定义>
SEMICN ;
<常量说明>
VOIDTK void
MAINTK main
LPARENT (
RPARENT )
LBRACE {
INTTK int
IDENFR a
COMMA ,
IDENFR b
COMMA ,
IDENFR i
<变量定义>
SEMICN ;
<变量说明>
SCANFTK scanf
LPARENT (
IDENFR i
RPARENT )
<读语句>
SEMICN ;
<语句>
IDENFR a
ASSIGN =
IDENFR i
<因子>
<项>
<表达式>
<赋值语句>
SEMICN ;
<语句>
PRINTFTK printf
LPARENT (
IDENFR a
<因子>
<项>
<表达式>
RPARENT )
<写语句>
SEMICN ;
<语句>
<语句列>
<复合语句>
RBRACE }
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 10000;
bool IsDigit(char c) {
return isdigit(c);
}
bool IsLetter(char c) {
if (isalpha(c) || (c == '_'))
return true;
return false;
}
map <string, string>category;
int length = 0;
char in[MAXN];
//vector in;
int num = 0;
vector<string> token;
vector<string> val;
void read()
{
category["const"] = "CONSTTK";
category["int"] = "INTTK";
category["char"] = "CHARTK";
category["void"] = "VOIDTK";
category["main"] = "MAINTK";
category["if"] = "IFTK";
category["else"] = "ELSETK";
category["do"] = "DOTK";
category["while"] = "WHILETK";
category["for"] = "FORTK";
category["scanf"] = "SCANFTK";
category["printf"] = "PRINTFTK";
category["return"] = "RETURNTK";
category["+"] = "PLUS";
category["-"] = "MINU";
category["*"] = "MULT";
category["/"] = "DIV";
category[","] = "COMMA";
category[";"] = "SEMICN";
category["("] = "LPARENT";
category[")"] = "RPARENT";
category["["] = "LBRACK";
category["]"] = "RBRACK";
category["{"] = "LBRACE";
category["}"] = "RBRACE";
//读取文件转存in数组
ifstream input("testfile.txt", ios::in);
if (!input)
{
cout << "open testfile.txt error!" << endl;
exit(1);
}
input.unsetf(ios::skipws);
while (input.peek() != EOF) {
char c = input.get();
in[length++] = c;
//in.push_back(c);
}
input.close();
//for(int i=0;i
}
void WordAnalysis()
{
int p = 0;
while (p < length)
{
while (in[p] == ' ' || in[p] == '\n')p++;
if (IsLetter(in[p]) || in[p] == '_')
{
string s = "";
while (IsLetter(in[p]) || IsDigit(in[p]) || in[p] == '_')
{
s += in[p++];
}
if (category[s] != "")
{
token.push_back(category[s]);
}
else
{
token.push_back("IDENFR");
}
val.push_back(s);
num++;
}
else if (IsDigit(in[p]))
{
string s = "";
int num = 0;
while (IsDigit(in[p]))
{
num = num * 10 + (in[p] - '0');
s += in[p++];
}
token.push_back("INTCON");
val.push_back(s);
num++;
}
else if (in[p] == '=')
{
if (in[p + 1] == '=')//双等号
{
token.push_back("EQL");
val.push_back("==");
num++;
p += 2;
}
else
{
token.push_back("ASSIGN");
val.push_back("=");
num++;
p++;
}
}
else if (in[p] == '+' || in[p] == '-' || in[p] == '*' || in[p] == '/'
|| in[p] == ';' || in[p] == ',' || in[p] == '(' || in[p] == ')'
|| in[p] == '[' || in[p] == ']' || in[p] == '{' || in[p] == '}')
{
string s = "";s += in[p];
p++;
token.push_back(category[s]);
val.push_back(s);
num++;
}
else if (in[p] == 39)//单引号
{
p++;
string s = "";s += in[p];
p++;
if (in[p] == 39)p++;
token.push_back("CHARCON");
val.push_back(s);
num++;
}
else if (in[p] == '"')
{
string s;
p++;
while (in[p] != '"')
{
s += in[p];
p++;
}
p++;
token.push_back("STRCON");
val.push_back(s);
num++;
}
else if (in[p] == '<')
{
if (in[p + 1] == '=')//小于等于号
{
token.push_back("LEQ");
val.push_back("<=");
num++;
p += 2;
}
else
{
token.push_back("LSS");
val.push_back("<");
num++;
p++;
}
}
else if (in[p] == '>')
{
if (in[p + 1] == '=')//大于等于号
{
token.push_back("GEQ");
val.push_back(">=");
num++;
p += 2;
}
else
{
token.push_back("GRE");
val.push_back(">");
num++;
p++;
}
}
else if (in[p] == '!')
{
if (in[p + 1] == '=')//不等于号
{
token.push_back("NEQ");
val.push_back("!=");
num++;
p += 2;
}
}
else p++;
}
/*输出
ofstream output("output.txt",ios::out);
for(int i=0;i
return;
}
#pragma once
int q;//token[q]==lookahead
map <string, int>VoidFunction;
ofstream output("output.txt", ios::out);
void MatchToken(string expected);
void parse0(); //<字符串>
void parse1(); //<程序>
void parse2(); //<常量说明>
void parse3(); //<常量定义>
void parse4(); //<无符号整数>
void parse5(); //<整数>
void parse6(); //<声明头部>
void parse7(); //<变量说明>
void parse8(); //<变量定义>
void parse9(); //<有返回值函数定义>
void parse10(); //<无返回值函数定义>
void parse11(); //<复合语句>
void parse12(); //<参数表>
void parse13(); //<主函数>
void parse14(); //<表达式>
void parse15(); //<项>
void parse16(); //<因子>
void parse17(); //<语句>
void parse18(); //<赋值语句>
void parse19(); //<条件语句>
void parse20(); //<条件>
void parse21(); //<循环语句>
void parse22(); //<步长>
void parse234(); //<有无返回值函数调用语句>
void parse25(); //<值参数表>
void parse26(); //<语句列>
void parse27(); //<读语句>
void parse28(); //<写语句>
void parse29(); //<返回语句>
void GrammarAnalysis()
{
q = 0;
parse1();
output.close();
return;
}
void parse0()
{
//<字符串> ::= "{十进制编码为32,33,35-126的ASCII字符}"
MatchToken("STRCON");
printf("<字符串>\n");
output << "<字符串>\n";
}
void parse1()
{
//<程序> ::= [<常量说明>][<变量说明>]
// {<有返回值函数定义>|<无返回值函数定义>}<主函数>
if (token[q] == "CONSTTK") {
parse2();
}
if ((token[q] == "INTTK" || token[q] == "CHARTK") &&
token[q + 1] == "IDENFR" && token[q + 2] != "LPARENT") {
parse7();
}
while ((token[q] == "INTTK" || token[q] == "CHARTK" || token[q] == "VOIDTK") &&
token[q + 1] == "IDENFR" && token[q + 2] == "LPARENT") {
if (token[q] == "VOIDTK") {
parse10();
}
else {
parse9();
}
}
if (token[q] == "VOIDTK" && token[q + 1] == "MAINTK") {
parse13();
}
if (q == num) {
printf("<程序>\n");
output << "<程序>\n";
return;
}
else {
printf("shitbrofuckingerror");
exit(0);
}
}
void parse2()
{
//<常量说明> ::= const<常量定义>;{ const<常量定义>;}
do {
MatchToken("CONSTTK");
parse3();
MatchToken("SEMICN");
} while (token[q] == "CONSTTK");
printf("<常量说明>\n");
output << "<常量说明>\n";
}
void parse3()
{
//<常量定义> ::= int<标识符>=<整数>{,<标识符>=<整数>}
// | char<标识符>=<字符>{,<标识符>=<字符>}
if (token[q] == "INTTK") {
MatchToken("INTTK");
MatchToken("IDENFR");
MatchToken("ASSIGN");
parse5();
while (token[q] == "COMMA") {
MatchToken("COMMA");
MatchToken("IDENFR");
MatchToken("ASSIGN");
parse5();
}
}
if (token[q] == "CHARTK") {
MatchToken("CHARTK");
MatchToken("IDENFR");
MatchToken("ASSIGN");
MatchToken("CHARCON");
while (token[q] == "COMMA") {
MatchToken("COMMA");
MatchToken("IDENFR");
MatchToken("ASSIGN");
MatchToken("CHARCON");
}
}
printf("<常量定义>\n");
output << "<常量定义>\n";
}
void parse4()
{
//<无符号整数> ::= <非零数字>{<数字>}| 0
if (val[q][0] == '0' && val[q].length() > 1) {
printf("error");
exit(0);
}
else MatchToken("INTCON");
printf("<无符号整数>\n");
output << "<无符号整数>\n";
}
void parse5()
{
//<整数> ::= [+|-]<无符号整数>
if (token[q] == "PLUS")MatchToken("PLUS");
else if (token[q] == "MINU")MatchToken("MINU");
parse4();
printf("<整数>\n");
output << "<整数>\n";
}
void parse6()
{
//<声明头部> ::= int<标识符> |char<标识符>
if (token[q] == "INTTK")MatchToken("INTTK");
else if (token[q] == "CHARTK")MatchToken("CHARTK");
MatchToken("IDENFR");
printf("<声明头部>\n");
output << "<声明头部>\n";
}
void parse7()
{
//<变量说明> ::= <变量定义>;{<变量定义>;}
do {
parse8();
MatchToken("SEMICN");
} while ((token[q] == "INTTK" || token[q] == "CHARTK") &&
token[q + 1] == "IDENFR" && token[q + 2] != "LPARENT");
printf("<变量说明>\n");
output << "<变量说明>\n";
}
void parse8()
{
//<变量定义> ::= <类型标识符>
// (<标识符>|<标识符>'['<无符号整数>']')
// {,(<标识符>|<标识符>'['<无符号整数>']')}
if (token[q] == "INTTK")MatchToken("INTTK");
else if (token[q] == "CHARTK")MatchToken("CHARTK");
MatchToken("IDENFR");
if (token[q] == "LBRACK") {
MatchToken("LBRACK");
parse4();
MatchToken("RBRACK");
}
while (token[q] == "COMMA") {
MatchToken("COMMA");
MatchToken("IDENFR");
if (token[q] == "LBRACK") {
MatchToken("LBRACK");
parse4();
MatchToken("RBRACK");
}
}
printf("<变量定义>\n");
output << "<变量定义>\n";
}
void parse9()
{
//<有返回值函数定义> ::= <声明头部>'('<参数表>')' '{'<复合语句>'}'
parse6();
MatchToken("LPARENT");
parse12();
MatchToken("RPARENT");
MatchToken("LBRACE");
parse11();
MatchToken("RBRACE");
printf("<有返回值函数定义>\n");
output << "<有返回值函数定义>\n";
}
void parse10()
{
//<无返回值函数定义> ::= void<标识符>'('<参数表>')''{'<复合语句>'}'
MatchToken("VOIDTK");
VoidFunction[val[q]] = 1;
MatchToken("IDENFR");
MatchToken("LPARENT");
parse12();
MatchToken("RPARENT");
MatchToken("LBRACE");
parse11();
MatchToken("RBRACE");
printf("<无返回值函数定义>\n");
output << "<无返回值函数定义>\n";
}
void parse11()
{
//<复合语句> ::= [<常量说明>][<变量说明>]<语句列>
if (token[q] == "CONSTTK") {
parse2();
}
if ((token[q] == "INTTK" || token[q] == "CHARTK") &&
token[q + 1] == "IDENFR" && token[q + 2] != "LPARENT") {
parse7();
}
parse26();
printf("<复合语句>\n");
output << "<复合语句>\n";
}
void parse12()
{
//<参数表> ::= <类型标识符><标识符>{,<类型标识符><标识符>}| <空>
if (token[q] != "RPARENT")//如果下一个token为右小括号,则为空
{
if (token[q] == "INTTK")MatchToken("INTTK");
else if (token[q] == "CHARTK")MatchToken("CHARTK");
MatchToken("IDENFR");
while (token[q] == "COMMA") {
MatchToken("COMMA");
if (token[q] == "INTTK")MatchToken("INTTK");
else if (token[q] == "CHARTK")MatchToken("CHARTK");
MatchToken("IDENFR");
}
}
printf("<参数表>\n");
output << "<参数表>\n";
}
void parse13()
{
//<主函数> ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
MatchToken("VOIDTK");
MatchToken("MAINTK");
MatchToken("LPARENT");
MatchToken("RPARENT");
MatchToken("LBRACE");
parse11();
MatchToken("RBRACE");
printf("<主函数>\n");
output << "<主函数>\n";
}
void parse14()
{
//14<表达式> ::= [+|-]<项>{<加法运算符><项>}
if (token[q] == "PLUS")MatchToken("PLUS");
else if (token[q] == "MINU")MatchToken("MINU");
parse15();
while (token[q] == "PLUS" || token[q] == "MINU")
{
if (token[q] == "PLUS")MatchToken("PLUS");
else if (token[q] == "MINU")MatchToken("MINU");
parse15();
}
printf("<表达式>\n");
output << "<表达式>\n";
}
void parse15()
{
//15<项> ::= <因子>{<乘法运算符><因子>}
parse16();
while (token[q] == "MULT" || token[q] == "DIV")
{
if (token[q] == "MULT")MatchToken("MULT");
else if (token[q] == "DIV")MatchToken("DIV");
parse16();
}
printf("<项>\n");
output << "<项>\n";
}
void parse16()
{
//<因子> ::= <标识符>|<标识符>'['<表达式>']'
// |'('<表达式>')'|<整数>|<字符>|<有返回值函数调用语句>
if (token[q] == "IDENFR") {
if (token[q + 1] == "LBRACK") {
MatchToken("IDENFR");
MatchToken("LBRACK");
parse14();
MatchToken("RBRACK");
}
else if (token[q + 1] == "LPARENT")parse234();
else MatchToken("IDENFR");
}
else if (token[q] == "LPARENT") { MatchToken("LPARENT");parse14();MatchToken("RPARENT"); }
else if (token[q] == "INTCON" || token[q] == "PLUS" || token[q] == "MINU")parse5();
else if (token[q] == "CHARCON")MatchToken("CHARCON");
printf("<因子>\n");
output << "<因子>\n";
}
void parse17()
{
/*<语句> ::= <条件语句>|<循环语句>| '{'<语句列>'}'
| <有返回值函数调用语句>; |<无返回值函数调用语句>;|<赋值语句>;
|<读语句>;|<写语句>;|<空>;|<返回语句>;
*/
if (token[q] == "IFTK")parse19();
else if (token[q] == "WHILETK" || token[q] == "DOTK" || token[q] == "FORTK")parse21();
else if (token[q] == "LBRACE") { MatchToken("LBRACE");parse26();MatchToken("RBRACE"); }
else if (token[q] == "IDENFR")
{
if (token[q + 1] == "LPARENT") { parse234();MatchToken("SEMICN"); }
else { parse18();MatchToken("SEMICN"); }
}
else if (token[q] == "SCANFTK") { parse27();MatchToken("SEMICN"); }
else if (token[q] == "PRINTFTK") { parse28();MatchToken("SEMICN"); }
else if (token[q] == "RETURNTK") { parse29();MatchToken("SEMICN"); }
else if (token[q] == "SEMICN")MatchToken("SEMICN");
printf("<语句>\n");
output << "<语句>\n";
}
void parse18()
{
//<赋值语句> ::= <标识符>=<表达式>
// |<标识符>'['<表达式>']'=<表达式>
MatchToken("IDENFR");
if (token[q] == "LBRACK") { MatchToken("LBRACK");parse14();MatchToken("RBRACK"); }
MatchToken("ASSIGN");
parse14();
printf("<赋值语句>\n");
output << "<赋值语句>\n";
}
void parse19()
{
//<条件语句> ::= if '('<条件>')'<语句>[else<语句>]
MatchToken("IFTK");
MatchToken("LPARENT");
parse20();
MatchToken("RPARENT");
parse17();
if (token[q] == "ELSETK")
{
MatchToken("ELSETK");
parse17();
}
printf("<条件语句>\n");
output << "<条件语句>\n";
}
void parse20()
{
//<条件> ::= <表达式><关系运算符><表达式> //整型表达式之间才能进行关系运算
// |<表达式> //表达式为整型,其值为0条件为假,值不为0时条件为真
parse14();
if (token[q] == "LSS" || token[q] == "LEQ" || token[q] == "GRE"
|| token[q] == "GEQ" || token[q] == "EQL" || token[q] == "NEQ") {
MatchToken(token[q]);
parse14();
}
printf("<条件>\n");
output << "<条件>\n";
}
void parse21()
{
//<循环语句> ::= while '('<条件>')'<语句>
// |do<语句>while '('<条件>')'
// |for'('<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>')'<语句>
if (token[q] == "WHILETK") {
MatchToken("WHILETK");
MatchToken("LPARENT");
parse20();
MatchToken("RPARENT");
parse17();
}
else if (token[q] == "DOTK") {
MatchToken("DOTK");
parse17();
MatchToken("WHILETK");
MatchToken("LPARENT");
parse20();
MatchToken("RPARENT");
}
else if (token[q] == "FORTK") {
MatchToken("FORTK");
MatchToken("LPARENT");
MatchToken("IDENFR");
MatchToken("ASSIGN");
parse14();
MatchToken("SEMICN");
parse20();
MatchToken("SEMICN");
MatchToken("IDENFR");
MatchToken("ASSIGN");
MatchToken("IDENFR");
if (token[q] == "PLUS")MatchToken("PLUS");
else if (token[q] == "MINU")MatchToken("MINU");
parse22();
MatchToken("RPARENT");
parse17();
}
printf("<循环语句>\n");
output << "<循环语句>\n";
}
void parse22()
{
//<步长>::= <无符号整数>
parse4();
printf("<步长>\n");
output << "<步长>\n";
}
void parse234()
{
//<有无返回值函数调用语句> ::= <标识符>'('<值参数表>')'
int FunctionType = VoidFunction[val[q]];
MatchToken("IDENFR");
MatchToken("LPARENT");
parse25();
MatchToken("RPARENT");
if (FunctionType == 1)output << "<无返回值函数调用语句>\n";
else output << "<有返回值函数调用语句>\n";
}
void parse25()
{
//<值参数表> ::= <表达式>{,<表达式>}|<空>
if (token[q] != "RPARENT")
{
parse14();
while (token[q] == "COMMA")
{
MatchToken("COMMA");
parse14();
}
}
printf("<值参数表>\n");
output << "<值参数表>\n";
}
void parse26()
{
//<语句列> ::= {<语句>}
while (token[q] != "RBRACE")parse17();
printf("<语句列>\n");
output << "<语句列>\n";
}
void parse27()
{
//<读语句> ::= scanf '('<标识符>{,<标识符>}')'
MatchToken("SCANFTK");
MatchToken("LPARENT");
MatchToken("IDENFR");
while (token[q] == "COMMA") {
MatchToken("COMMA");
MatchToken("IDENFR");
}
MatchToken("RPARENT");
printf("<读语句>\n");
output << "<读语句>\n";
}
void parse28()
{
//<写语句> ::= printf '(' <字符串>,<表达式> ')'
// | printf '('<字符串> ')'
// | printf '('<表达式>')'
MatchToken("PRINTFTK");
MatchToken("LPARENT");
if (token[q] == "STRCON")parse0();
else parse14();
if (token[q] == "COMMA") { MatchToken("COMMA");parse14(); }
MatchToken("RPARENT");
printf("<写语句>\n");
output << "<写语句>\n";
}
void parse29()
{
//<返回语句> ::= return['('<表达式>')']
MatchToken("RETURNTK");
if (token[q] == "LPARENT") { MatchToken("LPARENT");parse14();MatchToken("RPARENT"); }
printf("<返回语句>\n");
output << "<返回语句>\n";
}
void MatchToken(string expected)
{
if (token[q] == expected) {
cout << token[q] << " " << val[q] << endl;
output << token[q] << " " << val[q] << endl;
q++;
}
else {
printf("shitbrofuckingerror_tm");
exit(0);
}
}
#include "WordAnalysis.h"
#include "GrammarAnalysis.h"
int main()
{
read();
WordAnalysis();
GrammarAnalysis();
return 0;
}