@@ -539,6 +539,17 @@ impl<'a> GrammarParser<'a> {
539539 self . expect_char ( '{' ) ?;
540540 self . skip_ws_and_comments ( ) ;
541541
542+ // Check if this is legacy JSON syntax (starts with quoted string key)
543+ if self . peek_char ( ) == Some ( '"' ) {
544+ // Legacy JSON action - capture everything until matching closing brace
545+ let json_content = self . parse_json_block_content ( ) ?;
546+ self . expect_char ( '}' ) ?;
547+ return Ok ( ( ActionIR :: LegacyJson {
548+ return_type : return_type. clone ( ) ,
549+ json_content,
550+ } , return_type) ) ;
551+ }
552+
542553 let mut fields = Vec :: new ( ) ;
543554
544555 while self . peek_char ( ) != Some ( '}' ) {
@@ -565,6 +576,60 @@ impl<'a> GrammarParser<'a> {
565576 } , return_type) )
566577 }
567578
579+ /// Parse the content of a JSON action block (legacy format)
580+ /// This captures everything between { and the matching }
581+ fn parse_json_block_content ( & mut self ) -> ParseResult < String > {
582+ let start = self . pos ;
583+ let mut depth = 0 ;
584+
585+ loop {
586+ match self . peek_char ( ) {
587+ Some ( '{' ) => {
588+ depth += 1 ;
589+ self . advance ( ) ;
590+ }
591+ Some ( '}' ) => {
592+ if depth == 0 {
593+ // Found the closing brace of the outer block
594+ let content = self . input [ start..self . pos ] . to_string ( ) ;
595+ return Ok ( content) ;
596+ }
597+ depth -= 1 ;
598+ self . advance ( ) ;
599+ }
600+ Some ( '"' ) => {
601+ // Skip string literals (they might contain braces)
602+ self . advance ( ) ;
603+ while let Some ( c) = self . peek_char ( ) {
604+ if c == '"' {
605+ self . advance ( ) ;
606+ break ;
607+ }
608+ if c == '\\' {
609+ self . advance ( ) ;
610+ self . advance ( ) ; // Skip escaped char
611+ } else {
612+ self . advance ( ) ;
613+ }
614+ }
615+ }
616+ Some ( '[' ) => {
617+ // Array - just advance
618+ self . advance ( ) ;
619+ }
620+ Some ( ']' ) => {
621+ self . advance ( ) ;
622+ }
623+ Some ( _) => {
624+ self . advance ( ) ;
625+ }
626+ None => {
627+ return Err ( self . error ( "Unexpected EOF in JSON block" ) ) ;
628+ }
629+ }
630+ }
631+ }
632+
568633 /// Parse a type path like TypedExpression::Binary
569634 fn parse_type_path ( & mut self ) -> ParseResult < String > {
570635 let mut path = self . parse_identifier ( ) ?;
@@ -1041,9 +1106,9 @@ impl<'a> GrammarParser<'a> {
10411106
10421107 // Rest is identifier-like or operator chars
10431108 if name. starts_with ( '$' ) {
1044- // Operator: can include things like *, +, etc.
1109+ // Operator: can include things like *, +, @, etc.
10451110 while let Some ( c) = self . peek_char ( ) {
1046- if c. is_ascii_alphanumeric ( ) || "*+-/<>=!" . contains ( c) {
1111+ if c. is_ascii_alphanumeric ( ) || "*+-/<>=!@%^&| " . contains ( c) {
10471112 name. push ( c) ;
10481113 self . advance ( ) ;
10491114 } else {
@@ -1390,4 +1455,69 @@ mod tests {
13901455 _ => panic ! ( "Expected Repeat pattern" ) ,
13911456 }
13921457 }
1458+
1459+ #[ test]
1460+ fn test_parse_imagepipe_grammar ( ) {
1461+ let input = include_str ! ( "../../../../examples/imagepipe/imagepipe.zyn" ) ;
1462+
1463+ match parse_grammar ( input) {
1464+ Ok ( grammar) => {
1465+ println ! ( "Successfully parsed ImagePipe grammar!" ) ;
1466+ println ! ( "Language: {} v{}" , grammar. metadata. name, grammar. metadata. version) ;
1467+ println ! ( "Rules: {}" , grammar. rules. len( ) ) ;
1468+ for ( name, _rule) in & grammar. rules {
1469+ println ! ( " - {}" , name) ;
1470+ }
1471+
1472+ // Verify key metadata
1473+ assert_eq ! ( grammar. metadata. name, "ImagePipe" ) ;
1474+ assert_eq ! ( grammar. metadata. version, "1.0" ) ;
1475+
1476+ // Verify key rules exist
1477+ assert ! ( grammar. rules. contains_key( "program" ) ) ;
1478+ assert ! ( grammar. rules. contains_key( "statement" ) ) ;
1479+ assert ! ( grammar. rules. contains_key( "load_stmt" ) ) ;
1480+ assert ! ( grammar. rules. contains_key( "save_stmt" ) ) ;
1481+ assert ! ( grammar. rules. contains_key( "identifier" ) ) ;
1482+ }
1483+ Err ( e) => {
1484+ panic ! ( "Failed to parse ImagePipe grammar: {:?}" , e) ;
1485+ }
1486+ }
1487+ }
1488+
1489+ #[ test]
1490+ fn test_parse_zynml_grammar ( ) {
1491+ let input = include_str ! ( "../../../zynml/ml.zyn" ) ;
1492+
1493+ match parse_grammar ( input) {
1494+ Ok ( grammar) => {
1495+ println ! ( "Successfully parsed ZynML grammar!" ) ;
1496+ println ! ( "Language: {} v{}" , grammar. metadata. name, grammar. metadata. version) ;
1497+ println ! ( "Rules: {}" , grammar. rules. len( ) ) ;
1498+
1499+ // Verify key metadata
1500+ assert_eq ! ( grammar. metadata. name, "ZynML" ) ;
1501+ assert_eq ! ( grammar. metadata. version, "1.0" ) ;
1502+
1503+ // Verify key rules exist
1504+ assert ! ( grammar. rules. contains_key( "program" ) ) ;
1505+ assert ! ( grammar. rules. contains_key( "fn_def" ) ) ;
1506+ assert ! ( grammar. rules. contains_key( "expr" ) ) ;
1507+ assert ! ( grammar. rules. contains_key( "statement" ) ) ;
1508+ assert ! ( grammar. rules. contains_key( "identifier" ) ) ;
1509+
1510+ // Print a few rule names
1511+ let mut rule_names: Vec < _ > = grammar. rules . keys ( ) . collect ( ) ;
1512+ rule_names. sort ( ) ;
1513+ println ! ( "Sample rules:" ) ;
1514+ for name in rule_names. iter ( ) . take ( 20 ) {
1515+ println ! ( " - {}" , name) ;
1516+ }
1517+ }
1518+ Err ( e) => {
1519+ panic ! ( "Failed to parse ZynML grammar: {:?}" , e) ;
1520+ }
1521+ }
1522+ }
13931523}
0 commit comments