• 词法分析程序(编译原理)


    一:词法分析程序的功能:

      输入单词串,以'begin'开始,以'#'结束。如果是文法正确的句子,则输出成功的信息:'输入单词串成功',否则返回错误提示。

           例:

                  输入 begin a:=345 end #

                  输出 输入单词串成功

    二:符号与种码对照表

    单词符号

    种别码

    单词符号

    种别码

    begin

    1

    :

    17

    if

    2

    :=

    18

    then

    3

    < 

    20

    while

    4

    <=

    21

    do

    5

    <> 

    22

    end

    6

    > 

    23

    l(l|d)*

    10

    >=

    24

    dd*

    11

    =

    25

    +

    13

    ;

    26

    -

    14

    (

    27

    *

    15

    )

    28

    /

    16

    #

    0

     

    三:程序代码以及运行结果

    代码:

    #include "stdio.h"
    #include "string.h"
    char prog[100],token[8],ch;
    char *rwtab[6]={"begin","if","then","while","do","end"};
    int syn,p,m,n,sum;
    int kk;
    void factor(void);
    void expression(void);
    void yucu(void);
    void term(void);
    void statement(void);
    void lrparser(void);
    void scaner(void);
    int main(void)
    {
    p=kk=0;
    printf(" 请输入一段以'begin'开头,以'#'结束的单词串: ");
    do
    {
    scanf("%c",&ch);
    prog[p++]=ch;
    }while(ch!='#');
    p=0;
    scaner();
    lrparser();
    //getch();
    }
    void lrparser(void)
    {
    if(syn==1)
    {
    scaner(); /*读下一个单词符号*/
    yucu(); /*调用yucu()函数;*/
    if(syn==6)
    {
    scaner();
    if((syn==0)&&(kk==0))
    printf("输入单词串成功! ");
    }
    else
    {
    if(kk!=1) printf("单词串没有以'#'作为结束! ");
    kk=1;
    }
    }
    else
    {
    printf("单词串没有以'begin'为开头! ");
    kk=1;
    }
    return;
    }
    void yucu(void)
    {
    statement(); /*调用函数statement();*/
    while(syn==26)
    {
    scaner(); /*读下一个单词符号*/
    if(syn!=6)
    statement(); /*调用函数statement();*/
    }
    return;
    }
    void statement(void)
    {
    if(syn==10)
    {
    scaner(); /*读下一个单词符号*/
    if(syn==18)
    {
    scaner(); /*读下一个单词符号*/
    expression(); /*调用函数statement();*/
    }
    else
    {
    printf("单词串 ':=' 表达错误! ");
    kk=1;
    }
    }
    else
    {
    printf("没有效的单词串! ");
    kk=1;
    }
    return;
    }
    void expression(void)
    {
    term();
    while((syn==13)||(syn==14))
    {
    scaner(); /*读下一个单词符号*/
    term(); /*调用函数term();*/
    }
    return;
    }
    void term(void)
    {
    factor();
    while((syn==15)||(syn==16))
    {
    scaner(); /*读下一个单词符号*/
    factor(); /*调用函数factor(); */
    }
    return;
    }
    void factor(void)
    {
    if((syn==10)||(syn==11))
    {
    scaner();
    }
    else if(syn==27)
    {
    scaner(); /*读下一个单词符号*/
    expression(); /*调用函数statement();*/
    if(syn==28)
    {
    scaner(); /*读下一个单词符号*/
    }
    else
    {
    printf("错误 '(' ");
    kk=1;
    }
    }
    else
    {
    printf("单词串有错! ");
    kk=1;
    }
    return;
    }
    void scaner(void)
    {
    sum=0;
    for(m=0;m<8;m++)
    token[m++]=NULL;
    m=0;
    ch=prog[p++];
    while(ch==' ')
    ch=prog[p++];
    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
    {
    while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
    {
    token[m++]=ch;
    ch=prog[p++];
    }
    p--;
    syn=10;
    token[m++]='';
    for(n=0;n<6;n++)
    if(strcmp(token,rwtab[n])==0)
    {
    syn=n+1;
    break;
    }
    }
    else if((ch>='0')&&(ch<='9'))
    {
    while((ch>='0')&&(ch<='9'))
    {
    sum=sum*10+ch-'0';
    ch=prog[p++];
    }
    p--;
    syn=11;
    }
    else
    switch(ch)
    {
    case '<':
    m=0;
    ch=prog[p++];
    if(ch=='>')
    {
    syn=21;
    }
    else if(ch=='=')
    {
    syn=22;
    }
    else
    {
    syn=20;
    p--;
    }
    break;
    case '>':
    m=0;
    ch=prog[p++];
    if(ch=='=')
    {
    syn=24;
    }
    else
    {
    syn=23;
    p--;
    }
    break;
    case ':':
    m=0;
    ch=prog[p++];
    if(ch=='=')
    {
    syn=18;
    }
    else
    {
    syn=17;
    p--;
    }
    break;
    case '+':
    syn=13;
    break;
    case '-':
    syn=14;
    break;
    case '*':
    syn=15;
    break;
    case '/':
    syn=16;
    break;
    case '(':
    syn=27;
    break;
    case ')':
    syn=28;
    break;
    case '=':
    syn=25;
    break;
    case ';':
    syn=26;
    break;
    case '#':
    syn=0;
    break;
    default:
    syn=-1;
    break;
    }
    }

    运行结果截图:

  • 相关阅读:
    Entity Framework 数据并发访问错误原因分析与系统架构优化
    项目中如何使用EF
    Entity Framework版本历史概览
    Entity Framework 6 预热、启动优化
    jQuery EasyUI Datagrid性能优化专题(转)
    jQuery EasyUI Datagrid VirtualScrollView视图简单分析
    用JS判断IE版本的代码
    【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程
    【转】编写高质量代码改善C#程序的157个建议——建议55:利用定制特性减少可序列化的字段
    【转】编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化
  • 原文地址:https://www.cnblogs.com/LauSir139/p/5924029.html
Copyright © 2020-2023  润新知