Skip to content

Commit

Permalink
support parse literal expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
sbwtw committed Aug 25, 2024
1 parent 5749754 commit 022cb50
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 31 deletions.
4 changes: 4 additions & 0 deletions lib/src/parser/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub trait Buffer {
fn peek(&mut self, n: usize) -> Option<char>;
fn current_line(&self) -> usize;
fn current_offset(&self) -> usize;
/// At end of buffer
fn eof(&mut self) -> bool {
self.peek1().is_some()
}
}

pub struct StringBuffer<'input> {
Expand Down
57 changes: 33 additions & 24 deletions lib/src/parser/default_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,40 @@ type ParseResult<T> = Result<Option<T>, ParseError>;
#[derive(Default)]
pub struct DefaultParser {}

impl DefaultParser {
pub fn new() -> Self {
Default::default()
}
}

impl ParserTrait for DefaultParser {
#[inline]
fn parse_decl(&self, lexer: &mut StLexer) -> Result<Declaration, ParseError> {
self.parse_declaration(lexer)
DefaultParserImpl::new(lexer.into_iter()).parse_declaration()
}

#[inline]
fn parse_stmt(&self, lexer: &mut StLexer) -> Result<Statement, ParseError> {
self.parse_body(lexer)
DefaultParserImpl::new(lexer.into_iter()).parse_function()
}

#[inline]
fn parse_literal(&self, lexer: &mut StLexer) -> Result<LiteralExpression, ParseError> {
todo!()
}
}

impl DefaultParser {
pub fn new() -> Self {
Default::default()
}
let parse_result = DefaultParserImpl::new(lexer.into_iter()).parse_literal_expr()?;
if let Some(expr) = parse_result {
return Ok(expr);
}

pub fn parse_declaration<I>(&self, lexer: I) -> Result<Declaration, ParseError>
where
I: IntoIterator<Item = LexerResult>,
{
DefaultParserImpl::new(lexer.into_iter()).parse_declaration()
// TODO: Parse no result
Err(ParseError::InvalidToken(0))
}

pub fn parse_body<I: IntoIterator<Item = LexerResult>>(
&self,
lexer: I,
) -> Result<Statement, ParseError> {
DefaultParserImpl::new(lexer.into_iter()).parse_function()
#[inline]
fn parse_expression(&self, lexer: &mut StLexer) -> Result<Expression, ParseError> {
match DefaultParserImpl::new(lexer.into_iter()).parse_expression()? {
Some(expr) => Ok(expr),
None => Err(ParseError::InvalidToken(0)),
}
}
}

Expand Down Expand Up @@ -1088,7 +1088,7 @@ impl<I: Iterator<Item = LexerResult>> DefaultParserImpl<I> {
return Ok(Some(val));
}

if let Some(literal) = self.parse_literal_expr()? {
if let Some(literal) = self.parse_literal_expression()? {
return Ok(Some(literal));
}

Expand Down Expand Up @@ -1157,7 +1157,7 @@ impl<I: Iterator<Item = LexerResult>> DefaultParserImpl<I> {

fn parse_argument_expression(&mut self) -> ParseResult<Expression> {
Ok(self
.parse_literal_expr()?
.parse_literal_expression()?
.or(self.parse_argument_assign_expr()?))
}

Expand Down Expand Up @@ -1188,11 +1188,20 @@ impl<I: Iterator<Item = LexerResult>> DefaultParserImpl<I> {
))))
}

fn parse_literal_expr(&mut self) -> ParseResult<Expression> {
#[inline]
fn parse_literal_expression(&mut self) -> ParseResult<Expression> {
let result = self.parse_literal_expr()?;
match result {
Some(literal_expr) => Ok(Some(Expression::literal(Box::new(literal_expr)))),
None => Ok(None),
}
}

fn parse_literal_expr(&mut self) -> ParseResult<LiteralExpression> {
let pos = self.next;

if let TokenKind::Literal(val) = self.next_kind()? {
return Ok(Some(Expression::new_literal(val.clone())));
return Ok(Some(LiteralExpression::new(val.clone())));
}

self.next = pos;
Expand Down
21 changes: 20 additions & 1 deletion lib/src/parser/lalrpop_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,23 @@ where
pub struct LalrpopParser {
decl_parser: Lazy<st::DeclarationParser>,
body_parser: Lazy<st::StFunctionParser>,
literal_parser: Lazy<st::LiteralExprParser>,
expression_parser: Lazy<st::ExprParser>,
}

impl LalrpopParser {
pub fn new() -> Self {
Default::default()
}
}

impl Default for LalrpopParser {
fn default() -> Self {
Self {
decl_parser: Lazy::new(st::DeclarationParser::new),
body_parser: Lazy::new(st::StFunctionParser::new),
literal_parser: Lazy::new(st::LiteralExprParser::new),
expression_parser: Lazy::new(st::ExprParser::new),
}
}
}
Expand All @@ -67,6 +77,15 @@ impl ParserTrait for LalrpopParser {

#[inline]
fn parse_literal(&self, lexer: &mut StLexer) -> Result<LiteralExpression, ParseError> {
todo!()
self.literal_parser
.parse(LalrPopLexerWrapper::new(lexer.into_iter()))
.map_err(Into::into)
}

#[inline]
fn parse_expression(&self, lexer: &mut StLexer) -> Result<Expression, ParseError> {
self.expression_parser
.parse(LalrPopLexerWrapper::new(lexer.into_iter()))
.map_err(Into::into)
}
}
8 changes: 6 additions & 2 deletions lib/src/parser/lalrpop_impl/st.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ ElseIfStatement: ElseIfStatement = {
}

/// Expression
Expr: Expression = {
pub Expr: Expression = {
BitOrExpr,
AssignExpr => <>.into_expression(),
CallExpr => <>.into_expression(),
Expand Down Expand Up @@ -247,11 +247,15 @@ CompoFactor: Expression = {

/// terminals in expression
Term: Expression = {
"LITERAL" => <>.into_expression(),
LiteralExpr => Expression::literal(Box::new(<>)),
"(" <Expr> ")",
VarExpr,
};

/// Literal expressions
pub LiteralExpr: LiteralExpression = {
"LITERAL" => LiteralExpression::new(<>),
}

/// Declarations
pub Declaration = SingleDeclaration;
Expand Down
4 changes: 4 additions & 0 deletions lib/src/parser/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ impl StLexerBuilder {
}

impl<'input> StLexer<'input> {
fn eof(&mut self) -> bool {
self.buffer.eof()
}

fn parse_number(&mut self, mut tok: Token, ch: char) -> Option<LexerResult> {
self.buffer.consume1();

Expand Down
12 changes: 8 additions & 4 deletions lib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ impl From<lalrpop_util::ParseError<usize, TokenKind, LexicalError>> for ParseErr
}
}

pub struct Parser<T: ParserTrait> {
pub struct Parser<'a, T: ParserTrait> {
inner: T,
lexer: Option<StLexer<'a>>,
}

impl<T: ParserTrait> Parser<T> {
impl<T: ParserTrait> Parser<'_, T> {
#[inline]
pub fn parse(&self, mut lexer: StLexer) -> Result<Declaration, ParseError> {
self.inner.parse_decl(&mut lexer)
Expand Down Expand Up @@ -94,16 +95,18 @@ pub struct ParserBuilder {}

impl ParserBuilder {
#[cfg(feature = "lalrpop_parser")]
pub fn build(self) -> Parser<LalrpopParser> {
pub fn build(self) -> Parser<'static, LalrpopParser> {
Parser {
inner: LalrpopParser::new(),
lexer: None,
}
}

#[cfg(not(feature = "lalrpop_parser"))]
pub fn build(self) -> Parser<DefaultParser> {
pub fn build(self) -> Parser<'static, DefaultParser> {
Parser {
inner: DefaultParser::new(),
lexer: None,
}
}
}
Expand All @@ -112,6 +115,7 @@ pub trait ParserTrait {
fn parse_decl(&self, lexer: &mut StLexer) -> Result<Declaration, ParseError>;
fn parse_stmt(&self, lexer: &mut StLexer) -> Result<Statement, ParseError>;
fn parse_literal(&self, lexer: &mut StLexer) -> Result<LiteralExpression, ParseError>;
fn parse_expression(&self, lexer: &mut StLexer) -> Result<Expression, ParseError>;
}

#[cfg(feature = "lalrpop_parser")]
Expand Down
8 changes: 8 additions & 0 deletions lib/src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ fn test_body_parse() {
}
}

#[test]
fn test_literal_parse() {
let parser = parser::ParserBuilder::default().build();

let literal = parser.parse_literal_from_str("1");
assert!(literal.is_ok());
}

#[test]
fn test_scope_lookup() {
let mgr = UnitsManager::new();
Expand Down

0 comments on commit 022cb50

Please sign in to comment.