fixed tokens
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
#Compiler and Linker
|
#Compiler and Linker
|
||||||
CC := g++
|
CC := g++
|
||||||
|
|
||||||
|
# Ensure POSIX utilities in MSYS2 take precedence over Windows System32
|
||||||
|
export PATH := /usr/bin:/ucrt64/bin:$(PATH)
|
||||||
|
|
||||||
#The Target Binary Program
|
#The Target Binary Program
|
||||||
TARGET := out.exe
|
TARGET := out.exe
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(ValueFromRemainingArguments = $true)]
|
||||||
|
[string[]]$Command
|
||||||
|
)
|
||||||
|
|
||||||
|
$msysRoot = if ($env:MSYS2_ROOT) { $env:MSYS2_ROOT } else { "C:\msys64" }
|
||||||
|
$bash = Join-Path $msysRoot "usr\bin\bash.exe"
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $bash)) {
|
||||||
|
Write-Error "MSYS2 bash was not found at: $bash"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$env:MSYSTEM = "UCRT64"
|
||||||
|
$env:CHERE_INVOKING = "1"
|
||||||
|
|
||||||
|
if ($Command.Count -eq 0) {
|
||||||
|
& $bash --login
|
||||||
|
} else {
|
||||||
|
$cmdString = $Command -join " "
|
||||||
|
& $bash -lc $cmdString
|
||||||
|
}
|
||||||
|
|
||||||
|
exit $LASTEXITCODE
|
||||||
@@ -101,7 +101,7 @@ void test_literals(TokenFactory& tf) {
|
|||||||
void test_addressing_modes(TokenFactory& tf) {
|
void test_addressing_modes(TokenFactory& tf) {
|
||||||
std::cout << "\n--- Testing Addressing Modes ---\n";
|
std::cout << "\n--- Testing Addressing Modes ---\n";
|
||||||
run_test_case(asm_ebnf::register_tok, "R0", true);
|
run_test_case(asm_ebnf::register_tok, "R0", true);
|
||||||
run_test_case(asm_ebnf::register_tok, "R15", true);
|
run_test_case(asm_ebnf::register_tok, "R15", false); // R15 does not exist!
|
||||||
|
|
||||||
run_test_case(asm_ebnf::addrm_ind, "[ 0x1000 ]", true);
|
run_test_case(asm_ebnf::addrm_ind, "[ 0x1000 ]", true);
|
||||||
run_test_case(asm_ebnf::addrm_ptr, "[R1]", true);
|
run_test_case(asm_ebnf::addrm_ptr, "[R1]", true);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace spider::asm_ebnf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isWhithespaceCharNotCrLf(u32 ch) {
|
bool isWhithespaceCharNotCrLf(u32 ch) {
|
||||||
return ch == u32(' ');
|
return ch == u32(' ') || ch == u32('\t');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isUTF8CharNotCrLf(u32 ch) {
|
bool isUTF8CharNotCrLf(u32 ch) {
|
||||||
@@ -17,11 +17,11 @@ namespace spider::asm_ebnf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isUTF8CharLitCont(u32 ch) {
|
bool isUTF8CharLitCont(u32 ch) {
|
||||||
return ch != u32('\'');
|
return ch != u32('\'') && ch != u32('\\') && ch != u32('\r') && ch != u32('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isUTF8StringLitCont(u32 ch) {
|
bool isUTF8StringLitCont(u32 ch) {
|
||||||
return ch != u32('"');
|
return ch != u32('"') && ch != u32('\\') && ch != u32('\r') && ch != u32('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token* letter;
|
const Token* letter;
|
||||||
@@ -151,12 +151,12 @@ namespace spider::asm_ebnf {
|
|||||||
octal_lit = tf.tag(tf.seq({ tf.opt(sign), tf["0c"], octal_digit, tf.rep(octal_digit) }), "octal_lit", true);
|
octal_lit = tf.tag(tf.seq({ tf.opt(sign), tf["0c"], octal_digit, tf.rep(octal_digit) }), "octal_lit", true);
|
||||||
binary_lit = tf.tag(tf.seq({ tf.opt(sign), tf["0b"], binary_digit, tf.rep(binary_digit) }), "binary_lit", true);
|
binary_lit = tf.tag(tf.seq({ tf.opt(sign), tf["0b"], binary_digit, tf.rep(binary_digit) }), "binary_lit", true);
|
||||||
|
|
||||||
literal = tf.tag(tf.choice({ float_lit, decimal_lit, hex_lit, octal_lit, binary_lit, string_lit, char_lit }), "literal");
|
literal = tf.tag(tf.choice({ hex_lit, octal_lit, binary_lit, float_lit, decimal_lit, string_lit, char_lit }), "literal");
|
||||||
literal_cast = tf.tag(tf.seq({ tf.choice("BSILFD"), ws_optional, tf["("], ws_optional, literal, ws_optional, tf[")"] }), "literal_cast");
|
literal_cast = tf.tag(tf.seq({ tf.choice("BSILFD"), ws_optional, tf["("], ws_optional, literal, ws_optional, tf[")"] }), "literal_cast");
|
||||||
literal_decl = tf.tag(tf.choice({ literal, literal_cast }), "literal_decl");
|
literal_decl = tf.tag(tf.choice({ literal, literal_cast }), "literal_decl");
|
||||||
|
|
||||||
// (* Operands *)
|
// (* Operands *)
|
||||||
register_tok = tf.tag(tf.seq({ tf["R"], alpha_num_char }), "register", true);
|
register_tok = tf.tag(tf.seq({ tf["R"], alpha_num_char, tf.not_(tf.choice({ alpha_num_char, tf["_"] })) }), "register", true);
|
||||||
|
|
||||||
addrm_ind = tf.tag(tf.seq({ tf["["], ws_optional, literal_decl, ws_optional, tf["]"] }), "addrm_ind", true);
|
addrm_ind = tf.tag(tf.seq({ tf["["], ws_optional, literal_decl, ws_optional, tf["]"] }), "addrm_ind", true);
|
||||||
addrm_ptr = tf.tag(tf.seq({ tf["["], ws_optional, register_tok, ws_optional, tf["]"] }), "addrm_ptr", true);
|
addrm_ptr = tf.tag(tf.seq({ tf["["], ws_optional, register_tok, ws_optional, tf["]"] }), "addrm_ptr", true);
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ namespace spider {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token* TokenFactory::not_(const Token* target) {
|
||||||
|
uptr<Token> p = std::make_unique<NotToken>(target);
|
||||||
|
auto t = p.get();
|
||||||
|
arena.emplace_back(std::move(p));
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
Token* TokenFactory::tag(const Token* target, std::string_view tagname, bool flatten) {
|
Token* TokenFactory::tag(const Token* target, std::string_view tagname, bool flatten) {
|
||||||
uptr<Token> p = std::make_unique<TagToken>(target, tagname, flatten);
|
uptr<Token> p = std::make_unique<TagToken>(target, tagname, flatten);
|
||||||
auto t = p.get();
|
auto t = p.get();
|
||||||
@@ -97,27 +104,15 @@ namespace spider {
|
|||||||
return { .success = false };
|
return { .success = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
FnToken::FnToken(FnTokenFn chfn) : fn(chfn) {}
|
FnToken::FnToken(FnTokenFn chfn) : fn(std::move(chfn)) {}
|
||||||
|
|
||||||
TokenResult FnToken::test(TextReader& ctx) const {
|
TokenResult FnToken::test(TextReader& ctx) const {
|
||||||
TokenResult r;
|
auto c = ctx.current();
|
||||||
|
if (c && fn(*c)) {
|
||||||
for (;;) {
|
|
||||||
auto i = ctx.push();
|
|
||||||
auto c = ctx.current();
|
|
||||||
|
|
||||||
if (!c || !fn(*c)) {
|
|
||||||
ctx.pop(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
r.match += *c;
|
|
||||||
ctx.nextChar();
|
ctx.nextChar();
|
||||||
|
return { .success = true, .match = std::u32string(1, char32_t(*c)) };
|
||||||
}
|
}
|
||||||
|
return { .success = false };
|
||||||
r.success = !r.match.empty();
|
|
||||||
if(r.success) std::cout << "[fn] matched: " << unicode::toUTF8(r.flatMatch()) << std::endl;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -166,7 +161,6 @@ namespace spider {
|
|||||||
// Short-circuit branch: return immediately on first valid choice match
|
// Short-circuit branch: return immediately on first valid choice match
|
||||||
TokenResult res = token_ref->test(ctx);
|
TokenResult res = token_ref->test(ctx);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
std::cout << "[or] matched: " << unicode::toUTF8(res.flatMatch()) << std::endl;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +182,6 @@ namespace spider {
|
|||||||
TokenResult res = target->test(ctx);
|
TokenResult res = target->test(ctx);
|
||||||
|
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
std::cout << "[~] matched: " << unicode::toUTF8(res.flatMatch()) << std::endl;
|
|
||||||
return res; // Option matched exactly 1 instance successfully
|
return res; // Option matched exactly 1 instance successfully
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +191,19 @@ namespace spider {
|
|||||||
return { .success = true };
|
return { .success = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// NotToken Implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
NotToken::NotToken(const Token* t) : target(t) {}
|
||||||
|
|
||||||
|
TokenResult NotToken::test(TextReader& ctx) const {
|
||||||
|
auto i = ctx.push();
|
||||||
|
TokenResult res = target->test(ctx);
|
||||||
|
ctx.pop(i);
|
||||||
|
return { .success = !res.success };
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// RepToken Implementation
|
// RepToken Implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -225,7 +231,6 @@ namespace spider {
|
|||||||
// Repetition rules (* token) always evaluate to successful
|
// Repetition rules (* token) always evaluate to successful
|
||||||
// completion state, even with 0 matches.
|
// completion state, even with 0 matches.
|
||||||
r.success = true;
|
r.success = true;
|
||||||
std::cout << "[*] matched: " << unicode::toUTF8(r.flatMatch()) << std::endl;
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ namespace spider {
|
|||||||
|
|
||||||
Token* rep(const Token* target);
|
Token* rep(const Token* target);
|
||||||
|
|
||||||
|
Token* not_(const Token* target);
|
||||||
|
|
||||||
Token* tag(const Token* target, std::string_view tagname, bool flatten = false);
|
Token* tag(const Token* target, std::string_view tagname, bool flatten = false);
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -211,6 +213,20 @@ namespace spider {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Negative lookahead combinator (NotToken).
|
||||||
|
*/
|
||||||
|
class NotToken : public Token {
|
||||||
|
private:
|
||||||
|
const Token* target;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NotToken(const Token* t);
|
||||||
|
|
||||||
|
TokenResult test(TextReader& ctx) const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Evaluates zero-to-infinite loops of a single repetitive match signature (RepToken).
|
* @brief Evaluates zero-to-infinite loops of a single repetitive match signature (RepToken).
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user