json
This commit is contained in:
parent
4e5905b6fd
commit
31cf3b0e08
7 changed files with 159 additions and 9 deletions
|
@ -19,3 +19,6 @@ name = "g10"
|
|||
|
||||
[[bin]]
|
||||
name = "ast"
|
||||
|
||||
[[bin]]
|
||||
name = "json"
|
||||
|
|
|
@ -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;
|
||||
"#,
|
||||
|
|
|
@ -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
141
src/bin/json.rs
Normal 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:?}");
|
||||
}
|
|
@ -24,6 +24,7 @@ macro_rules! cfg_grammar {
|
|||
);* $(;)?
|
||||
) => {
|
||||
{
|
||||
use std::collections::HashMap;
|
||||
let mut map = HashMap::new();
|
||||
$({
|
||||
if !map.contains_key(&$left) {
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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;}",
|
||||
|
|
Loading…
Reference in a new issue