Зубр - принять параметры из командной строки
Я работаю над простым интерпретатором зубров, который может принимать аргументы командной строки в качестве параметров. Например, функция main a: integer, b: integer возвращает целое число; Вы бы поместили следующее в командную строку:
$ ./compile < test.txt 2 4
И при компиляции параметр a будет инициализирован равным 2, а параметр b равным 4. Например:
$ ./compile < test.txt 2 4
1 function main a: integer, b: integer returns integer;
2 c: integer is
3 if a > b then
4 a rem b;
5 else
6 a ** 2;
7 endif;
8 begin
9 case a is
10 when 1 => c;
11 when 2 => (a + b / 2 - 4) * 3;
12 others => 4;
13 endcase;
14 end;
Compiled Successfully
Result = 0
Я где-то видел, что для этого мне нужно объявить глобальный массив, который динамически размещается на основе argc, в верхней части parser.y. В основном я бы преобразовал каждый аргумент командной строки в double и сохранил его в этом глобальном массиве. Функция atof сделает преобразование char * в double.
Можете ли вы рассказать мне, как я это реализовал? Не уверен, что это вопрос C или Bison. Это мой файл parser.y:
%{
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <math.h>
using namespace std;
#include "values.h"
#include "listing.h"
#include "symbols.h"
int yylex();
void yyerror(const char* message);
Symbols<int> symbols;
int result;
%}
%error-verbose
%union
{
CharPtr iden;
Operators oper;
int value;
}
%token <iden> IDENTIFIER
%token <value> INT_LITERAL REAL_LITERAL BOOL_LITERAL
%token <oper> ADDOP MULOP RELOP OROP NOTOP REMOP EXPOP
%token ANDOP
%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%token THEN WHEN
%token CASE ELSE ENDCASE ENDIF IF OTHERS REAL
%type <value> body statement_ statement reductions unary exponent expression binary relation term
factor primary
%type <oper> operator
%%
function:
function_header optional_variable body {result = $3;} ;
function_header:
FUNCTION IDENTIFIER parameters RETURNS type ';' |
FUNCTION IDENTIFIER RETURNS type ';' |
error ';' ;
optional_variable:
optional_variable variable |
error ';' |
;
variable:
IDENTIFIER ':' type IS statement_ {symbols.insert($1, $5);} ;
parameters:
parameter optional_parameter;
optional_parameter:
optional_parameter ',' parameter |
;
parameter:
IDENTIFIER ':' type;
type:
INTEGER |
REAL |
BOOLEAN ;
body:
BEGIN_ statement_ END ';' {$$ = $2;} ;
statement_:
statement ';' |
error ';' {$$ = 0;} ;
statement:
expression |
REDUCE operator reductions ENDREDUCE {$$ = $3;} |
IF expression THEN statement_ ELSE statement_ ENDIF {$$ = $4,$6;};
/* CASE expression IS case OTHERS ARROW statement_ ENDCASE ;
case:
case WHEN INT_LITERAL ARROW statement_ |
;*/
operator:
ADDOP |
RELOP |
EXPOP |
MULOP ;
reductions:
reductions statement_ {$$ = evaluateReduction($<oper>0, $1, $2);} |
{$$ = $<oper>0 == ADD ? 0 : 1;} ;
expression:
expression OROP binary {$$ = $1 || $3;} |
binary;
binary:
binary ANDOP relation {$$ = $1 && $3;} |
relation ;
relation:
relation RELOP term {$$ = evaluateRelational($1, $2, $3);} |
term ;
term:
term ADDOP factor {$$ = evaluateArithmetic($1, $2, $3);} |
factor ;
factor:
factor MULOP exponent {$$ = evaluateArithmetic($1, $2, $3);} |
factor REMOP exponent { $$=$1%$3; } |
exponent ;
exponent:
exponent EXPOP unary { $$=pow($1,$3); } |
exponent '(' unary ')' {$$ = $3;}|
unary;
unary:
NOTOP primary {$$ = $2;}|
primary;
primary:
'(' expression ')' {$$ = $2;} |
INT_LITERAL |
REAL_LITERAL |
BOOL_LITERAL |
IDENTIFIER {if (!symbols.find($1, $$)) appendError(UNDECLARED, $1);} ;
%%
void yyerror(const char* message)
{
appendError(SYNTAX, message);
}
int main(int argc, char *argv[])
{
firstLine();
yyparse();
if (lastLine() == 0)
cout << "Result = " << result << endl;
return 0;
}