验证Yacc的使用
输入为一个布尔表达式,以换行结束。输出为这个布尔表达式的真值(true或false)。
尝试二义文法和非二义文法两种不同的实现方式。布尔表达式二义文法为:S –>S or S | S and S | not S | (S) | true | false,其中优先级or < and < not,or 和 and 左结合,not 右结合。
非二义文法请参照表达式非二义文法自己写出来。
在cygwin下用flex,bison和gcc工具将例子调试通过,并写出测试例测试正确性。
参考:calculator0-3这四个例子。
%{
#include "cal.tab.h"
int yywrap(void)
{
return 1;
}
%}
delim [ \t ]
ws {delim}+
<strong>tr true
fa false</strong>
%%
<strong>{fa} {return F;}
{tr} {return T;}
"||" {return AND;}
"&&" {return OR;}
"!" {return NOT;}
"(" {return LPAREN;}
")" {return RPAREN;}</strong>
{ws} {;}
"\n" {return ENTER;}
. {printf("\nLEX:ERROR! c=%s\n", yytext);}
Cal.y:
%{
int yylex();
#define YYSTYPE double /* 将Yacc栈定义为double类型 */
%}
<strong>%token T F LPAREN RPAREN ENTER
%left OR AND
%right NOT</strong>
%%
/* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析exprg*/
prog : prog exprp
| exprp
;
exprp : expr ENTER { if($1) printf("The value of the expr is true\n");else printf("The value of the expr is false\n");}
;
<strong>expr : expr OR expr {$$ = $1 || $3;}
| expr AND expr {$$ = $1 && $3;}
| NOT expr %prec NOT{$$ = ! $2;}
| LPAREN expr RPAREN {$$ = $2;}
| T {$$ = 1;}
| F {$$ = 0;}
;</strong>
%%
int main(){
yyparse();
return 0;
}
Makefile:
cal3: cal.tab.o lex.yy.o
gcc -o cal3 cal.tab.o lex.yy.o -ly
lex.yy.o: lex.yy.c cal.tab.h
gcc -c lex.yy.c
cal.tab.o: cal.tab.c
gcc -c cal.tab.c
lex.yy.c: cal.l
flex cal.l
cal.tab.c: cal.y
bison -dv cal.y
cal.tab.h: cal.y
echo "cal.tab.h was created at the same time as cal.tab.c."
clean:
rm -f cal3.exe lex.yy.o cal.tab.o lex.yy.c cal.tab.c cal.tab.h cal3.exe.stackdump cal.output
<span style="font-weight: bold;"> </span>true||true
The value of the expr is true.
true&&false
The value of the expr is false.
!false&&(false||true)
The value of the expr is true.<strong>
</strong>
输入一个布尔表达式,以换行结束。输出了这个布尔表达式的真值(true或false)。
%{
#include "cal.tab.h"
int yywrap(void){
return 1;
}
%}
delim [ \t ]
ws {delim}+
tr true
fa false
%%
{fa} {return F;}
{tr} {return T;}
"||" {return AND;}
"&&" {return OR;}
"!" {return NOT;}
"(" {return LPAREN;}
")" {return RPAREN;}
{ws} {;}
"\n" {return ENTER;}
. {printf("\nLEX:ERROR! c=%s\n", yytext);}
cal.y:
%{
int yylex();
#define YYSTYPE double /* 将Yacc栈定义为double类型 */
%}
%token T F LPAREN RPAREN ENTER
%left OR AND
%right NOT
%%
/* 这样写prog可以让分析器每次读入一行进行分析,下一行重新分析expr */
prog : prog exprp
| exprp
;
exprp : expr ENTER { if($1) printf("The value of the expr is true\n");else printf("The value of the expr is false\n");}
;
expr : expr OR expr {$$ = $1 || $3;}
| expr AND expr {$$ = $1 && $3;}
| NOT expr %prec NOT{$$ = ! $2;}
| LPAREN expr RPAREN {$$ = $2;}
| T {$$ = 1;}
| F {$$ = 0;}
;
%%
int main(){
yyparse();
return 0;
}
makefile:
cal3: cal.tab.o lex.yy.o
gcc -o cal3 cal.tab.o lex.yy.o -ly
lex.yy.o: lex.yy.c cal.tab.h
gcc -c lex.yy.c
cal.tab.o: cal.tab.c
gcc -c cal.tab.c
lex.yy.c: cal.l
flex cal.l
cal.tab.c: cal.y
bison -dv cal.y
cal.tab.h: cal.y
echo "cal.tab.h was created at the same time as cal.tab.c."
clean:
rm -f cal3.exe lex.yy.o cal.tab.o lex.yy.c cal.tab.c cal.tab.h cal3.exe.stackdump cal.output
本例是一个有移进-归约冲突的例子,在calculator2的基础上做了如下修改:未定义PLUS的优先级和结合性,没有使用%prec UMINUS。
注意:
int yywrap(void)函数中void不能少,否则出warning。
makefile中 gcc *.tab.o lex.yy.o -ly ,-ly必须在最后,否则可能出现重复定义main函数等错误。
makefile中, cal2.exe: cal.tab.o lex.yy.o ,lex.yy.o必须在cal.tab.o后面,否则会先编译lex.yy.o发现找不到cal.tab.h
yacc程序中不要随便引用yytext和yyleng,容易出问题。
文章浏览阅读413次。4. 异构多核处理器的支持(Support for Heterogeneous Multi-core Processors):HarmonyOS可以支持不同的处理器,包括不同架构的CPU、GPU、芯片和物联网芯片等,这可以使得系统更加灵活和具有更强的性能。5. 面向服务的架构(Service-oriented Architecture):HarmonyOS强调面向服务的架构,可以将不同服务进行解耦,使得开发人员可以根据需求对服务进行组合和调用,提高系统的可扩展性和可维护性。_harmonyos架构
文章浏览阅读492次。平时在写vue项目的时候经常会遇到这个问题,写着写着浏览器就会突然抛出下面这个报错(这个报错无关紧要,不影响开发,一般不要管他,有强迫症的小伙伴往下看)网上找到的原因是因为sockjs-node库创建了一个低延迟、全双工的浏览器和web服务器之间通信通道,当我们在项目运行的时候会自动调用这个接口,如果没有使用,就会一直报这个错误(企业中跟后端联调之后就不会有这个报错了)解决方法:1.在项目中打开node_modules包并找到/sockjs-client/dist/sockjs.js文件2.编码器(
文章浏览阅读132次。knife4j配置文档_knife4j配置 包
文章浏览阅读779次。ThreadPoolExecutor + CountDownLatch 实际应用Java并发编程笔记之 CountDownLatch闭锁的源码分析线程池之ThreadPoolExecutor使用_threadpoolexecutor 配合 countdownlatch
文章浏览阅读2.6k次。对于在不同分辨率下对于div设置固定的宽高,显然是很不适合的,当页面的分辨率发生改变后,你所用的固定宽高的div就不会随着屏幕的变化而发生改变,今天就在不同屏幕分辨率下,如何利用百分比和js设置div的宽高。直接上代码: html代码:这里很简单:div class="fr_lr" id = "div_rh"> div class="fr_lrt" id="div_rht">_js获取不同像素下的显示高度
文章浏览阅读639次。本节主要介绍数据库涉及到的技术,包括数据库系统、SQL 语言和数据库访问技术。数据库系统数据库管理系统(Database Management System,DBMS)是位于操作系统与用户之间的一种操纵和管理数据库的软件,按照一定的数据模型科学地组织和存储数据,同时可以提供数据高效地获取和维护。DBMS的主要功能包括以下几个方面。1) 数据定义功能DBMS 提供数据定义语..._建立数据库采用的技术是什么
文章浏览阅读1.3k次,点赞16次,收藏7次。使用预训练模型提取特征超参数调优实践案例:对某语音数据集进行分类,取得了90%的准确率深度学习在计算机视觉、语音识别等领域取得了显著成果,本文旨在探讨一种新的深度学习模型CNN-BiLSTM-attention,用于实现数据分类任务。_注意力机制代码实现
文章浏览阅读1.1k次。Nacos1.4.1百度网盘下载_nacos百度网盘
文章浏览阅读750次。#include <iostream>#include <cmath>using namespace std;bool Judge(int **A, int n, int r, int t, int i, int j, double &exist_sum, int &exist_y0, int &exist_y1){ double sum = 0; int count = 0; double average; int x0, y0, x1._java邻域均值ccf
文章浏览阅读941次。1、检查添加字段数量是否正确 2、添加字段类型是否正确 3、检查是否有非空字段为空_ef添加数据超过十条添加不成功
文章浏览阅读78次。Reward Model相较于原始的SFT Model,在后面加上了一个value head,value head是一个Linear,输入维度为模型的hidden_dim,输出维度为1,输出表示模型预测每一字符获取的得分。举个例子,如果我们模型有「上,下,左,右」四个动作,分别有累计奖励「10,20,30,40」,我们做出任意动作,都会获取正向的累计奖励,因此模型也会向这个动作更新参数。首先的超参的调节,γ参数为折扣回报率,DeepSpeed-Chat中初始设置为1,可以将其调小一些来缓解。whaosoft