basic_usage/
basic_usage.rs

1use gf_core::*;
2use std::fs;
3use bytes::Bytes;
4
5/*
6This program will:
7  1. Loads the Food.pgf grammar file from grammars/Food/
8  2. Parses it and converts it to JSON
9  3. Creates a GFGrammar from the JSON
10  4. Parses "this fish is delicious" into an AST
11  5. Linearizes the AST back to English text
12  6. Shows available concrete grammars
13
14  You can enable debug output by uncommenting the set_debug(true) line below.
15  This will show detailed information about parsing, linearization, and translation.
16*/
17
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19    // Uncomment the line below to see debug output from GF-Core operations
20    set_debug(true);
21    
22    // Load a PGF grammar from binary file and convert to JSON
23    println!("LOG: Reading binary PGF file from disk...");
24    let pgf_content = fs::read("grammars/Food/Food.pgf")?;
25    
26    println!("LOG: Attemp at parsing PGF file Food.pgf starting...");
27    let pgf = pgf2json::parse_pgf(&Bytes::from(pgf_content))?;
28    
29    println!("LOG: Attemp at transforming pgf data to json...");
30    let json_string = pgf2json::pgf_to_json(&pgf)?;
31    
32    println!("LOG: Result of parsing (json_string): {json_string}");
33    println!("TODO: Verify that json_string is json formated!");
34    
35    // Parse JSON string back into PGF struct for runtime usage
36    let json_value: serde_json::Value = serde_json::from_str(&json_string)?;
37    println!("TODO: Understand purpose of (json_value): {json_string}" );
38    
39    let pgf_struct: PGF = serde_json::from_value(json_value)?;
40    println!("TODO: Understand content of (pgf_struct): {:?}", pgf_struct);
41    
42    // Convert to runtime grammar
43    println!("TODO: Purpose of GFGrammar::from_json(pgf_struct)");
44    let grammar: GFGrammar = GFGrammar::from_json(pgf_struct);
45    
46    
47    // Test our fixed abstract syntax parsing
48    println!("LOG: Testing fixed abstract syntax parsing");
49    
50    let test_cases = [
51        "Fish",
52        "This(Fish)", 
53        "Is(This(Fish), Delicious)",
54        "MakeS (NP) (VP)",
55    ];
56    
57    for test_case in test_cases {
58        println!("\nTesting abstract syntax: '{}'", test_case);
59        match grammar.abstract_grammar.parse_tree(test_case, None) {
60            Some(tree) => {
61                println!("✓ Parsed successfully: {}", tree.print());
62                
63                // Try to linearize this tree
64                if let Some(eng_concrete) = grammar.concretes.get("FoodEng") {
65                    println!("LOG: Attempting linearization with FoodEng concrete grammar");
66                    let english_output = eng_concrete.linearize(&tree);
67                    println!("  English: '{}'", english_output);
68                }
69            }
70            None => {
71                println!("✗ Failed to parse");
72            }
73        }
74    }
75    
76    // Also test the natural language parsing for comparison
77    println!("\n=== Natural Language Parsing (for comparison) ===");
78    if let Some(eng_concrete) = grammar.concretes.get("FoodEng") {
79        let trees = eng_concrete.parse_string("this fish is delicious", &grammar.abstract_grammar.startcat);
80        
81        if trees.is_empty() {
82            println!("No valid parse found for 'this fish is delicious'");
83        } else {
84            println!("Found {} parse tree(s):", trees.len());
85            for (i, tree) in trees.iter().enumerate() {
86                println!("  Tree {}: {}", i + 1, tree.print());
87                
88                // Linearize back to English
89                let english_output = eng_concrete.linearize(tree);
90                println!("  English: {}", english_output);
91            }
92        }
93    }
94
95    // Note: FoodIta concrete grammar not available in this PGF file
96    println!("Available concrete grammars: {:?}", grammar.concretes.keys().collect::<Vec<_>>());
97
98    Ok(())
99}