なぜ動かないんだ・・・・・っ

これがコードです

lexer.l

---------------------------------------------------------------------------

%{
#include <string>
%}

%option noyywrap batch debug

%%

"\"" return DQ;
"[" return LSB;
"]" return RSB;

"+" return ADD;
"-" return SUB;
"*" return MUL;
"/" return DIV;
"(" return LPAREN;
")" return RPAREN;

"=" return ASGN;
"==" return EQ;
"is" return EQ;
"!=" return NEQ;
"isnot" return NEQ;
">" return GT;
"<" return LT;
">=" return GTEQ;
"<=" return LTEQ;
"&&" return AND;
"and" return AND;
"||" return OR;
"or" return OR;
"," return COMMA;
"int" return INT;
"double" return DOUBLE;
"str" return STR;

"if" return IF;
"else" return ELSE;
"for" return FOR;
"while" return WHILE;

([1-9][0-9]*)|0|([0-9]+\.[0-9]*) {
double tmp;
sscanf(yytext, "%lf", &tmp);
yylval.num = tmp;
return NUMBER;
}

[ \t\n] ;

([a-z]|[A-Z])+ {
yylval.str = std::string(yytext);
return STRING;
}

*1("_"|([a-z]|[A-Z])|[1-9])*) {
yylval.str = std::string(yytext);
return NAME;
}

%%
 
---------------------------------------------------------------------------

parser.y

---------------------------------------------------------------------------

%{
#include <iostream>
#include <string>
#include <typeinfo>
#include <any>

#include "variable.hpp"

static void yyerror(const char* s)
{
fputs(s, stderr);
fputs("\n", stderr);
}

int yylex();

#define YYLOCATION_PRINT location_print

setVariable variables;
%}

%union {
double num;
std::string str;
}

%nterm <num> expr_ expr expr_large
%nterm <str> type

/* DATA */
%token <str> STRING
%token <num> NUMBER

/* DATA-SYMBOL */
%token DQ "\""
%token LSB "["
%token RSB "]"

/* CALC */
%token ADD "+"
%token SUB "-"
%token MUL "*"
%token DIV "/"
%token LPAREN "("
%token RPAREN ")"

/* OPERATORS */
%token ASGN "="
%token EQ "=="
%token NEQ "!="
%token GT ">"
%token LT "<"
%token GTEQ ">="
%token LTEQ "<="
%token AND "&&"
%token OR "||"
%token COMMA ","

%left "&&" "||"
%left "==" "!="
%left ">=" "<=" "<" ">"
%left "+" "-"
%left "*" "/"

/* STATEMENTS */
%token <str> NAME
%token <str> INT "int"
%token <str> DOUBLE "double"
%token <str> STR "str"
%token IF "if"
%token ELSE "else"
%token FOR "for"
%token WHILE "while"

%start program

%%

program : statements

statements : statement
| "{" statements "}"

statement : statement_large
| statement_small

statement_large : "if" "(" expr_large ")" statements[T] "else" statements[F]
{
if ($expr_large)
{
$<void>T;
}
else
{
$<void>F;
}
}
| "for" "(" expr_large[on] "," expr_large[tw] "," expr_large[th] ")" statements
{
for (int i=$on, i<$tw, i+=$th)
{
$<void>statements;
}
}
| "while" "(" expr_large ")" statements
{
while ($expr_large)
{
$<void>statements;
}
}

statement_small : NAME "<" type ">" "=" expr_large
{
if ($type == "int")
{
if (typeid($expr_large) == typeid(int))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.integer = $expr_large;
variables.addVar(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
else if ($type == "double")
{
if (typeid($expr_large) == typeid(double))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.decimal = $expr_large;
variables.addVar(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
else if ($type == "str")
{
if (typeid($expr_large) == typeid(std::string))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.str = $expr_large;
variables.addVar(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
}
| type NAME "=" expr_large
{
if ($type == "int")
{
if (typeid($expr_large) == typeid(int))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.integer = $expr_large;
variables.push(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
else if ($type == "double")
{
if (typeid($expr_large) == typeid(double))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.decimal = $expr_large;
variables.push(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
else if ($type == "str")
{
if (typeid($expr_large) == typeid(std::string))
{
variableValue tmp;
tmp.name = $NAME;
tmp.type = $type;
tmp.value.str = $expr_large;
variables.push(tmp);
}
else
{
std::cerr << @3.first_line << "." << @3.first_column << "-" << @3.last_line << "." << @3.last_column << " type error!" << std::endl;
exit(1);
}
}
}

type : INT
| DOUBLE
| STR

expr_large : expr
| expr "||" expr
{
$$ = $1 || $3;
}
| expr "&&" expr
{
$$ = $1 && $3;
}

expr : expr_
| expr_ "==" expr_
{
$$ = $1 == $3;
}
| expr_ "!=" expr_
{
$$ = $1 != $3;
}
| expr_ ">" expr_
{
$$ = $1 > $3;
}
| expr_ "<" expr_
{
$$ = $1 < $3;
}
| expr_ ">=" expr_
{
$$ = $1 >= $3;
}
| expr_ "<=" expr_
{
$$ = $1 <= $3;
}

expr_ : NUMBER
{
$$ = $1;
}
| NAME
{
std::any result;
for (variableValue element : variables.showVar();)
{
if (element.name == $1)
{
if (element.type == "int")
{
result = element.value.integer;
break;
}
else if (element.type == "double")
{
result = element.value.decimal;
break;
}
else if (element.type == "str")
{
result = element.value.str;
break;
}
$$ = result;
}
}
}
| "(" expr_ ")"
{
$$ = $2;
}
| expr_ "+" expr_
{
$$ = $1 + $3;
}
| expr_ "-" expr_
{
$$ = $1 - $3;
}
| expr_ "*" expr_
{
$$ = $1 * $3;
}
| expr_ "/" expr_
{
if ($3 == 0)
{
std::cerr << "division by zero\n";
exit(1);
}
else $$ = $1 / $3;
}

%%

#include "lex.yy.c"

int main()
{
yyparse();
}
 
---------------------------------------------------------------------------

variable.hpp

---------------------------------------------------------------------------

 
#pragma once

#include <iostream>
#include <stdexcept>
#include <string>
#include <stack>
#include <vector>


struct variableValue
{
std::string name;
std::string type;

struct value
{
std::string str;
int integer;
double decimal;
};
};

class setVariable
{
private:
std::stack<std::vector<variableValue>> varStack;
public:
void pushStack(variableValue);
void popStack();
std::vector<variableValue> showVar();
void addVar(variableValue);
};

void setVariable::pushStack(variableValue value)
{
if (varStack.size() == 0)
{
std::vector<variableValue> tmp;
tmp.push_back(value);
varStack.push(tmp);
}
else
{
std::vector<variableValue> tmp = varStack.top();
for (variableValue element : tmp)
{
if (element.name == value.name)
{
varStack.push(tmp);
return;
}
}

tmp.push_back(value);
varStack.push(tmp);
}
}

void setVariable::popStack()
{
varStack.pop();
}

std::vector<variableValue> setVariable::showVar()
{
return varStack.top();
}

void setVariable::addVar(variableValue value)
{
std::vector<variableValue> tmp = varStack.top();
tmp.push_back(value);
varStack.pop();
varStack.push(tmp);
}

補足

上から順に、lexer.l、parser.y、variable.hppです。

考察

parser.tab.c:995:9: error: use of deleted function ‘YYSTYPE::YYSTYPE()’
  995 | YYSTYPE yylval;
      |         ^~~~~~
In file included from parser.tab.c:114:
parser.tab.h:92:7: note: ‘YYSTYPE::YYSTYPE()’ is implicitly deleted because the default definition would be ill-formed:
   92 | union YYSTYPE
      |       ^~~~~~~
In file included from parser.tab.c:114:
parser.y:24:17: error: union member ‘YYSTYPE::str’ with non-trivial ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
   24 |     std::string str;
      |                 ^~~
parser.tab.c: In function ‘int yyparse()’:
parser.tab.c:1031:30: error: use of deleted function ‘YYSTYPE::YYSTYPE()’
 1031 |     YYSTYPE yyvsa[YYINITDEPTH];
      |                              ^
parser.tab.c:1031:30: error: use of deleted function ‘YYSTYPE::~YYSTYPE()’
In file included from parser.tab.c:114:
parser.tab.h:92:7: note: ‘YYSTYPE::~YYSTYPE()’ is implicitly deleted because the default definition would be ill-formed:
   92 | union YYSTYPE
      |       ^~~~~~~
In file included from parser.tab.c:114:
parser.y:24:17: error: union member ‘YYSTYPE::str’ with non-trivial ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::~basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
   24 |     std::string str;
      |                 ^~~
parser.tab.c:1031:30: error: use of deleted function ‘YYSTYPE::~YYSTYPE()’
 1031 |     YYSTYPE yyvsa[YYINITDEPTH];
      |                              ^
parser.tab.c:1047:11: error: use of deleted function ‘YYSTYPE::YYSTYPE()’
 1047 |   YYSTYPE yyval;
      |           ^~~~~
parser.tab.c:1047:11: error: use of deleted function ‘YYSTYPE::~YYSTYPE()’
parser.tab.c:1231:14: error: use of deleted function ‘YYSTYPE& YYSTYPE::operator=(const YYSTYPE&)’
 1231 |   *++yyvsp = yylval;
      |              ^~~~~~
In file included from parser.tab.c:114:
parser.tab.h:92:7: note: ‘YYSTYPE& YYSTYPE::operator=(const YYSTYPE&)’ is implicitly deleted because the default definition would be ill-formed:
   92 | union YYSTYPE
      |       ^~~~~~~
In file included from parser.tab.c:114:
parser.y:24:17: error: union member ‘YYSTYPE::str’ with non-trivial ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’
   24 |     std::string str;
      |                 ^~~
parser.tab.c:1265:24: error: use of deleted function ‘YYSTYPE& YYSTYPE::operator=(const YYSTYPE&)’
 1265 |   yyval = yyvsp[1-yylen];
      |                        ^
parser.y:91:40: error: expected unqualified-id before ‘void’
   91 |                             $<void>T;
      |                                        ^   
parser.y:91:40: error: expected ‘)’ before ‘void’
   91 |                             $<void>T;
      |                             ~          ^   
      |                                        )
parser.y:95:39: error: expected unqualified-id before ‘void’
   95 |                             $<void>F;
      |                                       ^   
parser.y:95:39: error: expected ‘)’ before ‘void’
   95 |                             $<void>F;
      |                             ~         ^   
      |                                       )
parser.y:100:54: error: expected ‘;’ before ‘<’ token
  100 |                         for (int i=$on, i<$tw, i+=$th)
      |                                                      ^
      |                                                      ;
parser.y:100:54: error: expected primary-expression before ‘<’ token
parser.y:100:90: error: expected ‘;’ before ‘)’ token
  100 |                         for (int i=$on, i<$tw, i+=$th)
      |                                                                                          ^
      |                                                                                          ;
parser.y:102:39: error: expected unqualified-id before ‘void’
  102 |                             $<void>statements;
      |                                       ^~~~
parser.y:102:39: error: expected ‘)’ before ‘void’
  102 |                             $<void>statements;
      |                             ~         ^~~~
      |                                       )
parser.y:109:39: error: expected unqualified-id before ‘void’
  109 |                             $<void>statements;
      |                                       ^~~~
parser.y:109:39: error: expected ‘)’ before ‘void’
  109 |                             $<void>statements;
      |                             ~         ^~~~
      |                                       )
parser.y:122:37: error: invalid use of ‘struct variableValue::value
  122 |                                 tmp.value.integer = $expr_large;
      |                                     ^~~~~
parser.y:138:37: error: invalid use of ‘struct variableValue::value
  138 |                                 tmp.value.decimal = $expr_large;
      |                                     ^~~~~
parser.y:154:37: error: invalid use of ‘struct variableValue::value
  154 |                                 tmp.value.str = $expr_large;
      |                                     ^~~~~
parser.y:173:37: error: invalid use of ‘struct variableValue::value
  173 |                                 tmp.value.integer = $expr_large;
      |                                     ^~~~~
parser.y:174:43: error: ‘class setVariable’ has no member named ‘push’
  174 |                                 variables.push(tmp);
      |                                           ^~~~
parser.y:189:37: error: invalid use of ‘struct variableValue::value
  189 |                                 tmp.value.decimal = $expr_large;
      |                                     ^~~~~
parser.y:190:43: error: ‘class setVariable’ has no member named ‘push’
  190 |                                 variables.push(tmp);
      |                                           ^~~~
parser.y:205:37: error: invalid use of ‘struct variableValue::value
  205 |                                 tmp.value.str = $expr_large;
      |                                     ^~~~~
parser.y:206:43: error: ‘class setVariable’ has no member named ‘push’
  206 |                                 variables.push(tmp);
      |                                           ^~~~
parser.y:263:73: error: expected ‘)’ before ‘;’ token
  263 |                         for (variableValue element : variables.showVar();)
      |                             ~                                           ^
      |                                                                         )
