mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:07:47 +00:00
JSSpecCompiler: Parse lists in xspec mode
This commit is contained in:
parent
d14bb7e91e
commit
e1a1f4ed1a
9 changed files with 102 additions and 0 deletions
|
@ -146,4 +146,12 @@ String Variable::name() const
|
||||||
return MUST(String::from_utf8(m_name->m_name));
|
return MUST(String::from_utf8(m_name->m_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<NodeSubtreePointer> List::subtrees()
|
||||||
|
{
|
||||||
|
Vector<NodeSubtreePointer> result;
|
||||||
|
for (auto& element : m_elements)
|
||||||
|
result.append({ &element });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,6 +547,22 @@ protected:
|
||||||
void dump_tree(StringBuilder& builder) override;
|
void dump_tree(StringBuilder& builder) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class List : public Expression {
|
||||||
|
public:
|
||||||
|
List(Vector<Tree>&& elements)
|
||||||
|
: m_elements(elements)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<NodeSubtreePointer> subtrees() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dump_tree(StringBuilder& builder) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<Tree> m_elements;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
|
@ -187,4 +187,11 @@ void FunctionPointer::dump_tree(StringBuilder& builder)
|
||||||
dump_node(builder, "Func \"{}\"", m_declaration->m_name);
|
dump_node(builder, "Func \"{}\"", m_declaration->m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void List::dump_tree(StringBuilder& builder)
|
||||||
|
{
|
||||||
|
dump_node(builder, "List");
|
||||||
|
for (auto const& element : m_elements)
|
||||||
|
element->format_tree(builder);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ void tokenize_string(SpecificationParsingContext& ctx, XML::Node const* node, St
|
||||||
{ ">"sv, TokenType::Greater },
|
{ ">"sv, TokenType::Greater },
|
||||||
{ "is"sv, TokenType::Is },
|
{ "is"sv, TokenType::Is },
|
||||||
{ "<"sv, TokenType::Less },
|
{ "<"sv, TokenType::Less },
|
||||||
|
{ "»"sv, TokenType::ListEnd },
|
||||||
|
{ "«"sv, TokenType::ListStart },
|
||||||
{ "."sv, TokenType::MemberAccess },
|
{ "."sv, TokenType::MemberAccess },
|
||||||
{ "×"sv, TokenType::Multiplication },
|
{ "×"sv, TokenType::Multiplication },
|
||||||
{ "is not equal to"sv, TokenType::NotEquals },
|
{ "is not equal to"sv, TokenType::NotEquals },
|
||||||
|
|
|
@ -170,6 +170,30 @@ TextParseErrorOr<Vector<Tree>> TextParser::parse_function_arguments()
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <list_initialization> :== « (<expr> (, <expr>)*)? »
|
||||||
|
TextParseErrorOr<Tree> TextParser::parse_list_initialization()
|
||||||
|
{
|
||||||
|
auto rollback = rollback_point();
|
||||||
|
|
||||||
|
TRY(consume_token_with_type(TokenType::ListStart));
|
||||||
|
|
||||||
|
if (!consume_token_with_type(TokenType::ListEnd).is_error()) {
|
||||||
|
rollback.disarm();
|
||||||
|
return make_ref_counted<List>(Vector<Tree> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Tree> elements;
|
||||||
|
while (true) {
|
||||||
|
elements.append(TRY(parse_expression()));
|
||||||
|
|
||||||
|
auto token = TRY(consume_token_with_one_of_types({ TokenType::ListEnd, TokenType::Comma }));
|
||||||
|
if (token.type == TokenType::ListEnd)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rollback.disarm();
|
||||||
|
return make_ref_counted<List>(move(elements));
|
||||||
|
}
|
||||||
|
|
||||||
// <expr>
|
// <expr>
|
||||||
TextParseErrorOr<Tree> TextParser::parse_expression()
|
TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
{
|
{
|
||||||
|
@ -296,6 +320,9 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
// This is just an opening '(' in expression.
|
// This is just an opening '(' in expression.
|
||||||
stack.append(token);
|
stack.append(token);
|
||||||
}
|
}
|
||||||
|
} else if (token.type == TokenType::ListStart) {
|
||||||
|
stack.append(TRY(parse_list_initialization()));
|
||||||
|
is_consumed = true;
|
||||||
} else if (token.is_pre_merged_binary_operator()) {
|
} else if (token.is_pre_merged_binary_operator()) {
|
||||||
THROW_PARSE_ERROR_IF(last_element_type != ExpressionType);
|
THROW_PARSE_ERROR_IF(last_element_type != ExpressionType);
|
||||||
stack.append(token);
|
stack.append(token);
|
||||||
|
|
|
@ -73,6 +73,7 @@ private:
|
||||||
|
|
||||||
TextParseErrorOr<Tree> parse_record_direct_list_initialization();
|
TextParseErrorOr<Tree> parse_record_direct_list_initialization();
|
||||||
TextParseErrorOr<Vector<Tree>> parse_function_arguments();
|
TextParseErrorOr<Vector<Tree>> parse_function_arguments();
|
||||||
|
TextParseErrorOr<Tree> parse_list_initialization();
|
||||||
TextParseErrorOr<Tree> parse_expression();
|
TextParseErrorOr<Tree> parse_expression();
|
||||||
TextParseErrorOr<Tree> parse_condition();
|
TextParseErrorOr<Tree> parse_condition();
|
||||||
TextParseErrorOr<Tree> parse_return_statement();
|
TextParseErrorOr<Tree> parse_return_statement();
|
||||||
|
|
|
@ -37,6 +37,8 @@ constexpr i32 closing_bracket_precedence = 18;
|
||||||
F(Identifier, -1, Invalid, Invalid, Invalid, "identifier") \
|
F(Identifier, -1, Invalid, Invalid, Invalid, "identifier") \
|
||||||
F(Is, -1, Invalid, Invalid, Invalid, "operator is") \
|
F(Is, -1, Invalid, Invalid, Invalid, "operator is") \
|
||||||
F(Less, 9, Invalid, CompareLess, Invalid, "less than") \
|
F(Less, 9, Invalid, CompareLess, Invalid, "less than") \
|
||||||
|
F(ListEnd, -1, Invalid, Invalid, Invalid, "»") \
|
||||||
|
F(ListStart, -1, Invalid, Invalid, Invalid, "«") \
|
||||||
F(MemberAccess, 2, Invalid, MemberAccess, Invalid, "member access operator '.'") \
|
F(MemberAccess, 2, Invalid, MemberAccess, Invalid, "member access operator '.'") \
|
||||||
F(Multiplication, 5, Invalid, Multiplication, Invalid, "multiplication") \
|
F(Multiplication, 5, Invalid, Multiplication, Invalid, "multiplication") \
|
||||||
F(NotEquals, 10, Invalid, CompareNotEqual, Invalid, "not equals") \
|
F(NotEquals, 10, Invalid, CompareNotEqual, Invalid, "not equals") \
|
||||||
|
|
|
@ -49,4 +49,18 @@
|
||||||
</ol>
|
</ol>
|
||||||
</emu-alg>
|
</emu-alg>
|
||||||
</emu-clause>
|
</emu-clause>
|
||||||
|
<emu-clause id="5" aoid="Lists">
|
||||||
|
<h1>
|
||||||
|
<span class="secnum">5</span> Lists ( <var>a</var>, <var>b</var> )
|
||||||
|
</h1>
|
||||||
|
<emu-alg>
|
||||||
|
<ol>
|
||||||
|
<li>Let <var>a</var> be « ».</li>
|
||||||
|
<li>Set <var>a</var> to « <emu-const>1</emu-const> ».</li>
|
||||||
|
<li>Set <var>a</var> to « <emu-const>1</emu-const>, <emu-const>2</emu-const> ».</li>
|
||||||
|
<li>Set <var>a</var> to « <emu-const>1</emu-const>, <emu-const>2</emu-const>, 3 + 4 ».</li>
|
||||||
|
<li>Return <emu-const>unused</emu-const>.</li>
|
||||||
|
</ol>
|
||||||
|
</emu-alg>
|
||||||
|
</emu-clause>
|
||||||
</specification>
|
</specification>
|
||||||
|
|
|
@ -62,3 +62,28 @@ TreeList
|
||||||
Func "WellKnownConstants"
|
Func "WellKnownConstants"
|
||||||
Enumerator enumerator
|
Enumerator enumerator
|
||||||
|
|
||||||
|
Lists(a, b):
|
||||||
|
TreeList
|
||||||
|
BinaryOperation Assignment
|
||||||
|
Var a
|
||||||
|
List
|
||||||
|
BinaryOperation Assignment
|
||||||
|
Var a
|
||||||
|
List
|
||||||
|
Enumerator 1
|
||||||
|
BinaryOperation Assignment
|
||||||
|
Var a
|
||||||
|
List
|
||||||
|
Enumerator 1
|
||||||
|
Enumerator 2
|
||||||
|
BinaryOperation Assignment
|
||||||
|
Var a
|
||||||
|
List
|
||||||
|
Enumerator 1
|
||||||
|
Enumerator 2
|
||||||
|
BinaryOperation Plus
|
||||||
|
MathematicalConstant 3
|
||||||
|
MathematicalConstant 4
|
||||||
|
ReturnNode
|
||||||
|
Enumerator unused
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue