import { alphanum , char } from "parser-ts/lib/char" ; import { string , spaces1 , spaces , many1 as stringMany1 , doubleQuotedString , } from "parser-ts/lib/string" ; import { seq , map , Parser , apFirst , many , many1 , sat , either , eof , } from "parser-ts/lib/Parser" ; import { anyOf } from "./util" ; function isNonNewline ( char ) { return char !== "\n" ; } const spaceRe = /^\s$/ ; function isNonNewlineSpace ( char ) { return char !== "\n" && spaceRe . test ( char ) ; } const nonNewlineSpace = many ( sat ( isNonNewlineSpace ) ) ; const nonNewlineSpace1 = many1 ( sat ( isNonNewlineSpace ) ) ; const allowSpaceLeft = < T > ( parser ) => seq ( nonNewlineSpace , ( ) => parser ) ; const allowSpaceRight = < T > ( parser ) => apFirst ( nonNewlineSpace ) ( parser ) ; const allowSpaceAround = < T > ( parser ) => allowSpaceLeft ( allowSpaceRight ( parser ) ) ; const allowNewlineSpaceRight = < T > ( parser ) => apFirst ( spaces ) ( parser ) ; export type BasicToken < T > = { token : T ; } ; const parserForBasicToken = < T extends string > ( tokenName , parseStr = tokenName ) => { return map ( ( ) => { const token = { token : tokenName } ; return token ; } ) ( string ( parseStr ) ) ; } ; export type ImportToken = BasicToken < "import" > ; const importTokenParser = apFirst ( spaces1 ) ( parserForBasicToken < "import" > ( "import" ) ) ; export type FromToken = BasicToken < "from" > ; const fromTokenParser = apFirst ( spaces1 ) ( seq ( spaces1 , ( ) => parserForBasicToken < "from" > ( "from" ) ) ) ; export type QuotedStringToken = { token : "quotedString" ; contents : string ; } ; const quotedStringTokenParser = map ( ( str ) : QuotedStringToken => ( { token : "quotedString" , contents : str } ) ) ( doubleQuotedString ) ; export type StructToken = BasicToken < "struct" > ; const structTokenParser = apFirst ( nonNewlineSpace1 ) ( parserForBasicToken < "struct" > ( "struct" ) ) ; export type OneOfToken = BasicToken < "oneof" > ; const oneofTokenParser = apFirst ( nonNewlineSpace1 ) ( parserForBasicToken < "oneof" > ( "oneof" ) ) ; export type ServiceToken = BasicToken < "service" > ; const serviceTokenParser = apFirst ( nonNewlineSpace1 ) ( parserForBasicToken < "service" > ( "service" ) ) ; export type RPCToken = BasicToken < "rpc" > ; const rpcTokenParser = apFirst ( nonNewlineSpace1 ) ( parserForBasicToken < "rpc" > ( "rpc" ) ) ; export type ChannelToken = BasicToken < "channel" > ; const channelTokenParser = apFirst ( nonNewlineSpace1 ) ( parserForBasicToken < "channel" > ( "channel" ) ) ; export type ColonToken = BasicToken < "colon" > ; const colonTokenParser = allowSpaceAround ( parserForBasicToken < "colon" > ( "colon" , ":" ) ) ; export type NewLineToken = BasicToken < "newline" > ; const newlineTokenParser = map ( ( ) : NewLineToken => ( { token : "newline" } ) ) ( allowSpaceLeft ( char ( "\n" ) ) ) ; export type IndentToken = BasicToken < "indent" > ; const indentParser = map ( ( ) : IndentToken => ( { token : "indent" } ) ) ( either ( string ( "  " ) , ( ) => char ( "\t" ) ) ) ; export type CommaToken = BasicToken < "comma" > ; const commaTokenParser = allowNewlineSpaceRight ( allowSpaceLeft ( parserForBasicToken < "comma" > ( "comma" , "," ) ) ) ; export type PeriodToken = BasicToken < "period" > ; const periodTokenParser = allowNewlineSpaceRight ( allowSpaceLeft ( parserForBasicToken < "period" > ( "period" , "." ) ) ) ; export type OpenBracketToken = BasicToken < "openbracket" > ; const openBracketTokenParser = allowNewlineSpaceRight ( allowSpaceLeft ( parserForBasicToken < "openbracket" > ( "openbracket" , "<" ) ) ) ; export type CloseBracketToken = BasicToken < "closebracket" > ; const closeBracketTokenParser = allowSpaceAround ( parserForBasicToken < "closebracket" > ( "closebracket" , ">" ) ) ; export type NameToken = { token : "name" ; name : string ; } ; export const nameTokenParser = map ( ( name ) : NameToken => ( { token : "name" , name : name } ) ) ( stringMany1 ( alphanum ) ) ; export type ShiftInToken = BasicToken < "shiftIn" > ; export type ShiftOutToken = BasicToken < "shiftOut" > ; export const commentParser = map ( ( ) => undefined ) ( seq ( spaces , ( ) => seq ( char ( "#" ) , ( ) => many ( sat ( isNonNewline ) ) ) ) ) ; export type Token = ImportToken | FromToken | QuotedStringToken | StructToken | OneOfToken | ServiceToken | RPCToken | ChannelToken | ColonToken | NewLineToken | IndentToken | ShiftInToken | ShiftOutToken | CommaToken | PeriodToken | OpenBracketToken | CloseBracketToken | NameToken ; export const lexer = map ( ( tokens ) => tokens . filter ( Boolean ) as Token [ ] ) ( seq ( spaces , ( ) => apFirst ( seq ( spaces , ( ) => eof < string > ( ) ) ) ( many ( anyOf < string , Token | void > ( [ commentParser , importTokenParser , fromTokenParser , structTokenParser , oneofTokenParser , serviceTokenParser , rpcTokenParser , channelTokenParser , quotedStringTokenParser , colonTokenParser , commaTokenParser , periodTokenParser , openBracketTokenParser , closeBracketTokenParser , newlineTokenParser , indentParser , nameTokenParser , ] ) ) ) ) ) ;