functype的常量 是不是写对了??

博客围绕functype常量书写是否正确展开探讨,虽内容简短,但聚焦信息技术领域中常量书写这一关键问题。

functype的常量 是不是写对了??

【问题描述】 请根据给定的文法设计并实现语法分析程序,能基于上次作业的词法分析程序所识别出的单词,识别出各类语法成分。输入输出及处理要求如下: (1)需按文法规则,用递归子程序法对文法中定义的语法成分进行分析; (2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要错文件名);输出的结果文件统一命名为output.txt(注意不要错文件名);结果文件中包含如下两种信息: 1)按词法分析识别单词的顺序,按行输出每个单词的信息(要求同词法分析作业,对于预读的情况不能输出)。 2)在文法中出现(除了<BlockItem>, <Decl>, <BType> 之外)的语法分析成分分析结束前,另起一行输出当前语法成分的名字,形如“<Stmt>”(注:未要求输出的语法成分仍需要进行分析,但无需输出) 文法: SysY 语⾔的⽂法表示如下,其中 CompUnit 为文法开始符号。 序号 含义 产生式左部 定义符号 产生式右部 备注 1 编译单元 CompUnit → {Decl} {FuncDef} MainFuncDef // 1.是否存在Decl 2.是否存在FuncDef 2 声明 Decl → ConstDecl | VarDecl // 覆盖两种声明 3 函数定义 FuncDef → FuncType Ident '(' [FuncFParams] ')' Block // 1.⽆形参 2.有形 参 4 主函数定义 MainFuncDef → 'int' 'main' '(' ')' Block // 存在main函数 5 常量声明 ConstDecl → 'const' BType ConstDef { ',' ConstDef } ';' // 花括号内重复0次或多次,单引号引起来的是终结符 6 变量声明 VarDecl → BType VarDef { ',' VarDef } ';' // 花括号内重复0次或多次 7 函数类型 FuncType → 'void' | 'int' | 'float' // 覆盖两种类型的函数 8 标识符 Ident → identifier-nondigit | identifier identifier-nondigit | identifier digit 词法分析 9 函数形参表 FuncFParams → FuncFParam { ',' FuncFParam } // 花括号内重复0次或多次 10 语句块 Block → {' { BlockItem } '}' // 花括号内重复0次或多次 11 基本类型 BType → 'int'|'float' // 存在即可 12 变量定义 VarDef → Ident { '[' ConstExp ']' } | Ident { '[' ConstExp ']' } '=' InitVal // 包含普通变量、⼀维数组、⼆维数组定义 13 函数形参 FuncFParam → BType Ident ['[' ']' { '[' ConstExp ']' }] // 1.普通变量 2.⼀维数组变量 3.⼆维数组变量 14 语句块项 BlockItem → Decl | Stmt // 覆盖两种语句块项 15 常量表达式 ConstExp → AddExp 注:使⽤的Ident 必须是常量 // 存在即可 16 变量初值 InitVal → Exp | '{' [ InitVal { ',' InitVal } ] '}' // 1.表达式初值 2.⼀维数组初值 3.⼆维数组初值 17 语句 Stmt → LVal '=' Exp ';' | [Exp] ';'| Block | 'if' '(' Cond ')' Stmt ['else' Stmt] | 'while' '(' Cond ')' Stmt | 'break' ';' | 'continue' ';' | 'return' [Exp] ';' | LVal '=' 'getint''('')'';' | 'printf''('FormatString{','Exp}')'';' // 1.每种类型的语句都要覆盖;//2.有⽆Exp两种情况;// 4.有else和⽆else; // 7.有⽆Exp两种情况; // 10.有⽆Exp两种情况 18 加减表达式 AddExp → MulExp | AddExp ('+' | '−') MulExp // 1.MulExp 2.+ 需覆盖 3.-需覆盖 19 表达式 Exp → AddExp 注:SysY 表达式是int 型表达式 // 存在即可 20 左值表达式 LVal → Ident {'[' Exp ']'} //1.普通变量 2.⼀维数组 3.⼆维数组 21 条件表达式 Cond → LOrExp // 存在即可 22 格式字符串终结符 FormatString → '"'{<Char>}'"' 词法分析 23 乘除模表达式 MulExp → UnaryExp | MulExp ('*' | '/' | '%') UnaryExp //1.UnaryExp 2.* 3./ 4.% 均需覆盖 24 逻辑或表达式 LOrExp → LAndExp | LOrExp '||' LAndExp // 1.LAndExp 2.|| 均需覆盖 25 逻辑与表达式 LAndExp → EqExp | LAndExp '&&' EqExp // 1.EqExp 2.&& 均需覆盖 26 相等性表达式 EqExp → RelExp | EqExp ('==' | '!=') RelExp // 1.RelExp 2.== 3.!=均需覆盖 27 ⼀元表达式 UnaryExp → PrimaryExp | Ident '(' [FuncRParams] ')'|UnaryOp UnaryExp // 3种情况均需覆盖,函数调⽤也需要覆盖FuncRParams的不同情况 28 关系表达式 RelExp → AddExp | RelExp ('<' | '>' | '<=' | '>=') AddExp // 1.AddExp 2.< 3.> 4.<= 5.>= 均需覆盖 29 <Char> → <FormatChar> | <NormalChar> 词法分析 30 <FormatChar> → %d 词法分析 31 <NormalChar> → ⼗进制编码为32,33,40-126的ASCII字符,'\'(编码92)出现当且仅当为'\n' 词法分析:为了与 gcc 评测结果⼀致,( <NormalChar>的转义字符有且仅有 '\n',其余情况,'\' 单独出现是不合法的) 32 基本表达式 PrimaryExp → '(' Exp ')' | LVal | Number // 三种情况均需覆盖 33 函数实参表 FuncRParams → Exp { ',' Exp } // 1.花括号内重复0次 2.花括号内重复多次 3.Exp需要覆盖数组传参和部分数组传参 34 数值 Number → IntConst // 存在即可 35 整数 IntConst → decimal-const | 0 词法分析 36 十进制数 decimal-const → nonzero-digit | decimal-const digit 词法分析 37 非零数字 nonzero-digit → 1|2|3|4|5|6|7|8|9 词法分析 38 单目运算符 UnaryOp → '+' | '-' | '!' //'!'仅出现在条件表达式中 39 常量初值 ConstInitVal → ConstExp | '{'[ConstInitVal{','ConstInitVal}] '}' 40 常数定义 ConstDef → Ident{'['ConstExp']'} | Ident{'['ConstExp']'}'='ConstInitVal 【输入形式】testfile.txt中的符合文法要求的测试程序。 【输出形式】按如上要求将语法分析结果输出至output.txt中。 【特别提醒】(1)本次作业只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。 (2)当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。 【样例输入】 int main(){ int c; c= getint(); printf("%d",c); return c; } 【样例输出】 INTTK int MAINTK main LPARENT ( RPARENT ) LBRACE { INTTK int IDENFR c <VarDef> SEMICN ; <VarDecl> IDENFR c <LVal> ASSIGN = GETINTTK getint LPARENT ( RPARENT ) SEMICN ; <Stmt> PRINTFTK printf LPARENT ( STRCON "%d" COMMA , IDENFR c <LVal> <PrimaryExp> <UnaryExp> <MulExp> <AddExp> <Exp> RPARENT ) SEMICN ; <Stmt> RETURNTK return IDENFR c <LVal> <PrimaryExp> <UnaryExp> <MulExp> <AddExp> <Exp> SEMICN ; <Stmt> RBRACE } <Block> <MainFuncDef> <CompUnit>
11-15
词法分析实验从文法的解读开始。 请仔细阅读下面的文法,要求对文法中每条规则所定义的语法成分进行分析,了解其作用、限定条件、组合情况和可能产生出的句子,在此基础上,编3-6个测试程序,要求所有测试程序能共同覆盖所有语法规则及每条规则内的常见组合情况,每个测试程序有且仅有10条语句(每个测试程序的第一条语句请用printf '('<字符串> ')'输出自己的学号,其他语句需尽量反映出程序定义的数据及其运算结果,以便在后续阶段测试各种语法成分翻译的正确性)。请提供每个测试程序的输入数据(有<读语句>则提供,否则无需提供)、输出数据(输出数据必须提供。若输入输出数据没有正确提供,评测时会报错),放到文件中,按下述要求为文件命名: 测试程序及对应的输入输出数据文件分别为 testfile1.txt input1.txt output1.txt testfile2.txt input2.txt output2.txt ... testfilen.txt inputn.txt outputn.txt 将以上文件打包为rar或zip文件后上传(请直接打包文件,不用置于文件夹中打包)。 需独立完成,发现雷同按作弊处理 注:本学期部分实验针对此文法,后续作业需在上一次作业的基础上进行增量式开发 编译器课程设计文法如下(详见文档编译实验文法定义及相关说明.pdf): 补充更新内容: 1. 常量数组不能作为参数传递; 2. 相邻的 UnaryOp 不能相同,如 i = --+4; 是不符合语义约束的; 3. UnaryOp 为 '!' 时只能出现在条件表达式中; 4. ConstExp -> AddExp 这条规则所涉及的 Ident 必须为常量; 5. printf 语句中的转义字符有且仅有 '\n',即为了与 gcc 评测结果保持一致, '\' 不能单独出现(将视为不符合文法),只可以与 'n' 结对出现。 6. 为了简化后续同学们开发编译器的难度,有返回值的函数的最后一个 <stmt> 一定是 return 语句(注意是 <FuncDef> 中 <Block> 的最后一个语句) 7. 对于整数数字的要求:不含前导0,但数字 0 是合法的。 8. main 函数的返回值只能为 0。 【提示】有不少同学的错误在于输入输出不匹配,输出文件的行尾缺少本应该输出的空格。这种情况请用电脑自带的文本编辑器来保存文件并上传,有的 IDE 如 jetbrain 那一套,保存后会自动抹去行尾空格,造成输出不一致的问题。 编译单元 CompUnit → {Decl} {FuncDef} MainFuncDef // 1.是否存在Decl 2.是否存在FuncDef 声明 Decl → ConstDecl | VarDecl // 覆盖两种声明 常量声明 ConstDecl → 'const' BType ConstDef { ',' ConstDef } ';' // 1.花括号内重复0次 2.花括号内重复多次 基本类型 BType → 'int' // 存在即可 常数定义 ConstDef → Ident { '[' ConstExp ']' } '=' ConstInitVal // 包含普通变量、一维数组、二维数组共三种情况 常量初值 ConstInitVal → ConstExp | '{' [ ConstInitVal { ',' ConstInitVal } ] '}' // 1.常表达式初值 2.一维数组初值 3.二维数组初值 变量声明 VarDecl → BType VarDef { ',' VarDef } ';' // 1.花括号内重复0次 2.花括号内重复多次 变量定义 VarDef → Ident { '[' ConstExp ']' } // 包含普通变量、一维数组、二维数组定义 | Ident { '[' ConstExp ']' } '=' InitVal 变量初值 InitVal → Exp | '{' [ InitVal { ',' InitVal } ] '}'// 1.表达式初值 2.一维数组初值 3.二维数组初值 函数定义 FuncDef → FuncType Ident '(' [FuncFParams] ')' Block // 1.无形参 2.有形参 主函数定义 MainFuncDef → 'int' 'main' '(' ')' Block // 存在main函数 函数类型 FuncType → 'void' | 'int' // 覆盖两种类型的函数 函数形参表 FuncFParams → FuncFParam { ',' FuncFParam } // 1.花括号内重复0次 2.花括号内重复多次 函数形参 FuncFParam → BType Ident ['[' ']' { '[' ConstExp ']' }] // 1.普通变量 2.一维数组变量 3.二维数组变量 语句块 Block → '{' { BlockItem } '}' // 1.花括号内重复0次 2.花括号内重复多次 语句块项 BlockItem → Decl | Stmt // 覆盖两种语句块项 语句 Stmt → LVal '=' Exp ';' // 每种类型的语句都要覆盖 | [Exp] ';' //有无Exp两种情况 | Block | 'if' '( Cond ')' Stmt [ 'else' Stmt ] // 1.有else 2.无else | 'while' '(' Cond ')' Stmt | 'break' ';' | 'continue' ';' | 'return' [Exp] ';' // 1.有Exp 2.无Exp | LVal = 'getint''('')'';' | 'printf' '('FormatString {',' Exp} ')'';' // 1.有Exp 2.无Exp 表达式 Exp → AddExp 注:SysY 表达式是int 型表达式 // 存在即可 条件表达式 Cond → LOrExp // 存在即可 左值表达式 LVal → Ident {'[' Exp ']'} //1.普通变量 2.一维数组 3.二维数组 基本表达式 PrimaryExp → '(' Exp ')' | LVal | Number // 三种情况均需覆盖 数值 Number → IntConst // 存在即可 一元表达式 UnaryExp → PrimaryExp | Ident '(' [FuncRParams] ')' // 三种情况均需覆盖,函数调用也需要覆盖FuncRParams的不同情况 | UnaryOp UnaryExp // 存在即可 单目运算符 UnaryOp → '+' | '−' | '!' 注:'!'仅出现在条件表达式中 // 三种均需覆盖 函数实参表 FuncRParams → Exp { ',' Exp } // 1.花括号内重复0次 2.花括号内重复多次 3. Exp需要覆盖数组传参和部分数组传参 乘除模表达式 MulExp → UnaryExp | MulExp ('*' | '/' | '%') UnaryExp // 1.UnaryExp 2.* 3./ 4.% 均需覆盖 加减表达式 AddExp → MulExp | AddExp ('+' | '−') MulExp // 1.MulExp 2.+ 3.- 均需覆盖 关系表达式 RelExp → AddExp | RelExp ('<' | '>' | '<=' | '>=') AddExp // 1.AddExp 2.< 3.> 4.<= 5.>= 均需覆盖 相等性表达式 EqExp → RelExp | EqExp ('==' | '!=') RelExp // 1.RelExp 2.== 3.!= 均需覆盖 逻辑与表达式 LAndExp → EqExp | LAndExp '&&' EqExp // 1.EqExp 2.&& 均需覆盖 逻辑或表达式 LOrExp → LAndExp | LOrExp '||' LAndExp // 1.LAndExp 2.|| 均需覆盖 常量表达式 ConstExp → AddExp 注:使用的Ident 必须是常量 // 存在即可 格式化字符 FormatChar → %d 普通字符 NormalChar → 十进制编码为32,33,40-126的ASCII字符 字符 Char → FormatChar | NormalChar 格式化字符串 FormatString → '"'{ Char }'"' *请注意: 评测程序对各测试程序进行编译运行,检查输入输出是否与给定的文件一致;计算每个测试程序的覆盖率和所有测试程序的累积覆盖率,得分率=累积覆盖的项数/检查的总项数。若得分率小于90%,不给出提示,请仔细阅读文法补充或完善测试程序;得分率大于等于90%,则可以得到关于未覆盖规则或组合的提示。 测试程序难度分为三个等级:A、B、C,难度依次递减。其中 B 级难度需要包含文法中黄色高亮内容,A 级难度需要包含绿色高亮内容,其中绿色高亮部分,即程序中的条件判断需要【短路求值】规则。上传文件时,请保证有且仅有一个 A 级难度 testfile ,编号为 1;有且仅有两个 B 级难度 testfile,编号为 2 和 3;其余为 C 级难度。即 testfile 编号越小,难度越高。 请同学在本地使用 gcc 8.5.0 以上的版本进行调测,需要替换输入的 getint() 函数为scanf(详见文档第一节)。 如果对测试结果有异议的话,请联系各班助教,课程组将进行错误排查。 评测机输出说明 每一个 testfile的 status 会有三种情况 RIGHT:完全正确(有的时候爆栈也会显示 RIGHT ,但是覆盖率是 0 ,这种情况请联系助教排查) WRONG:如果覆盖率为 0,则表示程序不符合文法及语义约束,同时 detail 中会提示某个 testfile 有问题;如果有覆盖率,则表示程序的输入输出不匹配 Runtime error:gcc 没有跑通你的测试程序 Total 的 status 只有 WRONG 和 RIGHT,RIGHT 的出现当且仅当所有 testfile 的 status 都是 RIGHT Score 是得分,若有一个 testfile 的 status 不为 RIGHT,则得分为0;若都为 RIGHT,则得分为总覆盖率 将文件保存成 utf-8(无 bom)或者 ANSI 的格式,否则可能会影响评测结果。 即使没有输入,也要给一个空的 input.txt 文件。
05-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值