⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readme.txt

📁 c—语言的句法分析器。读入一个C--语言程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
    :  type_specifer ID
    |  type_specifer '*' ID
    |  type_specifer ID '[' ']'
    |  ELLIPSIS
    ;
用InsertSym加入符号表时若返回值为0,说明它已被定义过
提示出错:redefinition

4.2.3 类型错误
4.2.3.1 运算符操作数两边的类型
在用到运算符的地方
simple_expression => additive_expression relop additive_expression
additive_expression => additive_expression ADDOP term
term => term mulop unary_expression
unary_expression => unaryop unary_expression
判断操作数是否具有所需要的类型
若不是提示出错:illegal, left(或right) operand is not constant( or character)

4.2.3.2 等号两边的类型
在用到等号的地方
expression => var = expression
判断等号两边的类型
若不匹配提示出错:the left and the right type does not match

4.2.3.3 函数调用参数
在函数表funtable里已存放了函数的传入参数的个数和类型
在调用函数时
call => ID ( args )
将传入参数和funtable里的对应函数比较即可
这里用的是LookUpFun函数,它不仅在funtable寻找是否定义了ID这个函数,
并检查传入参数是否正确,它的返回值是函数返回值的类型(找不到返回0)
若找不到函数提示出错:undeclared function
传入参数太少提示出错:too few actual parameters
传入的第i个参数类型不对提示出错:
different types for formal and actual parameter i

4.3 函数调用参数检查的实现
●函数声明时的参数用argtemp缓冲区保存,并在InsertFun函数里,把它加入相应的
  struct fun
  全局变量typecount指示参数个数
●调用函数时传入参数用arg_in缓冲区保存,在LookUpFun函数里用它和函数的声明时
  的参数比较
  全局变量typecheck指示参数个数

5. debug mode
●为了方便调式: ) 在程序中加入很多printf语句
它将输出当前词法分析器运行到哪一步,归约的产生式是什么(只给出一些主要的,若
要更详细的可以去掉在lab3.y的语义动作中的注释符/**/)
●通过输入带-d参数的命令行进入debug模式,见 三. 编译及运行

6. main函数
做成命令行程序,带一个参数,表示输入的C--文件名
若带两个参数,则第二个要为 -d,表示进入debug模式,第三个参数为输入的C--文件名

----------------------------------------------------------------------------
三. 编译及运行
----------------------------------------------------------------------------
1. 源程序名(源程序位于src目录下)
   lab3.l
   lex.yy.c(这是由flex lab3.l生成的)
   lab3.y
   lab3.tab.h  lab3.tab.c(由bison lab3.y -d生成的)
   lab3.c lab3.h

2. 如何编译生成可执行程序
   操作系统     Windows
   使用的编译器 Visual C++ 6.0(SP6)
   flex 版本2.5.4
   bison 版本1.28

   console mode 
   (1)运行cmd
   (2)进入src目录
   (3)src>set BISON_HAIRY=bison.hairy        /*为bison设置环境变量*/
      src>set BISON_SIMPLE=bison.simple
      src>bison -d lab3.y
      src>flex lab3.l
      src>cl lab3.c lab3.tab.c lex.yy.c /Felab3
更方便的,我写了一个批处理文件compile.bat
      src>compile 

3. 如何运行程序
实例(该目录下含老师的测试文件s2.c s3.c和我放的s1.c):
src>lab3                //参数错误,输出提示信息
lab3.exe -- Copyright (C) 2007 cj4 No.04120004
Usage: lab3 [-d] filename
----------------------------------------------------
filename    specifies the name of input file
-d          debug mode

src>lab3 s1.c
line   8 error: unknown character
line   8 error: unknown character
line  14 error: j :redefinition
line  16 error: = :the left and the right type does not match
line  18 error: < :illegal, right operand is not constant or character
line  19 error: % :illegal, left operand is not constant
line  21 error: + :illegal, right operand is not constant
line  24 error: u :undeclared identifier
line  25 error: min : too few actual parameters

src>lab3 s2.c
Well done!                  /* s2.c没有错 */

src>lab3 s3.c
line  15 error: min : different types for formal and actual parameter 2

