add missing parsing: parse and missing operatiors in arithmetics
This commit is contained in:
parent
652e238c64
commit
3b10ce9e52
1 changed files with 81 additions and 112 deletions
193
src/parse.cpp
193
src/parse.cpp
|
|
@ -22,7 +22,7 @@ const std::vector<std::string> posix_cmdvar = { "export", "unset", "local", "rea
|
||||||
const std::vector<std::string> bash_cmdvar = { "readonly", "declare", "typeset" };
|
const std::vector<std::string> bash_cmdvar = { "readonly", "declare", "typeset" };
|
||||||
|
|
||||||
const std::vector<std::string> arithmetic_precedence_operators = { "!", "~", "+", "-" };
|
const std::vector<std::string> arithmetic_precedence_operators = { "!", "~", "+", "-" };
|
||||||
const std::vector<std::string> arithmetic_operators = { "+", "-", "*", "/", "=", "==", "!=", "&", "|", "^", "<<", ">>", "&&", "||" };
|
const std::vector<std::string> arithmetic_operators = { "+", "-", "*", "/", "+=", "-=", "*=", "/=", "=", "==", "!=", "&", "|", "^", "<<", ">>", "&&", "||" };
|
||||||
|
|
||||||
const std::vector<std::string> all_reserved_words = { "if", "then", "else", "fi", "case", "esac", "for", "while", "do", "done", "{", "}" };
|
const std::vector<std::string> all_reserved_words = { "if", "then", "else", "fi", "case", "esac", "for", "while", "do", "done", "{", "}" };
|
||||||
const std::vector<std::string> out_reserved_words = { "then", "else", "fi", "esac", "do", "done", "}" };
|
const std::vector<std::string> out_reserved_words = { "then", "else", "fi", "esac", "do", "done", "}" };
|
||||||
|
|
@ -289,6 +289,84 @@ std::pair<manipulation_subarg*, uint32_t> parse_manipulation(const char* in, uin
|
||||||
return std::make_pair(ret, i);
|
return std::make_pair(ret, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void do_one_subarg_step(arg* ret, const char* in, uint32_t size, uint32_t& i, uint32_t& j, bool is_quoted)
|
||||||
|
{
|
||||||
|
if( in[i] == '`' )
|
||||||
|
{
|
||||||
|
// add previous subarg
|
||||||
|
std::string tmpstr=std::string(in+j, i-j);
|
||||||
|
if(tmpstr!="")
|
||||||
|
ret->add(tmpstr);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
uint32_t k=skip_until(in, size, i, "`");
|
||||||
|
if(k>=size)
|
||||||
|
throw PARSE_ERROR("Expecting '`'", i-1);
|
||||||
|
// get subshell
|
||||||
|
auto r=parse_list_until(in, k, i, 0);
|
||||||
|
ret->add(new subshell_subarg(new subshell(r.first), is_quoted));
|
||||||
|
j = i = r.second+1;
|
||||||
|
}
|
||||||
|
else if( word_eq("$((", in, size, i) ) // arithmetic operation
|
||||||
|
{
|
||||||
|
// add previous subarg
|
||||||
|
std::string tmpstr=std::string(in+j, i-j);
|
||||||
|
if(tmpstr!="")
|
||||||
|
ret->add(tmpstr);
|
||||||
|
// get arithmetic
|
||||||
|
auto r=parse_arithmetic(in, size, i+3);
|
||||||
|
arithmetic_subarg* tt = new arithmetic_subarg(r.first);
|
||||||
|
tt->quoted=is_quoted;
|
||||||
|
ret->add(tt);
|
||||||
|
i = r.second;
|
||||||
|
if(!word_eq("))", in, size, i))
|
||||||
|
throw PARSE_ERROR( "Unexpected token ')', expecting '))'", i);
|
||||||
|
i+=2;
|
||||||
|
j=i;
|
||||||
|
}
|
||||||
|
else if( word_eq("$(", in, size, i) ) // substitution
|
||||||
|
{
|
||||||
|
// add previous subarg
|
||||||
|
std::string tmpstr=std::string(in+j, i-j);
|
||||||
|
if(tmpstr!="")
|
||||||
|
ret->add(tmpstr);
|
||||||
|
// get subshell
|
||||||
|
auto r=parse_subshell(in, size, i+2);
|
||||||
|
ret->add(new subshell_subarg(r.first, is_quoted));
|
||||||
|
j = i = r.second;
|
||||||
|
}
|
||||||
|
else if( word_eq("${", in, size, i) ) // variable manipulation
|
||||||
|
{
|
||||||
|
// add previous subarg
|
||||||
|
std::string tmpstr=std::string(in+j, i-j);
|
||||||
|
if(tmpstr!="")
|
||||||
|
ret->add(tmpstr);
|
||||||
|
// get manipulation
|
||||||
|
auto r=parse_manipulation(in, size, i+2);
|
||||||
|
r.first->quoted=is_quoted;
|
||||||
|
ret->add(r.first);
|
||||||
|
j = i = r.second;
|
||||||
|
}
|
||||||
|
else if( in[i] == '$' )
|
||||||
|
{
|
||||||
|
auto r=parse_var(in, size, i+1);
|
||||||
|
if(r.first !=nullptr)
|
||||||
|
{
|
||||||
|
// add previous subarg
|
||||||
|
std::string tmpstr=std::string(in+j, i-j);
|
||||||
|
if(tmpstr!="")
|
||||||
|
ret->add(tmpstr);
|
||||||
|
// add var
|
||||||
|
ret->add(new variable_subarg(r.first, is_quoted));
|
||||||
|
j = i = r.second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
// parse one argument
|
// parse one argument
|
||||||
// must start at a read char
|
// must start at a read char
|
||||||
// ends at either " \t|&;\n()"
|
// ends at either " \t|&;\n()"
|
||||||
|
|
@ -329,64 +407,8 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
|
||||||
{
|
{
|
||||||
i+=2;
|
i+=2;
|
||||||
}
|
}
|
||||||
else if( word_eq("$((", in, size, i) ) // arithmetic operation
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get arithmetic
|
|
||||||
auto r=parse_arithmetic(in, size, i+3);
|
|
||||||
arithmetic_subarg* tt = new arithmetic_subarg(r.first);
|
|
||||||
tt->quoted=true;
|
|
||||||
ret->add(tt);
|
|
||||||
i = r.second;
|
|
||||||
if(!word_eq("))", in, size, i))
|
|
||||||
throw PARSE_ERROR( "Unexpected token ')', expecting '))'", i);
|
|
||||||
i+=2;
|
|
||||||
j=i;
|
|
||||||
}
|
|
||||||
else if( word_eq("$(", in, size, i) ) // substitution
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get subshell
|
|
||||||
auto r=parse_subshell(in, size, i+2);
|
|
||||||
ret->add(new subshell_subarg(r.first, true));
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else if( word_eq("${", in, size, i) ) // variable manipulation
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get manipulation
|
|
||||||
auto r=parse_manipulation(in, size, i+2);
|
|
||||||
r.first->quoted=true;
|
|
||||||
ret->add(r.first);
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else if( in[i] == '$' )
|
|
||||||
{
|
|
||||||
auto r=parse_var(in, size, i+1);
|
|
||||||
if(r.first !=nullptr)
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// add var
|
|
||||||
ret->add(new variable_subarg(r.first, true));
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
i++;
|
do_one_subarg_step(ret, in, size, i, j, true);
|
||||||
|
|
||||||
if(i>=size)
|
if(i>=size)
|
||||||
throw PARSE_ERROR("Unterminated double quote", q);
|
throw PARSE_ERROR("Unterminated double quote", q);
|
||||||
|
|
@ -403,61 +425,8 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
|
||||||
throw PARSE_ERROR("Unterminated single quote", q);
|
throw PARSE_ERROR("Unterminated single quote", q);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if( word_eq("$((", in, size, i) ) // arithmetic operation
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get arithmetic
|
|
||||||
auto r=parse_arithmetic(in, size, i+3);
|
|
||||||
ret->add(new arithmetic_subarg(r.first));
|
|
||||||
i = r.second;
|
|
||||||
if(!word_eq("))", in, size, i))
|
|
||||||
throw PARSE_ERROR( "Unexpected token ')', expecting '))'", i);
|
|
||||||
i+=2;
|
|
||||||
j=i;
|
|
||||||
}
|
|
||||||
else if( word_eq("$(", in, size, i) ) // substitution
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get subshell
|
|
||||||
auto r=parse_subshell(in, size, i+2);
|
|
||||||
ret->add(new subshell_subarg(r.first, false));
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else if( word_eq("${", in, size, i) ) // variable manipulation
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// get manipulation
|
|
||||||
auto r=parse_manipulation(in, size, i+2);
|
|
||||||
ret->add(r.first);
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else if( in[i] == '$' )
|
|
||||||
{
|
|
||||||
auto r=parse_var(in, size, i+1);
|
|
||||||
if(r.first != nullptr)
|
|
||||||
{
|
|
||||||
// add previous subarg
|
|
||||||
std::string tmpstr=std::string(in+j, i-j);
|
|
||||||
if(tmpstr!="")
|
|
||||||
ret->add(tmpstr);
|
|
||||||
// add var
|
|
||||||
ret->add(new variable_subarg(r.first));
|
|
||||||
j = i = r.second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
i++;
|
do_one_subarg_step(ret, in, size, i, j, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add string subarg
|
// add string subarg
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue