Implement native LSL parser runtime (#82)
Some checks failed
Native code generation / deterministic (push) Failing after 11m53s
Native Rust workspace compile / compile (push) Failing after 1m57s

This commit is contained in:
2026-08-11 02:45:31 +00:00
parent 73cef10054
commit 656d837778
11 changed files with 4008 additions and 1200 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -543,7 +543,7 @@ impl LineManager {
}
/// Source location compatible with `SourceLineInfo`.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub struct SourceLineInfo {
pub char_position: i32,
pub end_of_line: i32,
@@ -638,7 +638,10 @@ pub enum DiagnosticCategory {
Encoding,
InvalidCharacter,
InvalidState,
ParserRecovery,
ParserStackLimit,
Source,
Syntax,
TokenTooLong,
UnknownCharacterSet,
UnexpectedEof,
@@ -986,7 +989,7 @@ impl ErrorHandler {
std::mem::take(&mut self.diagnostics)
}
fn push(&mut self, diagnostic: Diagnostic) -> Result<(), Error> {
pub(crate) fn push(&mut self, diagnostic: Diagnostic) -> Result<(), Error> {
self.counter = self.counter.checked_add(1).ok_or(Error::IndexOutOfRange)?;
if self.throw_exceptions {
return Err(Error::InvalidOperation);
@@ -2007,6 +2010,24 @@ pub struct SYMBOL {
pub pos_with_field: i32,
pub yylx: Option<Box<Lexer>>,
pub yyps: Option<Box<Parser>>,
name: String,
number: i32,
text: String,
}
impl Clone for SYMBOL {
fn clone(&self) -> Self {
Self {
kids: self.kids.clone(),
m_dollar: self.m_dollar.clone(),
pos_with_field: self.pos_with_field,
yylx: self.yylx.clone(),
yyps: self.yyps.clone(),
name: self.name.clone(),
number: self.number,
text: self.text.clone(),
}
}
}
impl fmt::Debug for SYMBOL {
@@ -2018,6 +2039,9 @@ impl fmt::Debug for SYMBOL {
.field("pos", &self.pos_with_field)
.field("has_lexer", &self.yylx.is_some())
.field("has_parser", &self.yyps.is_some())
.field("name", &self.name)
.field("number", &self.number)
.field("text", &self.text)
.finish()
}
}
@@ -2030,6 +2054,9 @@ impl SYMBOL {
pos_with_field: lexer.yypos(),
yylx: Some(Box::new(lexer)),
yyps: None,
name: "SYMBOL".to_owned(),
number: 0,
text: String::new(),
})
}
@@ -2040,9 +2067,32 @@ impl SYMBOL {
pos_with_field: 0,
yylx: None,
yyps: Some(Box::new(parser)),
name: "SYMBOL".to_owned(),
number: 0,
text: String::new(),
})
}
pub(crate) fn parser_symbol(
name: String,
number: i32,
text: String,
pos: i32,
value: Object,
kids: ObjectList,
) -> Self {
Self {
kids,
m_dollar: value,
pos_with_field: pos,
yylx: None,
yyps: None,
name,
number,
text,
}
}
fn location(&self) -> Result<SourceLineInfo, Error> {
self.yylx
.as_deref()
@@ -2074,8 +2124,8 @@ impl SYMBOL {
pub fn is_terminal(&self) -> Result<bool, Error> {
Ok(false)
}
pub fn matches(&self, _value: String) -> Result<bool, Error> {
Ok(false)
pub fn matches(&self, value: String) -> Result<bool, Error> {
Ok(self.text == value)
}
pub fn pass_(
@@ -2093,7 +2143,11 @@ impl SYMBOL {
}
#[must_use]
pub fn to_string(&self) -> String {
self.yyname()
if self.text.is_empty() {
self.yyname()
} else {
format!("{}<{}>", self.yyname(), self.text)
}
}
pub fn from(symbol: SYMBOL) -> i32 {
@@ -2133,11 +2187,11 @@ impl SYMBOL {
}
#[must_use]
pub fn yyname(&self) -> String {
"SYMBOL".to_owned()
self.name.clone()
}
#[must_use]
pub const fn yynum(&self) -> i32 {
0
self.number
}
}
@@ -2297,6 +2351,10 @@ fn lookup_parser_entry(
state: i32,
entry: &mut ParserEntry,
) -> Result<bool, Error> {
if let Some(native) = symbols.lookup_entry(number, state)? {
*entry = native;
return Ok(true);
}
let Some(info) = symbols.symbol_info.0.get(&Object::Integer(number)) else {
return Err(Error::Parse {
position: 0,
@@ -2392,7 +2450,7 @@ impl Null {
}
/// Rust replacement for the C# cons-list, backed by contiguous storage.
#[derive(Debug, Default)]
#[derive(Clone, Debug, Default)]
pub struct ObjectList {
values: VecDeque<Object>,
count_override: Option<i32>,

View File

@@ -4,6 +4,7 @@ extern crate self as libremetaverse_lsl_tools;
mod generated;
mod lexer;
mod parser;
pub use generated::*;
pub use lexer::{
@@ -12,3 +13,7 @@ pub use lexer::{
MAX_TOKEN_UNITS, TokenDefinition, UnicodeClass,
};
pub use libremetaverse_types::Error;
pub use parser::{
Associativity, ERROR_TOKEN, Grammar, GrammarProduction, GrammarSymbol, MAX_PARSER_STACK,
MAX_PARSER_STATES, MAX_PARSER_STEPS, MAX_RECOVERY_ERRORS, ParseTree, ParserConflict,
};

File diff suppressed because it is too large Load Diff