src>lab3 -d s3.c           /* debug mode */
============= debug mode =============
make symboltable[0]
type_specifer => INT
type_specifer => INT
===========================================================
qt->level=0  level=1 insert_symbol_name=i potential_symboltable[0]
maketable symboltable[1]
actually insert symboltable[1]
===========================================================
param => type_specifer ID
type_specifer => INT
===========================================================
qt->level=1  level=1 insert_symbol_name=j potential_symboltable[1]
actually insert symboltable[1]
===========================================================
param => type_specifer ID
===========================================================
insert function: min in funtable[433]
argument: int int
===========================================================
fun_tag => type_specifer ID
===========================================================
lookup id: i in symboltable[1] hash h=105
tp->buckets[105]->sym.name=i
I find it
===========================================================
var => ID
factor => var
relop => LT
===========================================================
lookup id: j in symboltable[1] hash h=106
tp->buckets[106]->sym.name=j
I find it
===========================================================
var => ID
factor => var
simple_expression => additive_expression relop additive_expression
===========================================================
lookup id: i in symboltable[1] hash h=105
tp->buckets[105]->sym.name=i
I find it
===========================================================
var => ID
factor => var
return_stmt => RETURN expression ;
===========================================================
lookup id: j in symboltable[1] hash h=106
tp->buckets[106]->sym.name=j
I find it
===========================================================
var => ID
factor => var
return_stmt => RETURN expression ;
if_stmt => IF ( expression ) statement ELSE statement
declaration => fun_declaration
type_specifer => VOID
params => VOID
===========================================================
insert function: main in funtable[874]
argument: void
===========================================================
fun_tag => type_specifer ID
type_specifer => INT
===========================================================
qt->level=0  level=1 insert_symbol_name=i potential_symboltable[0]
maketable symboltable[1]
actually insert symboltable[1]
===========================================================
var_declaration => type_specifer ID ;
type_specifer => INT
===========================================================
qt->level=1  level=1 insert_symbol_name=j potential_symboltable[1]
actually insert symboltable[1]
===========================================================
var_declaration => type_specifer ID ;
===========================================================
lookup id: j in symboltable[1] hash h=106
tp->buckets[106]->sym.name=j
I find it
===========================================================
var => ID
factor => NUM
expression => var = expression
expression_stmt => expression ;
===========================================================
lookup id: i in symboltable[1] hash h=105
tp->buckets[105]->sym.name=i
I find it
===========================================================
var => ID
===========================================================
lookup id: j in symboltable[1] hash h=106
tp->buckets[106]->sym.name=j
I find it
===========================================================
var => ID
factor => var
factor => NUM
additive_expression => additive_expression ADDOP term
expression => var = expression
expression_stmt => expression ;
===========================================================
lookup id: i in symboltable[1] hash h=105
tp->buckets[105]->sym.name=i
I find it
===========================================================
var => ID
factor => NUM
factor => NUM
additive_expression => additive_expression ADDOP term
expression => var = expression
expression_stmt => expression ;
===========================================================
lookup id: j in symboltable[1] hash h=106
tp->buckets[106]->sym.name=j
I find it
===========================================================
var => ID
===========================================================
lookup id: i in symboltable[1] hash h=105
tp->buckets[105]->sym.name=i
I find it
===========================================================
var => ID
factor => var
factor => STRING_LITERAL
===========================================================
lookup function: min in funtable[433] and check arguments
===========================================================
line  15 error: min : different types for formal and actual parameter 2
call => ID ( args )
factor => call
expression => var = expression
expression_stmt => expression ;
declaration => fun_declaration
program => declaration_list


四. 花了多少时间?
合起来大概有3天:
一天看yacc/bison的介绍和文档等
一天写程序和调试
一天调试,写实验报告

五. 和谁讨论(还是独立完成)?
独立完成,遇到问题google,百度。。。

六. 问题,解决和体会
1. 使用yacc一般出错在两个地方
●一是
invalid input: 
ill-formed rule: initial symbol not followed by colon
一个非终结符对应多个产生式时要用 | 号
token和非终结符要由字母,点,下划线组成,数字(不在第一个位置)
Names may be of arbitrary length, and may be made up of letters, dot ``.'', 
underscore ``_'', and non-initial digits. Upper and lower case letters are 
distinct. The names used in the body of a grammar rule may represent tokens or 
nonterminal symbols. 
●还有就是
leftside
    :  aaa bbb
       {在这里面$$ $1 $2用错了,类型不匹配等}
    ;

2. 至少还有两个问题没解决
●对于char a[100]的a没有很好的处理,这里只是将它简单的处理成char类型
●对与id_hash_table symboltable funtable中由malloc生成的结构没有释放

●此外较新的bison版本提供了很好用的功能,可以做更好的错误提示,有时间的话将
  改进

3. 看了一些yacc的例子,不如直接自己写了解的快

4. 老师的 C--编译器的示例代码 很有帮助

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -