青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

yacc / lex 在linux 下 使用指南

    Lex 和 Yacc 是 Unix 和Linux 下詞法和語法的分析,解析工具,有了這兩個工具,你可以自己制作想要的編譯器,也可以重新制作已有程序語言的解析器。需要注意的是linux下的這兩個工具生成的程序源碼只能是C和C++語言,當然現在早已有類似可以生成Java源碼的語法分析器,如較常用的JavaCC(Java Compiler Compiler),相關內容可以去網上搜索。Lex和Yacc已被移植到windows下,現在常用的工具有Parser Generator。本文只介紹Linux 下Lex和Yacc的使用方法。


Lex介紹

Lex 通過對.lex或.l文件定義的格式生成一個C語言源碼文件,通過編譯這個源碼,就生成了.lex文件或.l文件定義的編譯器。.lex或.l文件的格式分三段:

1.全局變量聲明部分
2.詞法規則部分
3.函數定義部分

以下是一個簡單的例子:lex_example.l文件

%{            //全局聲明部分
/*林木100 linux
www.linmu100.com
*/
#include <stdio.h>  

extern char *yytext;
extern FILE *yyin;
int sem_count = 0;

%}

//規則定義部分,
%%
[a-zA-Z][a-zA-Z0-9]*    {printf("WORD[%s] ", yytext);}
[a-zA-Z0-9\/.-]+        printf("FILENAME ");
\"                      printf("QUOTE ");
\{                      printf("OBRACE ");
\}                      printf("EBRACE ");
;                       {sem_count++; printf("SEMICOLON ");}
\n                      printf("\n");
[ \t]+                  /* ignore whitespace */;
%%

//以下為函數定義部分
int main(int avgs, char *avgr[]) 
{
    yyin = fopen(avgr[1], "r");
    if (!yyin)
    {
        return 0;
    }
    yylex();
    printf("sem_count : %d\n", sem_count);
    fclose(yyin);

    return 1;
}

Lex 常用格式如下表,常規表達式:

字符

含義

A-Z, 0-9, a-z

構成了部分模式的字符和數字。

.

匹配任意字符,除了 \n。

-

用來指定范圍。例如:A-Z 指從 A 到 Z 之間的所有字符。

[ ]

一個字符集合。匹配括號內的任意 字符。如果第一個字符是 ^ 那么它表示否定模式。例如: [abC] 匹配 a, b, 和 C中的任何一個。

*

匹配0個或者多個上述的模式。

+

匹配1個或者多個上述模式。

?

匹配0個或1個上述模式。

$

作為模式的最后一個字符匹配一行的結尾。

{ }

指出一個模式可能出現的次數。 例如: A{1,3} 表示 A 可能出現1次或3次。

\

用來轉義元字符。同樣用來覆蓋字符在此表中定義的特殊意義,只取字符的本意。

^

否定。

|

表達式間的邏輯或。

"<一些符號>"

字符的字面含義。元字符具有。

/

向前匹配。如果在匹配的模版中的“/”后跟有后續表達式,只匹配模版中“/”前面的部分。如:如果輸入 A01,那么在模版 A0/1 中的 A0 是匹配的。

( )

將一系列常規表達式分組。


常規表達式舉例

常規表達式

含義

joke[rs]

匹配 jokes 或 joker。

A{1,2}shis+

匹配 AAshis, Ashis, AAshi, Ashi。

(A[b-e])+

匹配在 A 出現位置后跟隨的從 b 到 e 的所有字符中的 0 個或 1個。



使用lex掃描上述舉例文件 lex_example.l:
lex lex_example.l
缺省會生成lex.yy.c文件,然后用gcc編譯這個文件,注意要有-ll選項:
gcc lex.yy.c -o analyse -ll
這樣就生成了一個簡單的詞法分析器analyse,假設有文件demo,其內容如下所示:
firstword;
secondword;
thirdword

