- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 flex 和 bison 实现计算器,但是 double 值被解释为整数,然后我在互联网上寻找答案,我意识到错误可能是 bison 将数字解释为整数,所以如果我输入“1.2 "在 *yylval = atof(yytext) 中是 1 而不是 1.2。所以我尝试在 parser.ypp 中添加 #define YYSTYPE double 但我遇到了编译错误。我知道有几个类似的问题,但没有一个真正帮助过我。这是我的 lex 和 ypp 文件以及我得到的编译错误。
提前致谢。
词法分析器.lex:
%option noyywrap
%option noinput
%option nounput
%{
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
#include "parser.tab.hpp"
%}
%%
[0-9]+([.][0-9]+)? {
*yylval = atof(yytext);
return NUMBER;
}
sin {
return SIN;
}
cos {
return COS;
}
tan {
return TG;
}
tg {
return TG;
}
ctan {
return CTG;
}
ctg {
return CTG;
}
asin {
return ASIN;
}
acos {
return ACOS;
}
atan {
return ATG;
}
actan {
return ACTG;
}
ln {
return LN;
}
log {
return LOG;
}
exp {
return EXP;
}
sqrt {
return SQRT;
}
abs {
return ABS;
}
mod {
return MOD;
}
[a-z] {
return VARIABLE;
}
[-+*/^()%!,] {
return *yytext;
}
[ \t\n] ;
. {
}
解析器.ypp:
%{
#define YYSTYPE double
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
bool indicator_calculating_value ;
extern int yylex();
void yyerror(double *return_value, std::string s);
%}
%parse-param { double *return_value}
%left '+' '-'
%left '*' '/' '%'
%left SIN COS TG CTG ASIN ACOS ATG ACTG LN LOG MOD
%left UMINUS
%left '^' EXP SQRT
%left ABS
%left '!'
%type <double> E
%token <double> NUMBER
%token <char> VARIABLE;
%start pocetak
%%
pocetak
: E {
*return_value = $1;
};
E
: E '+' E {
if (indicator_calculating_value) {
$$ = $1 + $3;
}
}
| E '*' E {
if (indicator_calculating_value) {
$$ = $1 * $3;
}
}
| E '-' E {
if (indicator_calculating_value) {
$$ = $1 - $3;
}
}
| E '/' E {
if(indicator_calculating_value) {
if ($3 == 0) {
yyerror(0, "divide by zero");
}
$$ = $1 / $3;
}
}
| MOD '(' E ',' E ')' {
if(indicator_calculating_value) {
if ($5 == 0) {
yyerror(0, "divide by zero");
}
$$ = static_cast<int>($3) % static_cast<int>($5);
}
}
| SIN '(' E ')' {
if(indicator_calculating_value) {
$$ = sin($3);
}
}
| COS '(' E ')' {
if(indicator_calculating_value) {
$$ = cos($3);
}
}
| TG '(' E ')' {
if(indicator_calculating_value) {
$$ = tan($3);
}
}
| CTG '(' E ')' {
if(indicator_calculating_value) {
$$ = 1 / tan($3);
}
}
| ASIN '(' E ')' {
if(indicator_calculating_value) {
$$ = asin($3);
}
}
| ACOS '(' E ')' {
if(indicator_calculating_value) {
$$ = acos($3);
}
}
| ATG '(' E ')' {
if(indicator_calculating_value) {
$$ = atan($3);
}
}
| ACTG '(' E ')' {
if(indicator_calculating_value) {
$$ = 1 / atan($3);
}
}
| LN '(' E ')' {
if(indicator_calculating_value) {
$$ = log($3);
}
}
| LOG '(' E ',' E ')' {
if(indicator_calculating_value) {
$$ = log($5) / log($3);
}
}
| EXP '(' E ')' {
if(indicator_calculating_value) {
$$ = exp($3);
}
}
| SQRT '(' E ')' {
if(indicator_calculating_value) {
$$ = sqrt($3);
}
}
| E '^' E {
if(indicator_calculating_value) {
$$ = pow($1, $3);
}
}
| '-' E %prec UMINUS {
if(indicator_calculating_value) {
$$ = -$2;
}
}
| ABS '(' E ')' {
if(indicator_calculating_value) {
$$ = fabs($3);
}
}
| E '!' {
if(indicator_calculating_value) {
$$ = 1;
for (int i = 1; i <= static_cast<int>($1); i++) {
$$ = $$ * i;
}
}
}
| '(' E ')' {
if(indicator_calculating_value) {
$$ = $2;
}
}
| NUMBER {
if(indicator_calculating_value) {
$$ = $1;
}
}
| VARIABLE {
}
;
%%
void yyerror(double *return_value, std::string s)
{
std::cout << s << std::endl;
}
int main() {
indicator_calculating_value = true;
double value = 0.0;
yyparse(&value);
std::cout << value << std::endl;
return 0;
}
错误:
make
bison -d -v parser.ypp
g++ -Wall -L/usr/local/lib -lmgl-qt5 -lmgl -lm -c -o parser.tab.o parser.tab.cpp
parser.ypp: In function ‘int yyparse(double*)’:
parser.ypp:42:34: error: expected unqualified-id before ‘double’
*return_value = $1;
^
parser.ypp:42:34: error: expected ‘)’ before ‘double’
parser.ypp:49:20: error: expected unqualified-id before ‘double’
$$ = $1 + $3;
^~~~~~
parser.ypp:49:20: error: expected ‘)’ before ‘double’
parser.ypp:55:20: error: expected unqualified-id before ‘double’
$$ = $1 * $3;
^~~~~~
parser.ypp:55:20: error: expected ‘)’ before ‘double’
parser.ypp:60:20: error: expected unqualified-id before ‘double’
$$ = $1 - $3;
^~~~~~
parser.ypp:60:20: error: expected ‘)’ before ‘double’
parser.ypp:66:27: error: expected unqualified-id before ‘double’
if ($3 == 0) {
^
parser.ypp:66:27: error: expected ‘)’ before ‘double’
parser.ypp:69:20: error: expected unqualified-id before ‘double’
$$ = $1 / $3;
^~~~~~
parser.ypp:69:41: error: expected unqualified-id before ‘double’
$$ = $1 / $3;
^
parser.ypp:69:41: error: expected ‘)’ before ‘double’
parser.ypp:69:68: error: expected ‘)’ before ‘;’ token
$$ = $1 / $3;
^
parser.ypp:74:28: error: expected unqualified-id before ‘double’
if ($5 == 0) {
^
parser.ypp:74:28: error: expected ‘)’ before ‘double’
parser.ypp:77:20: error: expected unqualified-id before ‘double’
$$ = static_cast<int>($3) % static_cast<int>($5);
^~~~~~
parser.ypp:77:58: error: expected unqualified-id before ‘double’
$$ = static_cast<int>($3) % static_cast<int>($5);
^~~~
parser.ypp:77:58: error: expected ‘)’ before ‘double’
parser.ypp:77:105: error: expected ‘)’ before ‘;’ token
$$ = static_cast<int>($3) % static_cast<int>($5);
^
parser.ypp:77:105: error: expected ‘)’ before ‘;’ token
parser.ypp:82:20: error: expected unqualified-id before ‘double’
$$ = sin($3);
^~~~~~
parser.ypp:82:20: error: expected ‘)’ before ‘double’
parser.ypp:87:20: error: expected unqualified-id before ‘double’
$$ = cos($3);
^~~~~~
parser.ypp:87:20: error: expected ‘)’ before ‘double’
parser.ypp:92:20: error: expected unqualified-id before ‘double’
$$ = tan($3);
^~~~~~
parser.ypp:92:20: error: expected ‘)’ before ‘double’
parser.ypp:97:20: error: expected unqualified-id before ‘double’
$$ = 1 / tan($3);
^~~~~~
parser.ypp:97:20: error: expected ‘)’ before ‘double’
parser.ypp:102:20: error: expected unqualified-id before ‘double’
$$ = asin($3);
^~~~~~
parser.ypp:102:20: error: expected ‘)’ before ‘double’
parser.ypp:107:20: error: expected unqualified-id before ‘double’
$$ = acos($3);
^~~~~~
parser.ypp:107:20: error: expected ‘)’ before ‘double’
parser.ypp:112:20: error: expected unqualified-id before ‘double’
$$ = atan($3);
^~~~~~
parser.ypp:112:20: error: expected ‘)’ before ‘double’
parser.ypp:117:20: error: expected unqualified-id before ‘double’
$$ = 1 / atan($3);
^~~~~~
parser.ypp:117:20: error: expected ‘)’ before ‘double’
parser.ypp:122:20: error: expected unqualified-id before ‘double’
$$ = log($3);
^~~~~~
parser.ypp:122:20: error: expected ‘)’ before ‘double’
parser.ypp:127:20: error: expected unqualified-id before ‘double’
$$ = log($5) / log($3);
^~~~~~
parser.ypp:127:20: error: expected ‘)’ before ‘double’
parser.ypp:132:20: error: expected unqualified-id before ‘double’
$$ = exp($3);
^~~~~~
parser.ypp:132:20: error: expected ‘)’ before ‘double’
parser.ypp:137:20: error: expected unqualified-id before ‘double’
$$ = sqrt($3);
^~~~~~
parser.ypp:137:20: error: expected ‘)’ before ‘double’
parser.ypp:142:20: error: expected unqualified-id before ‘double’
$$ = pow($1, $3);
^~~~~~
parser.ypp:142:20: error: expected ‘)’ before ‘double’
parser.ypp:147:20: error: expected unqualified-id before ‘double’
$$ = -$2;
^~
parser.ypp:147:20: error: expected ‘)’ before ‘double’
parser.ypp:152:20: error: expected unqualified-id before ‘double’
$$ = fabs($3);
^~~~~~
parser.ypp:152:20: error: expected ‘)’ before ‘double’
parser.ypp:157:20: error: expected unqualified-id before ‘double’
$$ = 1;
^
parser.ypp:157:20: error: expected ‘)’ before ‘double’
parser.ypp:158:62: error: expected unqualified-id before ‘double’
for (int i = 1; i <= static_cast<int>($1); i++) {
^
parser.ypp:158:62: error: expected ‘)’ before ‘double’
parser.ypp:158:70: error: expected ‘)’ before ‘;’ token
for (int i = 1; i <= static_cast<int>($1); i++) {
^
parser.ypp:159:24: error: expected unqualified-id before ‘double’
$$ = $$ * i;
^~~~~
parser.ypp:159:24: error: expected ‘)’ before ‘double’
parser.ypp:165:20: error: expected unqualified-id before ‘double’
$$ = $2;
^
parser.ypp:165:20: error: expected ‘)’ before ‘double’
parser.ypp:170:20: error: expected unqualified-id before ‘double’
$$ = $1;
^
parser.ypp:170:20: error: expected ‘)’ before ‘double’
Makefile:15: recipe for target 'parser.tab.o' failed
make: *** [parser.tab.o] Error 1
最佳答案
您的 bison 文件定义了两种不同类型的符号:
%type <double> E
%token <double> NUMBER
%token <char> VARIABLE;
(第三行末尾的分号不正确,虽然我认为 Bison 会忽略它。)
正如在 bison manual 中讨论的那样,最常见的实现方式是使用 %union
Bison 声明,它将声明 YYSTYPE
成为C联盟。这与将预处理器用于 #define YYSTYPE
不兼容。作为单一类型。
如果您使用 %union
声明,您为 YYSTYPE
的每个变体指定一个 C 类型和一个标记.然后放在尖括号之间的是标签,而不是类型。例如,
%union {
double number;
char id;
}
%token <number> NUMBER
通过该声明, Bison 将声明一个 union
键入两个名为 number
的成员和 id
.它会自动生成 $n
通过附加成员选择器来引用正确的成员(如果符号 $n
指的是已知类型)。换句话说,如果 $1
指的是 NUMBER
, bison 将在生成的代码中将其替换为类似 stack[top - 2 + 1].number
的内容. (如果没有 %union
和类型声明,替换将类似于 stack[top - 2 + 1]
。)
Bison 不要求您使用 %union
.如果你不这样做并且你仍然为你的 token 和非终端声明类型, Bison 会假设你知道你在做什么并且你已经以某种方式声明了YYSTYPE
。作为复合类型。它将执行完全相同的替换,将成员选择器添加到对具有已知类型的堆栈值的引用。
所以在你的例子中,你已经声明了 %type <double> E
, 所以 bison 将替换一个 $1
在一个 Action 中 $1
指代符号 E
用类似 stack[top - 4 + 1].double
的东西.
当然,那会导致编译器卡住。 double
是保留字,不能作为复合成员名,反正YYSTYPE
是一个标量(double
),因为这是您定义它的方式。
您还没有尝试编译您的扫描仪,但您会在那里遇到类似的问题。显然,YYSTYPE
扫描器和解析器中的类型必须相同,它们是独立的 C 翻译单元。如果您使用了 %union
声明, Bison 会把 C union
进入 tje 生成的 header ,你 #include
在生成的扫描仪中。这保证了一致性。如果你不使用 %union
, 那么您必须确保扫描仪具有正确的定义。
因为您没有在 flex 文件中做任何事情来声明 YYSTYPE
,生成的代码将回退到 int
.它通过包含这样的 block 来做到这一点:
#ifndef YYSTYPE
#define YYSTYPE int
#endif
bison 手册包含许多简单示例。选项比我在这里介绍的要多得多,建议您花点时间阅读手册。
关于c++ - bison/flex : calculator interprets double values as integers so I added #define YYSTYPE double, 但我有多个编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59518552/
我知道 Magical Record 支持聚合操作,例如 sum:、max: 但是有没有办法进行一些简单的计算,例如: 总和:属性 * other_attributes 如果我们知道这些属性的值为 N
我有一个项目可以计算一些关于用户表现的“统计数据”,然后将其展示给他们。所有这些统计数据最终都来自一个记录用户与网站交互的大型“交互”表。目前,所有这些统计数据都是通过查看这些数据来计算的。我们广泛使
我正在试着用熊猫和NumPy来计算蟒蛇中的Connors RSI。我想用ConnorsRSI的默认值(3,2,100)来计算它。。Connors RSI的公式为:[RSI(Close,3)+RSI(S
我对某种 mean() 计算有疑问。我使用带有两个标识符“ID”和“year”的面板数据集(使用 plm pkg) 我想计算变量“y”的分组平均值,但省略了第一年的计算条目,然后仅填写用于计算它的年份
我不知道这是否是微不足道的或实际上很棘手:是否可以捕获 VBA 中的“计算工作表 (shift+f9)”和“计算工作簿”事件? 我想隐藏一些操作几千行的进程,只显示一些关键值。我正在计算分布,数千行,
我和#1895500有同样的问题, 但使用 PostgreSQL 而不是 MySQL。 如何定义具有计算字段的 View ,例如: (mytable.col1 * 2) AS times_two .
如何定义具有两个计算字段的 View ,例如... ('TableName'.'BlueSquares' + 'TableName'.'RedSquares') AS TotalSquares, (
CALCULATE(m, x=red) 和 CALCULATE(m, KEEPFILTERS(x=red)) 之间有什么区别 显然它们不一样。我找到了文档和解释,但我仍然不明白。 https://le
我正在尝试从命令提示符运行我的 Java 类文件,当我尝试这样做时,我收到此错误 C:\Users\New User\workspace\myproject\bin\apackage>java cal
我正在尝试根据用户的输入显示文本。例如输入单词 APPLE 应该让它显示 BANANA。 这段代码工作正常: :Input X :If X=APPLE :Disp "BANANA" 但我不确定如何以此
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
我们正在尝试实现自己的自定义购物篮计算规则集并注册新的结果 View 来获取购物篮计算结果,但我们无法找到一些如何注册新结果 View 类的信息? 我们使用这里的示例:https://support.
数字变量是否遵循 TI 计算器上的记录标准? 我真的很惊讶地注意到我的 TI 83 Premium CE 测试实际上返回了 true(即 1): 0.1 -> X 0.1 -> Y 0.01 -> Z
大约两天前,我收到了我的 TI-82 STATS 可编程计算器(实际上更像是一个 TI-83) - 并想用内置的 TI-BASIC 语言编写一个贪吃蛇游戏。 虽然我不得不找出:TI-BASIC 是 极
作为家庭作业,我们有一个基本的计算器,它只能进行+运算,我们必须实现更多的功能。我们必须实现括号运算符、符号运算符和最小最大函数。最后的任务之一是扩展最小/最大函数以计算具有两个以上参数的最小/最大,
如何从 Excel 的单元格中选择一列,然后仅计算该列?我只知道 SHIFT + F9 可以计算整个工作表,F9 可以计算整个工作簿。 谢谢你们;) 最佳答案 我认为仅使用标准 Excel 无法做到这
我已经为计算器编写了代码,但它还不能 100% 可靠地工作。每次我进行计算时,例如:“1+1=2”,并且我想要进行另一次计算,我必须关闭小程序并重新启动它。我怎样才能让它回到开始的地方。 这是代码:
意图:该程序要求用户提供其银行帐户中当前的金额、年利率和年数。输出是金额的开始和结束,显示用户指定年份的累计利息。 问题:我正在尝试找到一种正确添加利息的方法,截至目前,在指定的年份里,我所做的就是乘
我怎么让第一次点击不接受操作返回“0” 这是我的功能 $(document).ready(function(){ $('button').on('click', function(){
题目地址:https://leetcode.com/problems/basic-calculator/description/ 题目描述 Implement a basic calculator
我是一名优秀的程序员,十分优秀!