语法分析1

/**外部定义**/
/**
翻译单元
<translation_unit>::={<external_declaration>}<TK_EOF>
源文件就是一个翻译单元
翻译单元由0或多个外部声明+一个文件结束符组成
**/
void translation_unit()
{
    while(token!=TK_EOF)
    {
        external_declaration(SC_GLOBAL);/**由于外部声明和内部声明形式差不多,所以都用这个函数,就是参数不同**/
    }
}
/**
外部声明
<external_declaration>::=<function_definition>|<declaration>
<function_definition>::=<type_specifier><declarator><funcbody>
<declaration>::=<type_specifier><TK_SEMICOLON>
    |<type_specifier><init_declarator_list><TK_SEMICOLON>
<init_declarator_list>::=<init_declarator>{<TK_COMMA><init_declarator>}
<init_declarator>::=
    <declarator>[<TK_ASSIGN><initializer>]
等价转换为:
<external_declaration>::=<type_specifier>
    (
     <TK_SEMICOLON>
    |<declarator><funcbody>
    |<declarator>[<TK_ASSIGN><initializer>]{<TK_COMMA><declarator>[<TK_ASSIGN><initializer>]}<TK_SEMICOLON>
     )
解析外部声明
l:存储类型,局部的还是全局的
**/
void external_declaration(int l)
{
    if(!type_specifier())
    {
        error("<类型区分符>");
    }
    if(token==TK_SEMICOLON)
    {
        get_token();
        return;
    }
    while(1)
    {
        declarator();
        if(token==TK_BEGIN)
        {
            if(l==SC_LOCAL)
                error("不支持函数嵌套定义");
            funcbody();
            break;
        }
        else
        {
            if(token==TK_ASSIGN)
            {
                get_token();
                initializer();
            }
            if(token==TK_COMMA)
            {
                get_token();
            }
            else
            {
                syntax_state=SNTX_LF_HT;
                skip(TK_SEMICOLON);
                break;
            }
        }
    }
}
/**
解析类型区分符
返回值:是否发现合法的类型区分符
<type_specifier>::=<KW_INT>
    |<KW_CHAR>
    |<KW_SHORT>
    |<KW_VOID>
    |<struct_specifier>
**/
int type_specifier()
{
    int type_found=0;
    switch(token)
    {
    case KW_INT:
    case KW_CHAR:
    case KW_SHORT:
    case KW_VOID:
        type_found=1;
        syntax_state=SNTX_SP;
        get_token();
        break;
    case KW_STRUCT:
        syntax_state=SNTX_SP;
        struct_specifier();
        type_found=1;
        break;
    default:
        break;
    }
    return type_found;
}
/**
结构区分符
<struct_specifier>::=
<KW_STRUCT><IDENTIFIER>[<TK_BEGIN><struct_declaration_list><TK_END>]
**/
void struct_specifier()
{
    int v;
    get_token();
    v=token;

    syntax_state=SNTX_DELAY;        /**延迟到取出下一个单词后确定输出格式**/
    get_token();
    if(token==TK_BEGIN)             /**适用于结构体定义**/
        syntax_state=SNTX_LF_HT;
    else if(token==TK_CLOSEPA)      /**适用于sizeof(struct struct_name)**/
        syntax_state=SNTX_NUL;
    else                            /**适用于结构变量声明**/
        syntax_state=SNTX_SP;
    syntax_indent();
    if(v<TK_IDENT)                  /**关键字不能作为结构名称**/
        expect("结构体名");
    if(token==TK_BEGIN)
    {
        struct_declaration_list();
    }
}
/**
结构声明符表
<struct_declaration_list>::=<struct_declaration>{<struct_declaration>}
**/
void struct_declaration_list()
{
    syntax_state=SNTX_LF_HT;    /**第一个结构体成员与'('不写在一行**/
    syntax_level++;             /**结构体成员变量声明,缩进增加一级**/
    get_token();
    while(token!=TK_END)
        struct_declaration();
    skip(TK_END);               /**内含一个get_token()**/
    syntax_state=SNTX_LF_HT;
}
/**
结构声明
<struct_declaration>::=
    <type_specifier><struct_declarator_list><TK_SEMICOLON>
<struct_declarator_list>::=<declarator>{<TK_COMMA><declarator>}
**/
void struct_declaration()
{
    type_specifier();
    while(1)
    {
        declarator();
        if(token==TK_SEMICOLON)
            break;
        skip(TK_COMMA);
    }
    syntax_state=SNTX_LF_HT;
    skip(TK_SEMICOLON);
}
/**
函数调用约定
<function_calling_convention>::=<KW_CDECL>|<KW_STDCALL>
用在函数声明上,用在数据声明上忽略掉
**/
void function_calling_convention(int *fc)
{
    *fc=KW_CDECL;
    if(token==KW_CDECL||token==KW_STDCALL)
    {
        *fc=token;
        syntax_state=SNTX_SP;
        get_token();
    }
}
/**
结构成员对齐
<struct_member_alignment>::=<KW_AlIGN><TK_OPENPA><TK_CINT><TK_CLOSEPA>
**/
void struct_member_alignment()
{
    if(token==KW_ALIGN)
    {
        get_token();
        skip(TK_OPENPA);
        if(token==TK_CINT)
        {
            get_token();
        }
        else
            expect("整数常量");
        skip(TK_CLOSEPA);
    }
}
/**
声明符
<declarator>::={<pointer>}[<function_calling_convention>]
[<struct_member_alignment>]<direct_declarator>
<pointer>::=<TK_STAR>
**/
void declarator()
{
    int fc;
    while(token==TK_STAR)
        get_token();
    function_calling_convention();
    struct_member_alignment();
    direct_declarator();
}
/**
直接声明符
<direct_declarator>::=<IDENTIFIER><direct_declarator_postfix>
**/
void direct_declarator()
{
    if(token>=TK_IDENT)
    {
        get_token();
    }
    else
    {
        expect("标识符");
    }
    direct_declarator_postfix();
}
/**
直接声明符后缀
<direct_declarator_postfix>::={
    <TK_OPENBR>[<TK_CINT>]<TK_CLOSEBR>
    |<TK_OPENPA>[<parameter_type_list>]<TK_CLOSEPA>
}
**/
void direct_declarator_postfix()
{
    if(token==TK_OPENBR)
    {
        get_token();
        if(token==TK_CINT){
            get_token();
        }
    skip(TK_CLOSEBR);
    direct_declarator_postfix();
    }
    else if(token==TK_OPENPA)
    {
        parameter_type_list();
    }

}
/**
形参类型表
<parameter_type_list>::=<parameter_list>
    |<parameter_list><TK_COMMA><TK_ELLIPSIS>
<parameter_list>::=<parameter_declaration>{<TK_COMMA><parameter_declaration>}
<parameter_declaration>::=<type_specifier>{<declarator>}
等价转换后文法
<parameter_type_list>::=<type_specifier><declarator>
    {<TK_COMMA><type_specifier><declarator>}[<TK_COMMA><TK_ELLIPSIS>]
**/