fourthword{
fifthword
}
輸入命令:
./analyse demo
會有如下顯示:
WORD[firstword] SEMICOLON 
WORD[secondword] SEMICOLON 
WORD[thirdword] 

WORD[fourthword] OBRACE 
WORD[fifthword] 
EBRACE 
sem_count : 2

實際上,對于上述lex_example.l文件,函數定義部分可以完全省略,因為lex會自動為你生成main函數。這時仍然按上述方法生成analyse,輸入命令:
./analse < demo
結果如下:
WORD[firstword] SEMICOLON 
WORD[secondword] SEMICOLON 
WORD[thirdword] 

WORD[fourthword] OBRACE 
WORD[fifthword] 
EBRACE 


在上述lex_example.l文件中我們還使用了兩個變量:
extern char *yytext;
extern FILE *yyin;
這兩個變量是lex提供的外部借口,用戶可以根據自己需要自己更改,lex提供了以下接口:

Lex 變量

yyin

FILE* 類型。 它指向 lexer 正在解析的當前文件。

yyout

FILE* 類型。 它指向記錄 lexer 輸出的位置。 缺省情況下,yyin 和 yyout 都指向標準輸入和輸出。

yytext

匹配模式的文本存儲在這一變量中(char*)。

yyleng

給出匹配模式的長度。

yylineno

提供當前的行數信息。(lexer不一定支持。)

Lex 函數

yylex()

這一函數開始分析。 它由 Lex 自動生成。

yywrap()

這 一函數在文件(或輸入)的末尾調用。如果函數的返回值是1,就停止解析。 因此它可以用來解析多個文件。代碼可以寫在第三段,這就能夠解析多個文件。 方法是使用 yyin 文件指針(見上表)指向不同的文件,直到所有的文件都被解析。最后,yywrap() 可以返回 1 來表示解析的結束。

yyless(int n)

這一函數可以用來送回除了前憂? 個字符外的所有讀出標記。

yymore()

這一函數告訴 Lexer 將下一個標記附加到當前標記后。

以下是一個計算字符個數的.l文件內容,有興趣的朋友可以編譯試試
%{ 
/*
林木100 linux
www.linmu100.com
*/
int wc = 0;        /* word count */ 
%} 
 
%% 
[a-zA-Z]+    { wc++; } 
\n|.        { /* gobble up */ } 
%% 
int main(void) 

    int n = yylex(); 
    return n; 

 
int yywrap(void) 

    printf("word count: %d\n", wc); 
    return 1; 
}

yacc介紹

Yacc 是 Yet Another Compiler Compiler的縮寫。 Yacc 的 GNU 版叫做 Bison。它是一種語法解析工具。它用巴科斯范式(BNF, Backus Naur Form)來書寫。按照慣例,Yacc 文件有 .y 后綴。
實際上,yacc才是真正分析語法的核心,.y文件格式和.l文件一樣分三段,但每一段的意義有所不同:
1.全局變量聲明,終結符號(終端符號)聲明
2.語法定義
3.函數定義

以下是一個簡單的yacc_example.y文件,定義了一個簡單的計算器:
%{ 
//全局變量聲明 
#include <ctype.h> 
#include <stdio.h> 
#define YYSTYPE double /*double type for YACC stack; for yylval*/ 
 
/*林木100 www.linmu100.com */ 
 
void yyerror(const char *str) 

    fprintf(stderr, "error:%s\n", str ); 

%} 
//終結符聲明 
%token NUMBER 
 
%% 
lines    : lines expr '\n'            { printf("%g\n", $2); } 
        | lines '\n' 
        | /* e */ 
        | error '\n'                { yyerror("reenter last line:"); /*yyerrok(); */} 
        ; 
 
expr    : expr '+' term                { $$ = $1 + $3; } 
        | expr '-' term                { $$ = $1 - $3; } 
        | term 
        ; 
 
