#lang racket/base (require racket/contract/base) (provide (contract-out [parser? predicate/c] [parse-datum (-> parser? (sequence/c token?) any/c)] [parse-syntax (-> parser? (sequence/c syntax-token?) syntax?)] [parse-ambiguous-datum (-> parser? (sequence/c token?) (set/c any/c))] [parse-ambiguous-syntax (-> parser? (sequence/c syntax-token?) (set/c syntax?))])) (module+ private (provide (contract-out [make-parser (-> #:deriver (-> (sequence/c token?) (stream/c parser-derivation?)) parser?)]))) (require racket/sequence racket/set racket/stream yaragg/base/token yaragg/base/derivation) ;@---------------------------------------------------------------------------------------------------- (struct parser (deriver)) (define (make-parser #:deriver deriver) (parser deriver)) (define (parse-ambiguous-syntax p tokens) (for/set ([derivation (in-stream ((parser-deriver p) tokens))]) (parser-derivation->syntax derivation))) (define (parse-ambiguous-datum p tokens) (for/set ([derivation (in-stream ((parser-deriver p) tokens))]) (parser-derivation->datum derivation))) (define (parse-syntax p token-sequence) (define tokens (for/vector ([t token-sequence]) (token (syntax-token-type t) t))) (define derivations ((parser-deriver p) tokens)) (when (stream-empty? derivations) (raise-arguments-error 'parse-syntax "no parse trees produced" "parser" p "tokens" tokens)) (define stx (parser-derivation->syntax (stream-first derivations))) (unless (stream-empty? (stream-rest derivations)) (raise-arguments-error 'parse-syntax "ambiguous parse, multiple parse trees produced" "parser" p "tokens" tokens "first parse tree" stx "second parse tree" (parser-derivation->syntax (stream-first (stream-rest derivations))))) stx) (define (parse-datum p tokens) (define derivations ((parser-deriver p) tokens)) (when (stream-empty? derivations) (raise-arguments-error 'parse-datum "no parse trees produced" "parser" p "tokens" tokens)) (define datum (parser-derivation->datum (stream-first derivations))) (unless (stream-empty? (stream-rest derivations)) (raise-arguments-error 'parse-datum "ambiguous parse, multiple parse trees produced" "parser" p "tokens" tokens "first parse tree" datum "second parse tree" (parser-derivation->datum (stream-first (stream-rest derivations))))) datum)