void parameter_type_list(int func_call)
{
    get_token();
    while(token!=TK_CLOSEPA)
    {
        if(!type_specifier())
        {
            error("无效类型标识符");
        }
        declarator();
        if(token=TK_CLOSEPA)
            break;
        skip(TK_COMMA);
        if(token==TK_ELLIPSIS)
        {
            func_call=KW_CDECL;
            get_token();
            break;
        }
        
    }
    syntax_state=SNTX_DELAY;
    skip(TK_CLOSEPA);
    if(token==TK_BEGIN)         //函数定义
        syntax_state=SNTX_LF_HT;
    else                        //函数声明
        syntax_state=SNTX_NUL;
    syntax_indent();            /**出现这有何用意?**/
}
/**
函数体
<funcbody>::=<compound_statement>
**/
void funcbody()
{
    compound_statement();       //复合语句
}
/**
初值符
<initializer>::=<assignment_expression>
**/
void initializer()
{
    assignment_expression();    /**在语句篇会提到**/
}


第三次上机—语法分析1 目的:熟练掌握自上而下的语法分析方法,并能用C++程序实现。 要求: 1. 使用的文法如下: E ® TE ¢ E ¢ ® + TE ¢ | e T ® FT ¢ T ¢ ® * FT ¢ | e F ® (E) | id 2. 对于任意给定的输入串(词法记号流)进行语法分析,递归下降方法和非递归预测分析方法可以任选其一来实现。 3. 要有一定的错误处理功能。即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。可以参考书上介绍的同步记号集合来处理。 可能的出错情况:idid*id, id**id, (id+id, +id*+id …… 4. 输入串以#结尾,输出推导过程中使用到的产生式。例如: 输入:id+id*id# 输出:E ® TE ¢ T ® FT ¢ F ® id E ¢ ® + TE ¢ T ® FT ¢ …… 如果输入串有错误,则在输出中要体现是跳过输入串的某些记号了,还是弹栈,弹出某个非终结符或者是终结符了,同时给出相应的出错提示信息。比如: idid*id对应的出错信息是:“输入串跳过记号id,用户多输入了一个id”; id**id对应的出错信息是:“弹栈,弹出非终结符F,用户少输入了一个id” (id+id对应的出错信息是:“弹栈,弹出终结符 ) ,用户少输入了一个右括号(或者说,括号不匹配)” 有余力的同学可进一步考虑如下扩展: 1. 将递归下降方法和非递归预测分析方法都实现 2. 在语法分析的过程中调用第二次上机的结果,即利用词法分析器来返回一个记号给语法分析器。 3. 编写First和Follow函数,实现其求解过程。 测试文法: A->BCDE B->aBA|ε C->F|ε D->b|c|ε E->e|ε F->d|ε
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值