term    : term '*' factor            { $$ = $1 * $3; } 
        | term '/' factor            { $$ = $1 / $3; } 
        | factor 
        ; 
 
factor    : '(' expr ')'                { $$ = $2; } 
        | '(' expr error            { $$ = $2; yyerror("missing ')'"); /*yyerrok(); */} 
        | '-' factor                { $$ = -$2; } 
        | NUMBER 
        ; 
 
%% 
//以上部分為語法定義,以下部分為函數定義 
int main(void) 

    return yyparse(); 

 
int yylex(void) 

    int c; 
    while ((c = getchar()) == ' '); 
    if (c == '.' || isdigit(c)) { 
        ungetc(c, stdin); 
        scanf("%lf", &yylval); 
        return NUMBER; 
    } 
    return c; 


使用yacc掃描這個文件:
yacc yacc_example.y
缺省會生成一個y.tab.c文件,然后用gcc編譯這個文件,注意要有選項 -ll 或 -ly:
gcc y.tab.c -o analyse -ll
運行./analyse:結果如下圖所示:
clip_image001

現在對照yacc_example.y文件講解一下.y文件的規則:
1.在全局變量聲明部分,聲明了一個接口函數yyerror,這個函數是用來在出錯時調用的。這一段主要是聲明一些變量,數據結構,函數用。
2.%token NUMBER則聲明了一個終端符(終結符),這個符號是由Lex返回的,會在yacc語法規則中用到。
3.語法規則部分則聲明了語法:
    3.1語法規則對外只有一個接口,這一點要注意,初學者常常會犯語法對外有多個接口的錯誤。
    3.2無論是lex文件還是yacc文件都要注意最大可能性的詞法和語法規則要放在沖突規則的前面,這樣保證了最大可能規則會被最先匹配,比如lex文件中:
       temperator      return T1;
       temp             return T2;
        在yacc文件中,例子如下
            command:
                NUMBER CHAR
                |   NUMBER
               ;

對于.y文件還要注意全局語法,以及遞歸的調用。

初學者對于yacc文件規則可能會較為生疏,關鍵還要多做一些練習。


Lex 和 Yacc 的結合

lex和yacc結合時需要注意的是
lex文件頭要引用yacc生成的頭文件:"y.tab.h"

