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]]
|
[[bin]]
|
||||||
name = "ast"
|
name = "ast"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "json"
|
||||||
|
|
|
@ -361,7 +361,7 @@ ast_gen! {
|
||||||
fn main() {
|
fn main() {
|
||||||
let code = String::from(
|
let code = String::from(
|
||||||
r#"
|
r#"
|
||||||
a: int = 5;
|
a: int = 1 + 2 * 3 + 4;
|
||||||
b: fun int (a:int) = { b: int = a; return a; }
|
b: fun int (a:int) = { b: int = a; return a; }
|
||||||
c: arr[5] arr[5] int = 5;
|
c: arr[5] arr[5] int = 5;
|
||||||
"#,
|
"#,
|
||||||
|
|
|
@ -79,8 +79,14 @@ fn main() {
|
||||||
println!("automaton: {:?}", grammar.lr1_automaton);
|
println!("automaton: {:?}", grammar.lr1_automaton);
|
||||||
println!("conflict: {}", grammar.gen_slr_parse_table());
|
println!("conflict: {}", grammar.gen_slr_parse_table());
|
||||||
println!("conflict: {}", grammar.gen_lr1_parse_table());
|
println!("conflict: {}", grammar.gen_lr1_parse_table());
|
||||||
println!("parse_table: {:?}", grammar.slr_parse_table.as_ref().unwrap().0.len());
|
println!(
|
||||||
println!("parse_table: {:?}", grammar.lr1_automaton.as_ref().unwrap().0.len());
|
"parse_table: {:?}",
|
||||||
|
grammar.slr_parse_table.as_ref().unwrap().0.len()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"parse_table: {:?}",
|
||||||
|
grammar.lr1_automaton.as_ref().unwrap().0.len()
|
||||||
|
);
|
||||||
println!(
|
println!(
|
||||||
"parsed: {:?}",
|
"parsed: {:?}",
|
||||||
grammar.slr_parser(&mut m.iter_mut()).parse()
|
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();
|
let mut map = HashMap::new();
|
||||||
$({
|
$({
|
||||||
if !map.contains_key(&$left) {
|
if !map.contains_key(&$left) {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
|
pub mod ast_gen;
|
||||||
pub mod cfg;
|
pub mod cfg;
|
||||||
pub mod double_enum;
|
pub mod double_enum;
|
||||||
pub mod scanner;
|
pub mod scanner;
|
||||||
pub mod ast_gen;
|
|
||||||
|
|
||||||
pub mod prelude {
|
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::ll_grammar::*;
|
||||||
pub use crate::cfg::lr0_grammar::*;
|
pub use crate::cfg::lr0_grammar::*;
|
||||||
pub use crate::cfg::lr1_grammar::*;
|
pub use crate::cfg::lr1_grammar::*;
|
||||||
pub use crate::cfg::lr_parser::*;
|
pub use crate::cfg::lr_parser::*;
|
||||||
pub use crate::ast_gen::*;
|
pub use crate::cfg::*;
|
||||||
pub use crate::ast_gen;
|
|
||||||
pub use crate::cfg_grammar;
|
pub use crate::cfg_grammar;
|
||||||
pub use crate::double_enum;
|
pub use crate::double_enum;
|
||||||
pub use crate::scanner::*;
|
pub use crate::scanner::*;
|
||||||
|
|
|
@ -185,7 +185,6 @@ fn grammer() -> Grammar<NoneTerminals, BareTokens> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let code = String::from(
|
let code = String::from(
|
||||||
"a = 4; while a != 5 { a = (a+1) * 4; }; if a == 5 { a = \"abs123\"; } else {a = 5;}",
|
"a = 4; while a != 5 { a = (a+1) * 4; }; if a == 5 { a = \"abs123\"; } else {a = 5;}",
|
||||||
|
|
Loading…
Reference in a new issue