feat: Add file parsing entry point and refine grammar rules

Signed-off-by: erick-alcachofa <erick@artichoke.dev>

- Updated `main.cpp` to read source files and invoke the parser using
  `MatcherRule<rules::Program>`, providing clear error output or success
  indication.
- Replaced `peek` with `peekExpect` in `Parser` to ensure expected token
  types.
- Replaced parentheses with curly braces for struct and enum definitions
  as specified on grammar.
- Fixed `StructMembers` and `EnumMembers` to allow zero or more entries
  as specified on grammar.
- Replaced `MatcherNoneOrOnce` with `MatcherNoneOrMore` in expression
  rules to support chained binary expressions as specified on grammar.
- Reorganized `PrimaryTypeExpression` to include all valid expression
  types, and reordered rules for better match accuracy.
- Fixed `TypesListR` to correctly refer to `Type` instead of
  `TypesListR` in its recursive rule.

These changes fixes language grammar coverage, fix structural parsing
bugs, and enable full file parsing from the frontend.
This commit is contained in:
erick-alcachofa 2025-10-05 22:55:49 -06:00
parent 86d069d3d9
commit 5ba801a756
Signed by: me
GPG Key ID: 6FA5F8643444BAFA
2 changed files with 63 additions and 21 deletions

View File

@ -1,5 +1,45 @@
#include <print>
#include <fstream>
int main(int, char **) {
std::println("[LOG] Hello world");
#include <artichoke/Parser/Parser.hpp>
int main(int argc, char **argv) {
using namespace arti::lang;
if (argc < 2) {
std::println("Usage:\n {} <filename>", argv[0]);
return -1;
}
std::ifstream file;
file.open(argv[1]);
if (!file.is_open()) {
std::println("Failed to open file {}", argv[1]);
return -1;
}
std::string buffer{
std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>()
};
Tokenizer tokenizer{buffer};
auto result = MatcherRule<rules::Program>::parse(&tokenizer, 0);
if (!result) {
auto err = std::move(result).error();
std::println(
"Error at line {}, column {}. {}",
err.line,
err.column,
err.message
);
}
else {
std::println("Valid source");
}
return 0;
}

View File

@ -68,7 +68,7 @@ namespace arti::lang {
};
}
auto token = tokenizer->peek(offset);
auto token = tokenizer->peekExpect(offset, tokenType);
if (!token) {
return Unexpected<>{ std::move(token).error() };
@ -545,9 +545,9 @@ namespace arti::lang {
MatcherToken<TokenV::kwStruct>,
MatcherToken<TokenV::tkIdentifier>,
MatcherRule<GenericParams>,
MatcherToken<TokenV::opLParen>,
MatcherToken<TokenV::opLSquirly>,
MatcherRule<StructMembers>,
MatcherToken<TokenV::opRParen>
MatcherToken<TokenV::opRSquirly>
>;
};
@ -555,7 +555,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "StructMembers";
using Rule = MatcherSequence<
MatcherRule<StructMember>,
MatcherOnceOrMore<
MatcherNoneOrMore<
MatcherSequence<
MatcherToken<TokenV::opComma>,
MatcherRule<StructMember>
@ -580,9 +580,9 @@ namespace arti::lang {
MatcherToken<TokenV::kwEnum>,
MatcherToken<TokenV::tkIdentifier>,
MatcherRule<GenericParams>,
MatcherToken<TokenV::opLParen>,
MatcherToken<TokenV::opLSquirly>,
MatcherRule<EnumMembers>,
MatcherToken<TokenV::opRParen>
MatcherToken<TokenV::opRSquirly>
>;
};
@ -590,10 +590,10 @@ namespace arti::lang {
static constexpr std::string_view Name = "EnumMembers";
using Rule = MatcherSequence<
MatcherRule<EnumMember>,
MatcherOnceOrMore<
MatcherNoneOrMore<
MatcherSequence<
MatcherToken<TokenV::opComma>,
MatcherRule<StructMember>
MatcherRule<EnumMember>
>
>
>;
@ -1012,7 +1012,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "BoolOrExpression";
using Rule = MatcherSequence<
MatcherRule<BoolAndExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherAnyOf<
MatcherToken<TokenV::opBoolOr>,
@ -1028,7 +1028,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "BoolAndExpression";
using Rule = MatcherSequence<
MatcherRule<CompareExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherAnyOf<
MatcherToken<TokenV::opBoolAnd>,
@ -1057,7 +1057,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "BitwiseExpression";
using Rule = MatcherSequence<
MatcherRule<BitwiseShiftExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherRule<BitwiseOp>,
MatcherRule<BitwiseShiftExpression>
@ -1070,7 +1070,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "BitwiseShiftExpression";
using Rule = MatcherSequence<
MatcherRule<AdditionExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherRule<BitshiftOp>,
MatcherRule<AdditionExpression>
@ -1083,7 +1083,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "AdditionExpression";
using Rule = MatcherSequence<
MatcherRule<MultiplyExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherRule<AdditionOp>,
MatcherRule<MultiplyExpression>
@ -1096,7 +1096,7 @@ namespace arti::lang {
static constexpr std::string_view Name = "MultiplyExpression";
using Rule = MatcherSequence<
MatcherRule<PrefixExpression>,
MatcherNoneOrOnce<
MatcherNoneOrMore<
MatcherSequence<
MatcherRule<MultiplyOp>,
MatcherRule<PrefixExpression>
@ -1131,6 +1131,11 @@ namespace arti::lang {
struct PrimaryTypeExpression {
static constexpr std::string_view Name = "PrimaryTypeExpression";
using Rule = MatcherAnyOf<
MatcherRule<GroupedExpression>,
MatcherRule<ScopedAccessExpression>,
MatcherRule<ReflectionExpression>,
MatcherRule<StructLiteral>,
MatcherRule<TypeName>,
MatcherToken<TokenV::tkCharacter>,
MatcherToken<TokenV::kwNull>,
MatcherToken<TokenV::tkString>,
@ -1138,10 +1143,7 @@ namespace arti::lang {
MatcherToken<TokenV::tkDecimal>,
MatcherToken<TokenV::kwTrue>,
MatcherToken<TokenV::kwFalse>,
MatcherRule<StructLiteral>,
MatcherRule<GroupedExpression>,
MatcherRule<ScopedAccessExpression>,
MatcherRule<ReflectionExpression>
MatcherToken<TokenV::tkIdentifier>
>;
};
@ -1495,7 +1497,7 @@ namespace arti::lang {
MatcherNoneOrMore<
MatcherSequence<
MatcherToken<TokenV::opComma>,
MatcherRule<TypesListR>
MatcherRule<Type>
>
>
>;