[转载]Yacc基础
原文:https://www.ibm.com/developerworks/cn/linux/sdk/lex/index.html,摘錄部分內(nèi)容。
Yacc 代表 Yet Another Compiler Compiler。 Yacc 的 GNU 版叫做 Bison。它是一種工具,將任何一種編程語言的所有語法翻譯成針對(duì)此種語言的 Yacc 語 法解析器。它用巴科斯范式(BNF, Backus Naur Form)來書寫。按照慣例,Yacc 文件有 .y 后綴。
2. Yacc與Flex的配合
到目前為止我們已經(jīng)分別討論了 Lex 和 Yacc。現(xiàn)在讓我們來看一下他們是怎樣結(jié)合使用的。
一個(gè)程序通常在每次返回一個(gè)標(biāo)記時(shí)都要調(diào)用?yylex()?函數(shù)。只有在文件結(jié)束或者出現(xiàn)錯(cuò)誤標(biāo)記時(shí)才會(huì)終止。
一個(gè)由 Yacc 生成的解析器調(diào)用?yylex()?函數(shù)來獲得標(biāo)記。?yylex()?可以由 Lex 來生成或完全由自己來編寫。 對(duì)于由 Lex 生成的 lexer 來說,要和 Yacc 結(jié)合使用,每當(dāng) Lex 中匹配一個(gè)模式時(shí)都必須返回一個(gè)標(biāo)記。 因此 Lex 中匹配模式時(shí)的動(dòng)作一般格式為:
| 1 2 | {pattern} { /* do smthg*/ ?return TOKEN_NAME; } |
于是 Yacc 就會(huì)獲得返回的標(biāo)記。當(dāng) Yacc 編譯一個(gè)帶有 _d 標(biāo)記的?.y文件時(shí),會(huì)生成一個(gè)頭文件,它對(duì)每個(gè)標(biāo)記都有?#define的定義。 如果 Lex 和 Yacc 一起使用的話,頭文件必須在相應(yīng)的 Lex 文件?.lex中的 C 聲明段中包括。
讓我們回到名字和年齡的文件解析例子中,看一看 Lex 和 Yacc 文件的代碼。
Name.y - 語法文件
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | % ?typedef char* string; ?#define YYSTYPE string ?%} ?%token NAME EQ AGE ?%% ?file : record file ?| record ?; ?record : NAME EQ AGE { ?printf("%s is %s years old!!!\n", $1, $3); } ?; ?%% ?int main() ?{ ?yyparse(); ?return 0; ?} ?int yyerror(char *msg) ?{ ?printf("Error ?encountered: %s \n", msg); ?} |
Name.lex - Lex 的解析器文件
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | %{ ?#include "y.tab.h" ?? ?#include <stdio.h> ?#include <string.h> ?extern char* yylval; ?%} ?char [A-Za-z] ?num [0-9] ?eq [=] ?name {char}+ ?age {num}+ ?%% ?{name} { yylval = strdup(yytext); ?return NAME; } ?{eq} { return EQ; } ?{age} { yylval = strdup(yytext); ?return AGE; } ?%% ?int yywrap() ?{ ?return 1; ?} |
作為一個(gè)參考,我們列出了?y.tab.h, Yacc 生成的頭文件。
y.tab.h - Yacc 生成的頭文件
| 1 2 3 | # define NAME 257 ?# define EQ 258 ?# define AGE 259 |
轉(zhuǎn)載于:https://www.cnblogs.com/jiading/p/10793732.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的[转载]Yacc基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTTP请求与接收get/post方式
- 下一篇: jquery点击页面其他位置隐藏div