parser.y:263:74: error: expected primary-expression before ‘)’ token
  263 |                         for (variableValue element : variables.showVar();)
      |                                                                          ^
parser.tab.c:1588:14: error: use of deleted function ‘YYSTYPE& YYSTYPE::operator=(const YYSTYPE&)’
 1588 |   *++yyvsp = yyval;
      |              ^~~~~
parser.tab.c:1697:14: error: use of deleted function ‘YYSTYPE& YYSTYPE::operator=(const YYSTYPE&)’
 1697 |   *++yyvsp = yylval;
      |              ^~~~~~
parser.tab.c: In function ‘void __static_initialization_and_destruction_0(int, int)’:
parser.tab.c:995:9: error: use of deleted function ‘YYSTYPE::~YYSTYPE()’
  995 | YYSTYPE yylval;
      |         ^~~~~~

 

このエラーメッセージから考察するに、YYSTYPEすなわち型関係のエラーが中心である。(当たり前)

さて、どうやって修正するかだが、正直言ってさっぱりわからん。

仕方ないが、少しずつ書き直していく他ないだろう。

有識者の方は、なぜ動かないのか教えてくださると助かります。

 

*1:"_"|([a-z]|[A-Z]

申し訳ない・・・

謝罪

今回、だいぶ前にqittaで質問してたものに回答がついてたみたいで、それに気づかずに同じような質問をteratailに送ってしまいました。

しかも、qittaで回答してくださった方は非常に丁寧に回答してくださっており、申し訳ない気持ちでいっぱいです。

本当に、申し訳ありませんでした。

さて、すこし話題は変わりますが

結局、C++で書くのは諦めます。Cで書きます。

C++だと色々ややこしくてめんどくさい文法になることが判明したので・・・。

今後について

結局、flexとbisonを使うことになった。

多少めんどくさいが、仕方ないだろう。

ただし、今回使うのは普通のflex/bisonではない。

flexc++とbisonc++である。

これは、C++で書くことに特化したflex/bisonの進化形である。

日本語の資料が皆無なので、英語のリファレンスを読んでいくことになる。

がんばります

1.現在の状況

あいさつ

こんにちは。tomdawncatsです。ブログに興味を持ち、不定期更新ながら書こうと考え、このプログを始めました。

私は現在、私の長年の夢であったプログラミング言語開発を、PythonのLarkで実現しようとしており、その開発過程をこのブログにかいていこうと思います。

現在の状況

  • 言語の名前:「Freeze」 (先にどうでもいいところをきめちゃうやつ)
  • コンセプト: Python似の雰囲気を出しながら、ユーザに基本的に決めてもらう形式
  • 「while文、def文(関数定義)、変数定義文、if文、return文、比較演算子、デクリメント・インクリメント、カッコを含む計算、文字列(変数への代入のみ)、リスト、名前空間の宣言、include文」を実装済

これから実装したいもの

  1. for文
  2. Pythonを使用する、Freeze言語のAPI
  3. クラス
  4. 文字列操作