This commit is contained in:
jusax23 2024-11-14 11:55:23 +01:00
parent 4e5905b6fd
commit 31cf3b0e08
Signed by: jusax23
GPG key ID: 499E2AA870C1CD41
7 changed files with 159 additions and 9 deletions

View file

@ -19,3 +19,6 @@ name = "g10"
[[bin]]
name = "ast"
[[bin]]
name = "json"

View file

@ -361,7 +361,7 @@ ast_gen! {
fn main() {
let code = String::from(
r#"
a: int = 5;
a: int = 1 + 2 * 3 + 4;
b: fun int (a:int) = { b: int = a; return a; }
c: arr[5] arr[5] int = 5;
"#,

View file

@ -79,8 +79,14 @@ fn main() {
println!("automaton: {:?}", grammar.lr1_automaton);
println!("conflict: {}", grammar.gen_slr_parse_table());
println!("conflict: {}", grammar.gen_lr1_parse_table());
println!("parse_table: {:?}", grammar.slr_parse_table.as_ref().unwrap().0.len());
println!("parse_table: {:?}", grammar.lr1_automaton.as_ref().unwrap().0.len());
println!(
"parse_table: {:?}",
grammar.slr_parse_table.as_ref().unwrap().0.len()
);
println!(
"parse_table: {:?}",
grammar.lr1_automaton.as_ref().unwrap().0.len()
);
println!(
"parsed: {:?}",
grammar.slr_parser(&mut m.iter_mut()).parse()

141
src/bin/json.rs Normal file
View file

@ -0,0 +1,141 @@
use cfg::{Grammar, Sentential};
use rcompiler::*;
use regex::Match;
use scanner::Scanner;
double_enum!(BareTokens, Tokens {
WhiteSpace,
TokenString(String),
TokenObjectBegin,
TokenColon,
TokenComma,
TokenNumber(f64),
TokenTrue,
TokenFalse,
TokenNull,
TokenArrayBegin,
TokenArrayEnd,
TokenObjectEnd
});
token_scanner!(
Tokens,
r"^(\s|\t|\n|\r)" : |_,_| {
Some(WhiteSpace)
}
r"^\{" : |_,_|{
Some(TokenObjectBegin)
}
r"^\}" : |_,_|{
Some(TokenObjectEnd)
}
r"^\[" : |_,_|{
Some(TokenArrayBegin)
}
r"^\]" : |_,_|{
Some(TokenArrayEnd)
}
r#"^"(([^"\\\x00-\x1f]|\\(["\\/bfnrt]|(u[0-9a-f]{4})))*)""# : |capture: regex::Captures<'_>, _| {
capture.get(1).map(|m| TokenString(m.as_str().to_string()))
}
r"^-?([1-9][0-9]*|0)(\.[0-9]+)?([eE][-\+]?[0-9]+)?" : |_, m: Match<'_>| {
m.as_str().parse::<_>().ok().map(TokenNumber)
}
r"^," : |_,_|{
Some(TokenComma)
}
r"^:" : |_,_|{
Some(TokenColon)
}
r"^false" : |_,_|{
Some(TokenFalse)
}
r"^true" : |_,_|{
Some(TokenTrue)
}
r"^null" : |_,_|{
Some(TokenNull)
}
);
impl<N> From<NoneTerminals> for Sentential<NoneTerminals, N> {
fn from(value: NoneTerminals) -> Self {
Sentential::NoneTerminal(value)
}
}
impl<T> From<BareTokens> for Sentential<T, BareTokens> {
fn from(value: BareTokens) -> Self {
Sentential::Terminal(value)
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
enum NoneTerminals {
O,
Oi,
Oii,
A,
Ai,
Aii,
V,
}
fn grammer() -> Grammar<NoneTerminals, BareTokens> {
use BareTokens::*;
use NoneTerminals::*;
cfg_grammar![
start: V;
V -> TokenString;
V -> TokenNumber;
V -> O;
V -> A;
V -> TokenTrue;
V -> TokenFalse;
V -> TokenNull;
A -> TokenArrayBegin, Ai, TokenArrayEnd;
Ai -> V, Aii;
Aii -> TokenComma, V, Aii;
Aii -> ;
O -> TokenObjectBegin, Oi, TokenObjectEnd;
Oi -> TokenString, TokenColon, V, Oii;
Oii -> TokenComma, TokenString, TokenColon, V, Oii;
Oii -> ;
]
}
fn main() {
let json = r#"
{
"hello?": "Chinese Keyboard - 中文鍵盤/中文键盘 ",
"string": "abc\"d\u231ee\\f\/g\fh\ni\rj\tk",
"number": -123.12E+22,
"array": [
0,
1,
10,
-10,
-1E-34
],
"object": {
"1337": "187"
},
"true": true,
"false": false,
"null": null
}
"#;
let mut m = Scanner::<Tokens>::new(json.to_string()).with_skipping(Tokens::WhiteSpace);
let mut grammar = grammer();
let conflict_ll = grammar.gen_ll_parse_table();
let conflict_slr = grammar.gen_slr_parse_table();
let conflict_lr1 = grammar.gen_lr1_parse_table();
println!(
"is grammar: \n ll: {}, slr: {}, lr1: {}",
!conflict_ll, !conflict_slr, !conflict_lr1
);
let tree = grammar.ll_parser(&mut m.iter_mut()).parse();
println!("{tree:?}");
}

View file

@ -24,6 +24,7 @@ macro_rules! cfg_grammar {
);* $(;)?
) => {
{
use std::collections::HashMap;
let mut map = HashMap::new();
$({
if !map.contains_key(&$left) {

View file

@ -1,16 +1,16 @@
pub mod ast_gen;
pub mod cfg;
pub mod double_enum;
pub mod scanner;
pub mod ast_gen;
pub mod prelude {
pub use crate::cfg::*;
pub use crate::ast_gen;
pub use crate::ast_gen::*;
pub use crate::cfg::ll_grammar::*;
pub use crate::cfg::lr0_grammar::*;
pub use crate::cfg::lr1_grammar::*;
pub use crate::cfg::lr_parser::*;
pub use crate::ast_gen::*;
pub use crate::ast_gen;
pub use crate::cfg::*;
pub use crate::cfg_grammar;
pub use crate::double_enum;
pub use crate::scanner::*;

View file

@ -185,7 +185,6 @@ fn grammer() -> Grammar<NoneTerminals, BareTokens> {
]
}
fn main() {
let code = String::from(
"a = 4; while a != 5 { a = (a+1) * 4; }; if a == 5 { a = \"abs123\"; } else {a = 5;}",
@ -197,7 +196,7 @@ fn main() {
//println!("first: {:?}", grammar.first);
//println!("follow: {:?}", grammar.follow);
grammar.gen_lr1_automaton();
println!("conflict: {:?}", grammar.lr1_automaton);
println!("conflict: {:?}", grammar.lr1_automaton);
let conflict = grammar.gen_ll_parse_table();
println!("conflict: {conflict}");
println!("prase table: {:?}", grammar.ll_parse_table);