我是靠谱客的博主 快乐小蚂蚁,最近开发中收集的这篇文章主要介绍使用bison和yacc制作脚本语言(3),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我们现在已经可以写好文法了,下一步我们打算开始正式创建工程了

在工程目录下,我们创建如下文件夹

./include
./memory
./ms

include文件夹下我们将放头文件

memory是内存管理模块,检测内存泄漏

ms文件夹主要是放源文件

memory内存管理模块可以参考我另一个随笔 https://www.cnblogs.com/stdpain/p/10484403.html ,不愿意了解的话直接把里面的函数当做mallocfree即可

我们先创建lex文件ms.l这个是flex使用的文件,下面是部分代码:

%{
#include <stdio.h>
#include <string.h>
#include "../include/create.h"
#include "y.tab.h"
/* 一个功能性函数-都要加 */
int
yywrap(void)
{
return 1;
}
%}
%start COMMENT STRING_LITERAL_STATE
%%
<INITIAL>"function"
return FUNCTION;
<INITIAL>[A-Za-z_][A-Za-z_0-9]* {
yylval.identifier = Interpreter_str_malloc(yytext);
return IDENTIFIER;
}

%{ 中的内容会被原封不动的输出到文件中,%%之后是正则表达式匹配然后返回某个token(终结符),将会被bison识别,<...>前缀代表状态的意思,因为正则表达式有时候有一定的局限性(贪心匹配)

{}中的内容可以使用我们定义好的函数,当成功匹配的时候会执行里面的函数,return 也是返回某个token,yylval是yacc内置的对象,我们可以让yylval保存一些变量

我们接着编写其他的正则表达式

<INITIAL>([1-9][0-9]*)|"0" {
int temp;
sscanf(yytext, "%d", &temp);
yylval.integer = temp;
return INT_LITERAL;
}
<INITIAL>[0-9]+.[0-9]+ {
double temp;
sscanf(yytext, "%lf", &temp);
yylval.db = temp;
return DOUBLE_LITERAL;
}

以上两个分别是整数和浮点数的正则表达式,通过scanf读取然后保存到yylval中

<INITIAL>" {
open_charbuffer();
BEGIN STRING_LITERAL_STATE;
}

当遇见"的时候说明遇到了字符串,这个时候很多规则都会变动,我们可以让他转换到另一个状态 BEGIN 后面就是状态的名字, open_charbuffer()是我们写的函数用于打开一个缓冲区存放字符串

<STRING_LITERAL_STATE>"
{
yylval.identifier = flush_charbuffer();
BEGIN INITIAL;
return STRING_LITERAL;
}
<STRING_LITERAL_STATE>n
{
addc_charbuffer('n');
}
<STRING_LITERAL_STATE>\"
addc_charbuffer('"');
<STRING_LITERAL_STATE>\n
addc_charbuffer('n');
<STRING_LITERAL_STATE>\t
addc_charbuffer('t');
<STRING_LITERAL_STATE>\\
addc_charbuffer('\');
<STRING_LITERAL_STATE>.
addc_charbuffer(yytext[0]);

在字符串模式下,我们可以在遇到各种字符的时候可以添加到缓冲区,注意特殊字符需要转义,再次遇到"的时候把缓冲区刷新然后保存这个字符串到yylval中并且转移到初始模式

<INITIAL>.
{
//error
char buf[1024];
if (isprint(yytext[0])) {
buf[0] = yytext[0];
buf[1] = '';
} else {
sprintf(buf, "0x%02x", (unsigned char)yytext[0]);
}
printf("meet:%s",buf);
abort();
}

遇到期望之外的字符直接错误处理即可,

这几个字符串缓冲区函数我们先简单实现一下即可,有较长字符串需求的时候再重新写

void open_charbuffer()
{
buffer = Interpreter_malloc(100);
pos = 0;
}
void addc_charbuffer(char c)
{
assert(buffer);
assert(pos < 100);
buffer[pos++] = c;
}
char *flush_charbuffer()
{
char *p = buffer;
buffer[pos] = 0;
buffer = NULL;
return p;
}

代码已经上传至github地址:https://github.com/stdpain/compiler-interpreter

其中ms.l在ms/ms.l

转载于:https://www.cnblogs.com/stdpain/p/10528826.html

最后

以上就是快乐小蚂蚁为你收集整理的使用bison和yacc制作脚本语言(3)的全部内容,希望文章能够帮你解决使用bison和yacc制作脚本语言(3)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部