Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
acweathersby committed Dec 4, 2024
1 parent d8b653b commit 2867785
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 111 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/cli/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,5 @@ fn test_radlr_bytecode_bootstrap() -> RadlrResult<()> {

radlr_build::fs_build(build_config, parser_config, radlr_build::TargetLanguage::Rust)
}


5 changes: 3 additions & 2 deletions crates/radlr-ascript/build_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ pub fn build_database(db: RadlrGrammarDatabase) -> AscriptDatabase {

finalize_structs(&mut adb, &nonterm_types);

resolve_struct_definitions(&mut adb);

resolve_multi_types(&mut adb);

resolve_struct_definitions(&mut adb);

if let Err(err) = collect_types(&mut adb) {
adb.errors.push(RadlrError::Text(err));
}
Expand Down Expand Up @@ -145,6 +145,7 @@ fn resolve_struct_definitions(adb: &mut AscriptDatabase) {

for (_, prop) in strct.properties.iter() {
let mut structs = vec![];

for dependent_stct_id in prop.ty.get_structs(&mut structs, &adb.multi_types) {
let entry = dependency_lookup.entry(*dependent_stct_id).or_default();
entry.insert(*strct_id);
Expand Down
27 changes: 27 additions & 0 deletions crates/radlr-ascript/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,33 @@ fn aliased_struct_properties_are_tracked() -> RadlrResult<()> {
Ok(())
}

#[test]
fn test_temp() -> RadlrResult<()> {
let source = r##"
IGNORE { c:sp }
<> goal > fn | strct
<> fn > tk:(c:id+) "(" ")" ":" :ast { t_FN }
<> strct > tk:(c:id+) "{" "}" :ast { t_FN }
"##;

let db = RadlrGrammar::new().add_source_from_string(source, "", false)?.build_db("", Default::default())?;

let mut adb: AscriptDatabase = db.into();

assert_eq!(adb.structs.len(), 1);

let (_, strct) = adb.structs.pop_first().expect("should have that one struct here");

assert_eq!(strct.properties.len(), 2);

dbg!(strct);

Ok(())
}

#[test]
fn builds_rum_lang() -> RadlrResult<()> {
let source = r##"
Expand Down
2 changes: 2 additions & 0 deletions crates/radlr-build/targets/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,5 @@ pub fn build(db: &RadlrGrammarDatabase, build_config: BuildConfig, parser_config

Ok(())
}


9 changes: 7 additions & 2 deletions crates/radlr-rust-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ edition = "2021"
path = "./lib.rs"

[features]
wasm-lab = ["wasm-bindgen"]
wasm-lab = ["wasm-bindgen", "web-sys"]

[dependencies.wasm-bindgen]
optional = true
version = "0.2.87"
version = "0.2.87"

[dependencies.web-sys]
optional = true
version = "0.3.64"
features = [ 'console' ]
1 change: 0 additions & 1 deletion crates/radlr-rust-runtime/fuzz/mod.rs

This file was deleted.

60 changes: 37 additions & 23 deletions crates/radlr-rust-runtime/kernel/parser_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn dispatch<'a, 'debug>(
},
} {
OpResult { action: None, next: Option::None, .. } => {
unreachable!("Expected next instruction!")
todo!("Expected next instruction!")
}

OpResult { action: None, next: Some(next_instruction), is_goto, can_debug } => {
Expand Down Expand Up @@ -571,7 +571,7 @@ fn get_hash_result<'a>(
}
}

pub fn get_success_branches<'a>(i: Instruction<'a>) -> Vec<(MatchInputType, u32, u32)> {
pub fn get_success_branches<'a>(i: Instruction<'a>) -> Vec<SuccessorState> {
// if yield success branch actions.

let opcode = i.get_opcode();
Expand All @@ -588,21 +588,45 @@ pub fn get_success_branches<'a>(i: Instruction<'a>) -> Vec<(MatchInputType, u32,
let cell = iter.next_u32_le().unwrap();
let off = (cell >> 11) & 0x7FF;
let value = cell & 0x7FF;
let address = off as usize + i.address();
addresses.push((input_type, value, address as u32));
let address = off as u32 + i.address() as u32;
let next: Instruction<'_> = (i.bytecode(), address as usize).into();
addresses.push(SuccessorState {
edge_mode: input_type,
edge_value: value,
skipped: next.get_opcode() == Opcode::SkipToken,
state_info: StateInfo {
stack_address: 0,
state_type: StateType::Normal,
is_state_entry: false,
state_id: address,
},
});
}

addresses
}
Opcode::VectorBranch => {
let TableHeaderData { table_start, table_length, .. } = i.into();
let TableHeaderData { table_start, table_length, input_type, table_meta, .. } = i.into();

let mut iter: ByteCodeIterator = (i.bytecode(), table_start).into();

for _ in 0..table_length {
for val_offset in 0..table_length {
let address_offset = iter.next_u32_le().unwrap();
let address = address_offset as usize + i.address();
//addresses.insert(address as u32);

let address = address_offset as u32 + i.address() as u32;
let next: Instruction<'_> = (i.bytecode(), address as usize).into();

addresses.push(SuccessorState {
edge_mode: input_type,
edge_value: table_meta + val_offset as u32,
skipped: next.get_opcode() == Opcode::SkipToken,
state_info: StateInfo {
stack_address: 0,
state_type: StateType::Normal,
is_state_entry: false,
state_id: address,
},
});
}

addresses
Expand All @@ -629,15 +653,15 @@ pub fn get_token_id<'a>(i: Instruction<'a>, ctx: &mut ParserContext, input: &imp
if input_type == MatchInputType::Token {
let (input_value, is_nl) = get_input_value(input_type, scan_block_instruction, ctx, input, &mut None, false);

let next = match opcode {
let branch = match opcode {
Opcode::HashBranch => get_hash_result(input_value, table_meta, i, table_start, is_nl, ctx, default_block),
Opcode::VectorBranch => {
vector_input_match(input_value, table_meta, table_length, is_nl, ctx, i, table_start, default_block)
}
_ => unreachable!(),
_ => todo!(),
};

if next.next.unwrap().get_opcode() == Opcode::SkipToken {
if branch.next.unwrap().get_opcode() == Opcode::SkipToken {
(input_value, true)
} else {
(input_value, false)
Expand Down Expand Up @@ -815,7 +839,7 @@ fn get_input_value<'a, 'debug>(
ctx.byte_len = len as u32;
cp
}
i_type => unreachable!("{}", i_type),
i_type => todo!("{}", i_type),
}
}
};
Expand Down Expand Up @@ -932,18 +956,8 @@ impl ParserInitializer for ByteCodeParserNew {
}

impl<T: ParserInput> ParserIterator<T> for ByteCodeParserNew {
fn get_success_states<'ctx>(&mut self, address: StateInfo) -> Vec<(MatchInputType, u32, StateInfo)> {
fn get_success_states<'ctx>(&mut self, address: StateInfo) -> Vec<SuccessorState> {
get_success_branches(Instruction::from((self.bc.as_ref().as_ref(), address.state_id as usize)))
.into_iter()
.map(|(ty, val, address)| {
(ty, val, StateInfo {
stack_address: 0,
state_type: StateType::Normal,
is_state_entry: false,
state_id: address,
})
})
.collect()
}

fn get_token_id<'ctx>(&mut self, address: StateInfo, input: &mut T, ctx: &mut ParserContext) -> (u32, bool) {
Expand Down
13 changes: 12 additions & 1 deletion crates/radlr-rust-runtime/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,19 @@
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
/// IN THE SOFTWARE.
pub mod deprecate;
pub mod fuzz;
pub mod kernel;
pub mod parsers;
pub mod types;
pub mod utf8;

#[macro_export]
macro_rules! panic_with_string {
($data:expr ) => {{
let string = format!("{} at {}:{}", $data, file!(), line!());
#[cfg(feature = "wasm-lab")]
unsafe {
web_sys::console::debug_1(&wasm_bindgen::JsValue::from(&string))
};
panic!("{string}");
}};
}
36 changes: 22 additions & 14 deletions crates/radlr-rust-runtime/parsers/error_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bytecode::Instruction;

use crate::{
kernel::is_token_state,
panic_with_string,
parsers::fork::{fork_meta_kernel, CHAR_USAGE_SCORE},
types::*,
};
Expand Down Expand Up @@ -132,7 +133,7 @@ fn handle_failed_contexts<I: ParserInput, DB: ParserProducer<I>>(
// following that state off the stack and then resume
// parsing from the recovery state.
}
_ => unimplemented!(),
_ => {}
}
}

Expand Down Expand Up @@ -211,7 +212,7 @@ fn resolve_errored_contexts<I: ParserInput>(

rec_ctx.mode = RecoveryMode::Normal;
}
_ => unreachable!(),
mode => panic_with_string!(format!("Invalid recovery mode {mode:?}")),
}
to_continue.push(rec_ctx);
}
Expand Down Expand Up @@ -239,10 +240,10 @@ fn resolve_errored_contexts<I: ParserInput>(
RecoveryMode::SymbolDiscard { count, end_offset, .. } => {
drop_symbols(&rec_ctx, contexts, &mut best_failure, count, end_offset);
}
_ => unreachable!(),
mode => panic_with_string!(format!("Invalid recovery mode {mode:?}")),
},

_ => unreachable!(),
action => panic_with_string!(format!("Invalid parse action: {action:?}")),
}
}
}
Expand Down Expand Up @@ -271,29 +272,38 @@ fn inject_synthetics<I: ParserInput>(
) {
// Increment through states until we are able to get to a nonterminal

dbg!((rec_ctx.last_failed_state.address, rec_ctx.failed_state.address, last_state.address));
if rec_ctx.last_failed_state.address == last_state.address {
return;
}

let mut continue_contexts = VecDeque::new();

for (ty, val, state) in parser.get_success_states(last_state.info) {
for SuccessorState { edge_mode, edge_value, skipped, state_info } in parser.get_success_states(last_state.info) {
if skipped {
continue;
}

let mut ctx = rec_ctx.split();
ctx.ctx.push_state(ParserState { info: state, address: state.state_id as usize });
ctx.ctx.push_state(ParserState { info: state_info, address: state_info.state_id as usize });

let mut create_synthetic = false;

ctx.ctx.byte_len = 0;
ctx.ctx.tok_byte_len = 0;
ctx.last_failed_state = rec_ctx.failed_state;

match ty {
match edge_mode {
bytecode::MatchInputType::Token => {
ctx.ctx.recovery_tok_id = val;
ctx.ctx.recovery_tok_id = edge_value;
}
bytecode::MatchInputType::NonTerminal => {
create_synthetic = true;
}
ty => unreachable!("{ty}"),
bytecode::MatchInputType::ByteScanless => {
continue;
}
ty => panic_with_string!(format!("Unrecognized bytecode match type: {ty:?}")),
}

continue_contexts.push_back((false, create_synthetic, ctx));
Expand All @@ -303,8 +313,6 @@ fn inject_synthetics<I: ParserInput>(
if let Some(action) = parser.next(input, &mut ctx.ctx) {
match action {
ParseAction::Reduce { nonterminal_id, rule_id, symbol_count } => {
// panic!("action nonterminal_id: {nonterminal_id}");

ctx.ctx.recovery_tok_id = 0;
ctx.mode = RecoveryMode::Normal;

Expand Down Expand Up @@ -445,7 +453,7 @@ fn drop_symbols(
NodeType::Token => {
rec_ctx.entropy += tok.entropy() as isize * CHAR_USAGE_SCORE;
}
_ => unreachable!(),
_ => {}
}

rec_ctx.mode = RecoveryMode::SymbolDiscard { count, end_offset, start_offset };
Expand Down Expand Up @@ -473,7 +481,7 @@ fn drop_symbols(

break;
}
_ => unreachable!(),
node_ty => panic_with_string!(format!("Todo: handle node type {node_ty:?} in drop_symbols")),
}
}
CSTNode::PlaceholderNonTerm(..) | CSTNode::NonTerm(..) | CSTNode::Alts(..) => {
Expand All @@ -491,7 +499,7 @@ fn drop_symbols(
NodeType::Skipped | NodeType::Token => {
entropy_delta += tok.entropy() as isize * CHAR_USAGE_SCORE;
}
_ => unreachable!(),
node_ty => panic_with_string!(format!("Todo: handle node type {node_ty:?} in drop_symbols")),
},
CSTNode::PlaceholderNonTerm(node) => entropy_delta += 1,
CSTNode::NonTerm(node) => queue.extend(node.symbols.iter().cloned()),
Expand Down
10 changes: 9 additions & 1 deletion crates/radlr-rust-runtime/types/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,22 @@ pub trait ParserInitializer {
fn set_debugger(&mut self, debugger: Option<Box<DebugFnNew>>);
}

#[derive(Clone, Copy)]
pub struct SuccessorState {
pub edge_mode: MatchInputType,
pub edge_value: u32,
pub skipped: bool,
pub state_info: StateInfo,
}

pub trait ParserIterator<T: ParserInput> {
/// Given a parse context, returns the next ParseAction for that context,
/// mutating the context as needed.
///
/// Returns None if the context has already entered a finished state
fn next<'ctx>(&mut self, input: &mut T, context: &'ctx mut ParserContext) -> Option<ParseAction>;

fn get_success_states<'ctx>(&mut self, address: StateInfo) -> Vec<(MatchInputType, u32, StateInfo)> {
fn get_success_states<'ctx>(&mut self, address: StateInfo) -> Vec<SuccessorState> {
vec![]
}

Expand Down
Loading

0 comments on commit 2867785

Please sign in to comment.