美文网首页
【三】语法分析(1)demo

【三】语法分析(1)demo

作者: Michael_abc | 来源:发表于2019-11-19 10:46 被阅读0次

    前言

    PHP使用的词法分析使用的是Bison,它是将LALR(1)上下文无关语法描述转换为C语言的语法解析器。

    语法分析说明

    %{
    定义头
    %}
    
    %token头定义
    
    %%
    语法格式
    %%
    
    C语言代码
    

    语法分析实例

    先看下bison的示例:计算器

    calc.l(词法解析格式)

    %{
    # include "y.tab.h"
    int lexerror(char *s);
    %}
    
    %%
    "+"     { return ADD; }
    "-"     { return SUB; }
    "*"     { return MUL; }
    "/"     { return DIV; }
    "("     { return LP; }
    ")"     { return RP; }
    [0-9]+  { yylval = atoi(yytext); return NUM; }
    
    \n      { return EOL; }
    [ \t]    { /* ignore white space */ }
    .        { lexerror(yytext); }
    %%
    
    int lexerror(char *s)
    {
      fprintf(stderr, "lexical error: %s\n", s);
    }
    

    calc.y(语法解析格式)

    %{
    #  include <stdio.h>
    
    int yyerror(char *s);
    int yylex();
    
    %}
    
    //set attribute type
    %define api.value.type {int}
    
    /* declare tokens (terminal symbols) */
    %token NUM  256
    %token ADD 257
    %token SUB 258
    %token MUL 259
    %token DIV 260
    %token LP 261
    %token RP 262
    %token EOL 263
    
    %%
    
    start: 
     | start expr EOL { printf("= %d\n> ", $2); };
    
    expr: term
     | expr ADD term { $$ = $1 + $3; }
     | expr SUB term { $$ = $1 - $3; } 
     ;
    
    term: factor { $$ = $1; }
     | term MUL factor { $$ = $1 * $3; }
     | term DIV factor { $$ = $1 / $3; } 
     ;
    
    factor: NUM { $$ = $1; }
     | LP expr RP { $$ = $2; }
     ;
    %%
    int main()
    {
      printf("> "); 
      yyparse();
    }
    int yyerror(char *s)
    {
      fprintf(stderr, "error: %s\n", s);
    }
    

    makefile

    OUT         = calc
    CC          = gcc
    SCANNER     = calc.l
    PARSER      = calc.y
    OBJ         = y.tab.o lex.yy.o
    OUTFILES    = lex.yy.c y.tab.c y.tab.h y.output $(OUT)
    
    build: $(OUT)
    
    clean:
        rm -f *.o $(OUTFILES)
    
    lex.yy.c: $(SCANNER) y.tab.c
        flex $<
    
    y.tab.c: $(PARSER)
        bison -vdty $<
    
    y.tab.o: y.tab.c
        $(CC) -c $<
    
    lex.yy.o: lex.yy.c
        $(CC) -c $<
    
    $(OUT): $(OBJ)
        $(CC) -o $(OUT) $(OBJ) -lfl
    

    运行结果

    root@39b93c626114:/opt/app/calc# ./calc
    > 1+1
    =2
    >1+1-3
    =-1
    >1+6*7-8
    =35
    >
    

    相关文章

      网友评论

          本文标题:【三】语法分析(1)demo

          本文链接:https://www.haomeiwen.com/subject/vnjtvctx.html