以下是一個lex和yacc結合的實例:
lex_yacc_exp.l文件:
%{
/*林木100
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>
#include "y.tab.h"
extern char *yytext;
%}
%%
[0-9]+                  yylval.number=atoi(yytext); return NUMBER;
heater            return TOKHEATER;
heat                    return TOKHEAT;
on|off                  yylval.number=!strcmp(yytext,"on"); return STATE;
target                  return TOKTARGET;
temperature             return TOKTEMPERATURE;
[a-z0-9]+        yylval.string=strdup(yytext);return WORD;
\n                      /* ignore end of line */;
[ \t]+                  /* ignore whitespace */;
%%

lex_yacc_exp.y文件:
%{
/*林木100
www.linmu100.com
*/
#include <stdio.h>
#include <string.h>

void yyerror(const char *str)
{
    fprintf(stderr,"error: %s\n",str);
}

int yywrap()
{
    return 1;
}

main()
{
    yyparse();
}

char *heater="xl's test";

%}

%token TOKHEATER TOKHEAT TOKTARGET TOKTEMPERATURE

%union 
{
    int number;
    char *string;
}

%token <number> STATE
%token <number> NUMBER
%token <string> WORD

%%

commands:
    | commands command
    ;


command:
    heat_switch | target_set | heater_select

heat_switch:
    TOKHEAT STATE 
    {
        if($2)
            printf("\tHeater '%s' turned on\n", heater);
        else
            printf("\tHeat '%s' turned off\n", heater);
    }
    ;

target_set:
    TOKTARGET TOKTEMPERATURE NUMBER
    {
        printf("\tHeater '%s' temperature set to %d\n",heater, $3);
    }
    ;

heater_select:
    TOKHEATER WORD
    {
        printf("\tSelected heater '%s'\n",$2);
        heater=$2;
    }
    ;

輸入以下命令,分別生成lex.yy.c,y.tab.c,y.tab.h三個文件:
lex lex_yacc_exp.l
yacc -d lex_yacc_exp.y
gcc lex.yy.c y.tab.c -o analyse -ll

創建一個語法用例demo,內容如下:
heat on
target temperature 99
heater asdfsieiwef99adsf

輸入./analyse <demo分析demo文件,會得到以下結果:
clip_image002 


結語:
Lex 和 Yacc 是很強大的工具,這里只簡單介紹了一些入門知識。
The Lex & Yacc Page 中有很多有趣的歷史參考,以及 非常好的 lex 和 yacc 文檔。 

參考文檔:
http://www.ibm.com/developerworks/cn/linux/l-lexyac.html
http://blog.csdn.net/ThinkinginLinux/archive/2005/03/19/323379.aspx

/
/*-----Lex & Yacc ----www.linmu100.com ----*/
/
/*-----linux工具,Lex & Yacc,基本操作----*/
/
/*-----linux配置,UNIX,開源軟件,linux技術,makefile----*/
/
/*----------------------@xiaolin--------------------*/
/

 

posted on 2008-09-19 18:01 肥仔 閱讀(2070) 評論(0)  編輯 收藏 引用 所屬分類: LEX & YACC

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久免费高清视频| 亚洲一区二区三区在线看| 久久国产精品黑丝| 亚洲一区二区三区在线视频| 日韩亚洲欧美成人一区| 一本久道久久久| 一区二区电影免费观看| 亚洲欧美大片| 性欧美暴力猛交另类hd| 欧美伊人久久| 久久免费的精品国产v∧| 免费成人高清在线视频| 欧美激情一区二区三区不卡| 欧美日韩亚洲在线| 国产毛片精品国产一区二区三区| 国产欧美二区| 亚洲高清免费在线| 一区二区三区黄色| 久久久久久电影| 欧美国产第一页| 一区二区三区欧美视频| 久久国产日韩| 欧美日韩国产专区| 国产综合自拍| 一本久道久久综合中文字幕 | 亚洲国产精彩中文乱码av在线播放| 最新69国产成人精品视频免费| 一区二区三区.www| 久久久久国产精品www| 日韩一级在线| 久久综合九色综合网站| 国产精品日韩在线| 日韩午夜在线视频| 麻豆精品精华液| 亚洲在线国产日韩欧美| 欧美暴力喷水在线| 国产手机视频精品| 一本色道久久综合一区 | 亚洲大胆av| 欧美一区二区三区精品电影| 亚洲国产精品免费| 亚洲午夜精品一区二区| 欧美在线关看| 欧美日韩国产天堂| 在线看日韩av| 午夜精品一区二区在线观看 | 亚洲欧洲一区二区三区| 久久精品国产综合| 亚洲尤物视频网| 欧美日本国产在线| 亚洲国产美女久久久久| 久久久久一区| 亚洲免费一在线| 国产精品www.| 亚洲一区二区三区中文字幕 | 欧美黄色网络| 久久久人成影片一区二区三区 | 最新成人av在线| 免费观看成人网| 久久久久久国产精品一区| 国产精品综合| 欧美专区福利在线| 亚洲欧美自拍偷拍| 国产精品久久久久久户外露出| 一区二区三区四区五区精品| 91久久久亚洲精品| 欧美激情一区二区三区全黄| 亚洲人体大胆视频| 亚洲国内高清视频| 欧美日韩爆操| 亚洲尤物在线| 亚洲欧美综合另类中字| 国产午夜精品视频| 久久综合狠狠综合久久综合88| 久久精品2019中文字幕| 伊人夜夜躁av伊人久久| 免费亚洲电影在线| 欧美高潮视频| 一区二区三区免费在线观看| 亚洲图片在区色| 国产亚洲午夜高清国产拍精品| 久久久久国产精品麻豆ai换脸| 久久久国产成人精品| 亚洲精品看片| 亚洲新中文字幕| 激情成人综合网| 亚洲精品国产精品国自产在线 | 亚洲午夜高清视频| 亚洲视频一二| 国内自拍亚洲| 亚洲精品日产精品乱码不卡| 国产精品婷婷| 久久亚洲午夜电影| 99re这里只有精品6| 999亚洲国产精| 国产精品视频网| 另类人畜视频在线| 欧美三级视频在线观看| 欧美一区影院| 欧美福利一区| 久久蜜桃资源一区二区老牛 | 夜夜嗨一区二区三区| 亚洲直播在线一区| 亚洲精品麻豆| 亚洲主播在线播放| 亚洲精品乱码久久久久久久久 | 麻豆9191精品国产| 欧美日精品一区视频| 免费成人高清视频| 国产精品美女www爽爽爽视频| 久久影音先锋| 国产精品h在线观看| 欧美激情片在线观看| 国产精品综合久久久| 亚洲欧洲日韩在线| 亚洲第一主播视频| 欧美一级午夜免费电影| 亚洲午夜视频在线| 欧美69视频| 久久久亚洲一区| 国产精品视频观看| 一区二区福利| 一区二区三区黄色| 免费欧美在线视频| 久久久综合免费视频| 国产农村妇女精品| 亚洲性图久久| 亚洲男人第一av网站| 欧美日韩精品综合在线| 欧美激情一区二区三区在线| 黑人巨大精品欧美一区二区小视频| 中文av字幕一区| 中文日韩电影网站| 欧美日韩一区二| 9国产精品视频| 亚洲神马久久| 国产精品高潮呻吟久久av黑人| 亚洲精品影视| 亚洲一区免费| 国产伦精品一区二区三| 亚洲综合色激情五月| 欧美专区福利在线| 国内精品久久久久影院薰衣草| 欧美专区在线观看| 久久综合九色欧美综合狠狠| 精品成人一区二区| 免费在线成人av| 亚洲国产精品va在线看黑人动漫| 亚洲精品免费在线播放| 欧美日韩国产不卡在线看| 亚洲精品一区二区三| 一区二区三区 在线观看视频| 欧美日韩视频第一区| 亚洲图片在线| 亚洲综合色噜噜狠狠| 亚洲伦理久久| 91久久黄色| 亚洲专区一区二区三区| 欧美激情久久久久| 一区二区三区 在线观看视频| 亚洲一区二区免费在线| 国产精品午夜久久| 香蕉久久一区二区不卡无毒影院 | 欧美主播一区二区三区美女 久久精品人 | 久久国产精品色婷婷| 欧美国产综合视频| 9色porny自拍视频一区二区| 欧美色精品在线视频| 午夜激情综合网| 免费成人av在线| 一区二区三区欧美激情| 国产美女高潮久久白浆| 毛片一区二区| 亚洲欧美卡通另类91av| 女女同性女同一区二区三区91| 一本久久综合亚洲鲁鲁| 国产欧亚日韩视频| 欧美成人日韩| 欧美在线首页| 亚洲美女黄色片| 久久伊人精品天天| 亚洲深夜福利| 亚洲国产一区视频| 国产美女精品免费电影| 欧美精品日韩综合在线| 欧美一区二区成人6969| 在线精品视频在线观看高清| 欧美肥婆在线| 欧美一区二区三区日韩视频| 亚洲第一综合天堂另类专| 亚洲一区视频| 亚洲国产成人午夜在线一区| 国产精品国产三级国产普通话三级 | 久久国产精品一区二区| 一区二区国产精品| 久久青草欧美一区二区三区| 亚洲激情偷拍| 国产精品美女久久久| 美女日韩在线中文字幕| 亚洲伊人伊色伊影伊综合网|