/** * @file Tree-sitter grammar definition for XML * @author ObserverOfTime * @license MIT */ /// // @ts-check import * as c from '../common/common.mjs'; const O = optional; export default grammar({ name: 'xml', externals: $ => [ // DTD $.PITarget, $._pi_content, $.Comment, // XML $.CharData, $.CData, 'xml-model', 'xml-stylesheet', $._start_tag_name, $._end_tag_name, $._erroneous_end_name, '/>', ], extras: _ => [], supertypes: $ => [ $._markupdecl, $._AttType, $._EnumeratedType, $._EntityDecl, $._Reference, ], conflicts: $ => [ [$.AttlistDecl, $.AttDef] ], word: $ => $.Name, rules: { document: $ => prec(2, seq( O($._S), O($.prolog), field('root', $.element), repeat($._Misc), )), prolog: $ => choice( seq( $.XMLDecl, repeat($._Misc), ), seq( O($.XMLDecl), repeat($._Misc), $.doctypedecl, repeat($._Misc), ), repeat1($._Misc) ), _Misc: $ => choice( $.PI, $.StyleSheetPI, $.XmlModelPI, $.Comment, $._S ), XMLDecl: $ => seq( '' ), _SDDecl: $ => seq( $._S, 'standalone', $._Eq, c.str(choice('yes', 'no')) ), doctypedecl: $ => seq( '' ), _intSubset: $ => c.rseq1( O($._S), $._markupdecl, $._DeclSep ), element: $ => choice( $.EmptyElemTag, seq($.STag, O($.content), $.ETag) ), EmptyElemTag: $ => seq( '<', alias($._start_tag_name, $.Name), c.rseq($._S, $.Attribute), O($._S), '/>' ), Attribute: $ => seq($.Name, $._Eq, $.AttValue), STag: $ => seq( '<', alias($._start_tag_name, $.Name), c.rseq($._S, $.Attribute), O($._S), '>' ), ETag: $ => seq(''), _ErroneousETag: $ => seq( '', ), content: $ => repeat1( choice( $.CharData, $.element, $._Reference, $.CDSect, $.PI, $.Comment ) ), CDSect: $ => prec.left( seq($.CDStart, optional($.CData), ']]>') ), CDStart: _ => seq(' seq( '' ), XmlModelPI: $ => seq( '' ), PseudoAtt: $ => seq($.Name, $._Eq, $.PseudoAttValue), PseudoAttValue: $ => choice( c.att_value($, '"'), c.att_value($, "'") ), ...c.rules } });