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

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

./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] = '\0';
} 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

使用bison和yacc制作脚本语言(3)的更多相关文章

  1. 使用bison和yacc制作脚本语言(1)

    使用bison和yacc制作脚本语言(1) 环境: 环境 windows 10 Cygwin64 语言 C 工具 mingw bison flex 主要是使用bison和flex这两个软件,编译器无所 ...

  2. 使用bison和yacc制作脚本语言(2)

    我们先来想一下语法 一般脚本语言不需要定义类型直接在赋值的时候确定 我们主要考虑一下变量的类型 a = 1; b = 1.1; c = "str"; 一般来讲,我们使用这三种类型, ...

  3. 使用bison和yacc制作脚本语言(4)

    我们现在开始设计数据结构: interpreter.h #ifndef INTERPRETER #define INTERPRETER #include "../include/eval.h ...

  4. [Java面试九]脚本语言知识总结.

    核心内容概述 1.JavaScript加强,涉及到ECMAScript语法.BOM对象.DOM对象以及事件. 2.Ajax传统编程. 3.jQuery框架,九种选择器为核心学习内容 4.JQuery ...

  5. Perl,Python,Ruby,Javascript 四种脚本语言比较

    Perl 为了选择一个合适的脚本语言学习,今天查了不少有关Perl,Python,Ruby,Javascript的东西,可是发现各大阵营的人都在吹捧自己喜欢的语言,不过最没有争议的应该是Javascr ...

  6. JAVA平台上的网络爬虫脚本语言 CrawlScript

    JAVA平台上的网络爬虫脚本语言 CrawlScript 网络爬虫即自动获取网页信息的一种程序,有很多JAVA.C++的网络爬虫类库,但是在这些类库的基础上开发十分繁琐,需要大量的代码才可以完成一 个 ...

  7. Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言

    Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言 现在我们使用的操作系统(Windows.Mac OS.Android.iOS 等)都是带图形界面的,简单直观,容易上 ...

  8. PCB 规则引擎之脚本语言JavaScript应用评测

    世界上没有好做的软件,觉得好做,只是你的系统简单而已,而不是哪个行业简单,特别像我们PCB制造企业务逻辑的很复杂的,仅仅靠决策树中的每个节点布置决策逻辑是不能满足要求的,所以我们在制作PCB规则引擎必 ...

  9. Procomm Plus 与ASPECT脚本语言在基于远程终端设备上的测试应用

    产测 ---------------------------------------------------- 原文:http://www.bixuanzl.com/20180801/1084478. ...

随机推荐

  1. java IO流 总结

    [-] 1什么是IO 2数据流的基本概念 1 数据流 2 输入流Input  Stream 3 输出流 数据流分类 3 标准IO 命令行参数 标准输入输出数据流 4javaIO层次体系结构 5 非流式 ...

  2. SAP成都研究院2018年总共87篇技术文章合集

    2018年很快就要结束了.Jerry在2017年年底准备开始写这个公众号时,给自己定的目标是:2018年至少保证每周发布一篇高质量的文章.如今2018年就快过去了,高质量与否需要大家来反馈,至少从量上 ...

  3. hdu-2685 I won't tell you this is about number theory---gcd和快速幂的性质

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2685 题目大意: 求gcd(am-1,an-1)%k 解题思路: 对于am-1 = (a - 1) ...

  4. Django CreateView 简单使用

    django.views.generic中的CreateView类,是基于View的子类.CreateView可以简单快速的创建表对象. 下面记录小作代码. # polls/views.py from ...

  5. 体验了Sublime + Emmet,才体会到原来前端开发可以这么痛快!

    从当初用notepad写出第一个web页面,到现在偶尔使用Editplus做一些HTML5的消遣,不知不觉已经15年了  --! 在这中间,和那些老顽固一样,坚决远离FP.DW那些半自动的前端开发工具 ...

  6. [USACO19JAN]Exercise Route

    题目 这题的数据有点水,暴力合并\(set\)好像过了 分析一下这个题的性质,发现我们一条非树边就会形成一个环,而我们要求选择两个非树边,就会形成两个环,要求不走重复的点,就是说我们需要走一个大环,且 ...

  7. SPOJ SUBXOR

    SPOJ SUBXOR 题意 给定一个由正整数构成的数组, 求 异或和小于k 的子序列的个数. 题解 假设答案区间为 [L, R], XOR[L, R] 等价于 XOR[1, L - 1] ^ XOR ...

  8. 《Inetnet History,Technology and Security》学习笔记

    前言 本文为观看Cousera的Michigan<Internet History, Technology and Security>教程的个人学习笔记,包括了每个week的概要和个人感想 ...

  9. AutoLayout对 scrollview的contentSize 和contentOffset属性的影响

      AutoLayout对 scrollview的contentSize 和contentOffset属性的影响 问题一.iOS开发中,如果在XIB文件中创建一个scrollview,同时给它设置布局 ...

  10. Mongoose 对象的特殊性

    一.偶遇难题 在最近使用Mongoose的时候,遇到这样一个问题: 我从DB中查询出来一个对象,比如是Book,这个对象我想在返回时,给他附加一个字段,比如是字段A,正常来说,JS你只需要Book.A ...