使用bison和yacc制作脚本语言(3)
我们现在已经可以写好文法了,下一步我们打算开始正式创建工程了
在工程目录下,我们创建如下文件夹
./include
./memory
./ms
include文件夹下我们将放头文件
memory是内存管理模块,检测内存泄漏
ms文件夹主要是放源文件
memory内存管理模块可以参考我另一个随笔 https://www.cnblogs.com/stdpain/p/10484403.html ,不愿意了解的话直接把里面的函数当做malloc,free即可
我们先创建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)的更多相关文章
- 使用bison和yacc制作脚本语言(1)
使用bison和yacc制作脚本语言(1) 环境: 环境 windows 10 Cygwin64 语言 C 工具 mingw bison flex 主要是使用bison和flex这两个软件,编译器无所 ...
- 使用bison和yacc制作脚本语言(2)
我们先来想一下语法 一般脚本语言不需要定义类型直接在赋值的时候确定 我们主要考虑一下变量的类型 a = 1; b = 1.1; c = "str"; 一般来讲,我们使用这三种类型, ...
- 使用bison和yacc制作脚本语言(4)
我们现在开始设计数据结构: interpreter.h #ifndef INTERPRETER #define INTERPRETER #include "../include/eval.h ...
- [Java面试九]脚本语言知识总结.
核心内容概述 1.JavaScript加强,涉及到ECMAScript语法.BOM对象.DOM对象以及事件. 2.Ajax传统编程. 3.jQuery框架,九种选择器为核心学习内容 4.JQuery ...
- Perl,Python,Ruby,Javascript 四种脚本语言比较
Perl 为了选择一个合适的脚本语言学习,今天查了不少有关Perl,Python,Ruby,Javascript的东西,可是发现各大阵营的人都在吹捧自己喜欢的语言,不过最没有争议的应该是Javascr ...
- JAVA平台上的网络爬虫脚本语言 CrawlScript
JAVA平台上的网络爬虫脚本语言 CrawlScript 网络爬虫即自动获取网页信息的一种程序,有很多JAVA.C++的网络爬虫类库,但是在这些类库的基础上开发十分繁琐,需要大量的代码才可以完成一 个 ...
- Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言
Shell简介:1分钟理解什么是Shell 脚本语言 解释器 以及编译器和编译语言 现在我们使用的操作系统(Windows.Mac OS.Android.iOS 等)都是带图形界面的,简单直观,容易上 ...
- PCB 规则引擎之脚本语言JavaScript应用评测
世界上没有好做的软件,觉得好做,只是你的系统简单而已,而不是哪个行业简单,特别像我们PCB制造企业务逻辑的很复杂的,仅仅靠决策树中的每个节点布置决策逻辑是不能满足要求的,所以我们在制作PCB规则引擎必 ...
- Procomm Plus 与ASPECT脚本语言在基于远程终端设备上的测试应用
产测 ---------------------------------------------------- 原文:http://www.bixuanzl.com/20180801/1084478. ...
随机推荐
- myEclipse mybatis自动生成工具xml配置
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE generatorConfiguration ...
- U盘中毒了?教你如何删除System Volume Information这个顽固文件夹
不得不说cmd命令很好用呢.最近我的U盘中毒了,格式化都删除不了System Volume Information这个顽固的文件夹,真心伤不起哇!还好现在解决了问题.看来以后得好好对待U盘,不能乱用了 ...
- 监控DAG状态
Add-PSSnapin microsoft.exchange* Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 $server ...
- js 获取 网页屏幕高度 窗口高度 元素高度 滚动高度
常用: JS 获取浏览器窗口大小 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 获取窗口宽度 if (window.innerWidth) winWidth = ...
- 023re模块(正则)
之前我刚学的python知识点,没有题目进行熟悉,后面的知识点会有练习题,并且慢慢补充.看到很多都是很简单的练习,碰到复杂.需要运用的再补充吧#字符串中使用到正则表达式 s='hello world' ...
- Codeforces Round #433 (Div. 2)【A、B、C、D题】
题目链接:Codeforces Round #433 (Div. 2) codeforces 854 A. Fraction[水] 题意:已知分子与分母的和,求分子小于分母的 最大的最简分数. #in ...
- getResource和getResourceAsStream
1. 前言 在Java中获取资源的时候,经常用到getResource和getResourceAsStream,本文总结一下这两种获取资源文件的路径差异. 2.Class.getResource(St ...
- 使用 JDK XML 和 java对象相互转换
Unmarshaller 类能将 XML 数据转换为 Java 内容对象. Marshaller 类能够将 Java 对象转换回 XML 数据. package jaxb; /** * Created ...
- ListView实现下拉刷新(二)隐藏头布局
一.问题分析 在上一篇中,我们将头布局加到了ListView上.但是没有隐藏他.你可能会想,隐藏还不简单,直接给它设置为GONE属性不就可以了吗,在需要的时候再设定为可见.没错,这正是ListView ...
- UVa 12034 - Race(递推 + 杨辉三角)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...