mirror of
https://github.com/ksherlock/mpw-shell.git
synced 2025-01-19 13:32:07 +00:00
phase parsing improvements
This commit is contained in:
parent
1b4eb0f2bc
commit
1219a40d07
12
phase1.h
12
phase1.h
@ -24,11 +24,19 @@ public:
|
|||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
//template<class F>
|
|
||||||
//phase1 &operator >>= (F &&f) { pipe_to = pipe_function(f); return *this; }
|
|
||||||
|
|
||||||
phase1 &operator >>= (pipe_function f) { pipe_to = f; return *this; }
|
phase1 &operator >>= (pipe_function f) { pipe_to = f; return *this; }
|
||||||
|
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
phase1 &operator >>= (F &f) {
|
||||||
|
using std::placeholders::_1;
|
||||||
|
pipe_to = std::bind(&F::operator(), &f, _1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string scratch;
|
std::string scratch;
|
||||||
pipe_function pipe_to;
|
pipe_function pipe_to;
|
||||||
|
8
phase2.h
8
phase2.h
@ -52,11 +52,19 @@ public:
|
|||||||
phase2 & operator=(const phase2 &) = delete;
|
phase2 & operator=(const phase2 &) = delete;
|
||||||
phase2 & operator=(phase2 &&) = default;
|
phase2 & operator=(phase2 &&) = default;
|
||||||
|
|
||||||
|
void operator()(const std::string &line) { process(line); }
|
||||||
void process(const std::string &line);
|
void process(const std::string &line);
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
phase2 &operator >>=(pipe_function f) { pipe_to = f; return *this; }
|
phase2 &operator >>=(pipe_function f) { pipe_to = f; return *this; }
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
phase2 &operator >>= (F &f) {
|
||||||
|
using std::placeholders::_1;
|
||||||
|
pipe_to = std::bind(&F::operator(), &f, _1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void parse(int, std::string &&);
|
void parse(int, std::string &&);
|
||||||
|
79
phase2.rl
79
phase2.rl
@ -14,9 +14,51 @@
|
|||||||
|
|
||||||
action not_special { !special() }
|
action not_special { !special() }
|
||||||
|
|
||||||
|
|
||||||
|
escape = 0xb6;
|
||||||
ws = [ \t];
|
ws = [ \t];
|
||||||
|
|
||||||
|
|
||||||
|
escape_seq =
|
||||||
|
escape any
|
||||||
|
;
|
||||||
|
|
||||||
|
sstring =
|
||||||
|
[']
|
||||||
|
( (any-[']) )*
|
||||||
|
[']
|
||||||
|
$err{
|
||||||
|
throw std::runtime_error("### MPW Shell - 's must occur in pairs.");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
vstring =
|
||||||
|
[{]
|
||||||
|
( (any-[{]) )*
|
||||||
|
[}]
|
||||||
|
$err{
|
||||||
|
throw std::runtime_error("### MPW Shell - 's must occur in pairs.");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
# double-quoted string.
|
||||||
|
dstring =
|
||||||
|
["]
|
||||||
|
(
|
||||||
|
escape_seq
|
||||||
|
|
|
||||||
|
(any-escape-["])
|
||||||
|
)*
|
||||||
|
["]
|
||||||
|
$err{
|
||||||
|
throw std::runtime_error("### MPW Shell - \"s must occur in pairs.");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main := |*
|
main := |*
|
||||||
|
|
||||||
'||' when not_special => {
|
'||' when not_special => {
|
||||||
flush();
|
flush();
|
||||||
parse(PIPE_PIPE, std::string(ts, te));
|
parse(PIPE_PIPE, std::string(ts, te));
|
||||||
@ -27,23 +69,42 @@
|
|||||||
parse(AMP_AMP, std::string(ts, te));
|
parse(AMP_AMP, std::string(ts, te));
|
||||||
};
|
};
|
||||||
|
|
||||||
'(' when not_special => {
|
|
||||||
|
# ( evaluate (1+2) ) is lparen, eval, rparen.
|
||||||
|
# need to balance parens here and terminate a special token when it goes negative.
|
||||||
|
|
||||||
|
|
||||||
|
'(' => {
|
||||||
|
if (special()) {
|
||||||
|
pcount++;
|
||||||
|
scratch.push_back(fc);
|
||||||
|
} else {
|
||||||
flush();
|
flush();
|
||||||
parse(LPAREN, std::string(ts, te));
|
parse(LPAREN, std::string(ts, te));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# ) may include redirection so start a new token but don't parse it yet.
|
')' => {
|
||||||
')' when not_special => {
|
if (special() && pcount-- > 0) scratch.push_back(fc);
|
||||||
|
else {
|
||||||
flush();
|
flush();
|
||||||
scratch.push_back(fc);
|
scratch.push_back(fc);
|
||||||
type = RPAREN;
|
type = RPAREN;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# todo -- also add in strings and escapes.
|
|
||||||
|
|
||||||
';' => { flush(); parse(SEMI, ";"); };
|
';' => { flush(); parse(SEMI, ";"); };
|
||||||
|
|
||||||
ws => { if (!scratch.empty()) scratch.push_back(fc); };
|
ws => { if (!scratch.empty()) scratch.push_back(fc); };
|
||||||
any => { scratch.push_back(fc); };
|
|
||||||
|
sstring => { scratch.append(ts, te); };
|
||||||
|
dstring => { scratch.append(ts, te); };
|
||||||
|
vstring => { scratch.append(ts, te); };
|
||||||
|
escape_seq => { scratch.append(ts, te); };
|
||||||
|
|
||||||
|
|
||||||
|
(any-escape-['"{]) => { scratch.push_back(fc); };
|
||||||
*|;
|
*|;
|
||||||
}%%
|
}%%
|
||||||
|
|
||||||
@ -80,7 +141,7 @@
|
|||||||
BEGIN %eof{ type = BEGIN; return; };
|
BEGIN %eof{ type = BEGIN; return; };
|
||||||
BEGIN ws => { type = BEGIN; return; };
|
BEGIN ws => { type = BEGIN; return; };
|
||||||
|
|
||||||
')' => { type = LPAREN; return; };
|
'(' => { type = LPAREN; return; };
|
||||||
*|;
|
*|;
|
||||||
|
|
||||||
}%%
|
}%%
|
||||||
@ -106,6 +167,7 @@ void phase2::flush() {
|
|||||||
scratch.clear();
|
scratch.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* slightly wrong since whitespace is needed for it to be special. */
|
||||||
bool phase2::special() {
|
bool phase2::special() {
|
||||||
if (!type) classify();
|
if (!type) classify();
|
||||||
|
|
||||||
@ -140,6 +202,7 @@ void phase2::classify() {
|
|||||||
|
|
||||||
void phase2::process(const std::string &line) {
|
void phase2::process(const std::string &line) {
|
||||||
|
|
||||||
|
int pcount = 0; // special form parens cannot cross lines.
|
||||||
|
|
||||||
int cs;
|
int cs;
|
||||||
int act;
|
int act;
|
||||||
@ -156,6 +219,8 @@ void phase2::process(const std::string &line) {
|
|||||||
%% write exec;
|
%% write exec;
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
|
// 2 NLs to make the stack reduce. harmless if in a multi-line constuct.
|
||||||
|
parse(NL, "");
|
||||||
parse(NL, "");
|
parse(NL, "");
|
||||||
|
|
||||||
exec();
|
exec();
|
||||||
@ -185,6 +250,8 @@ void phase2::exec() {
|
|||||||
|
|
||||||
phase2::phase2() {
|
phase2::phase2() {
|
||||||
parser = std::move(phase2_parser::make());
|
parser = std::move(phase2_parser::make());
|
||||||
|
//parser->trace(stdout, " ] ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - phase2_parser
|
#pragma mark - phase2_parser
|
||||||
|
Loading…
x
Reference in New Issue
Block a user