diff --git a/ldtext/Parser.fs b/ldtext/Parser.fs index f70f310..99f21c9 100644 --- a/ldtext/Parser.fs +++ b/ldtext/Parser.fs @@ -35,7 +35,9 @@ type tokenId = | TOKEN_error // This type is used to give symbolic names to token indexes, useful for error messages type nonTerminalId = - | NONTERM__startinstr + | NONTERM__startrung + | NONTERM_rung + | NONTERM_steps | NONTERM_instr | NONTERM_operands | NONTERM_operand @@ -72,13 +74,16 @@ let tokenTagToTokenId (tokenIdx:int) = /// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production let prodIdxToNonTerminal (prodIdx:int) = match prodIdx with - | 0 -> NONTERM__startinstr - | 1 -> NONTERM_instr - | 2 -> NONTERM_operands - | 3 -> NONTERM_operands - | 4 -> NONTERM_operands - | 5 -> NONTERM_operand - | 6 -> NONTERM_operand + | 0 -> NONTERM__startrung + | 1 -> NONTERM_rung + | 2 -> NONTERM_steps + | 3 -> NONTERM_steps + | 4 -> NONTERM_instr + | 5 -> NONTERM_operands + | 6 -> NONTERM_operands + | 7 -> NONTERM_operands + | 8 -> NONTERM_operand + | 9 -> NONTERM_operand | _ -> failwith "prodIdxToNonTerminal: bad production index" let _fsyacc_endOfInputTag = 11 @@ -109,94 +114,127 @@ let _fsyacc_dataOfToken (t:token) = | RIGHT_PAREN -> (null : System.Object) | LEFT_PAREN -> (null : System.Object) | IDENTIFIER _fsyacc_x -> Microsoft.FSharp.Core.Operators.box _fsyacc_x -let _fsyacc_gotos = [| 0us;65535us;1us;65535us;0us;1us;2us;65535us;3us;4us;7us;8us;2us;65535us;3us;6us;7us;6us;|] -let _fsyacc_sparseGotoTableRowOffsets = [|0us;1us;3us;6us;|] -let _fsyacc_stateToProdIdxsTableElements = [| 1us;0us;1us;0us;1us;1us;1us;1us;1us;1us;1us;1us;2us;3us;4us;1us;3us;1us;3us;1us;5us;1us;6us;|] -let _fsyacc_stateToProdIdxsTableRowOffsets = [|0us;2us;4us;6us;8us;10us;12us;15us;17us;19us;21us;|] -let _fsyacc_action_rows = 11 -let _fsyacc_actionTableElements = [|1us;32768us;8us;2us;0us;49152us;1us;32768us;7us;3us;2us;16386us;1us;10us;8us;9us;1us;32768us;6us;5us;0us;16385us;1us;16388us;3us;7us;2us;16386us;1us;10us;8us;9us;0us;16387us;0us;16389us;0us;16390us;|] -let _fsyacc_actionTableRowOffsets = [|0us;2us;3us;5us;8us;10us;11us;13us;16us;17us;18us;|] -let _fsyacc_reductionSymbolCounts = [|1us;4us;0us;3us;1us;1us;1us;|] -let _fsyacc_productionToNonTerminalTable = [|0us;1us;2us;2us;2us;3us;3us;|] -let _fsyacc_immediateActions = [|65535us;49152us;65535us;65535us;65535us;16385us;65535us;65535us;16387us;16389us;16390us;|] +let _fsyacc_gotos = [| 0us;65535us;1us;65535us;0us;1us;2us;65535us;0us;2us;5us;6us;2us;65535us;0us;5us;5us;5us;2us;65535us;8us;9us;12us;13us;2us;65535us;8us;11us;12us;11us;|] +let _fsyacc_sparseGotoTableRowOffsets = [|0us;1us;3us;6us;9us;12us;|] +let _fsyacc_stateToProdIdxsTableElements = [| 1us;0us;1us;0us;1us;1us;1us;1us;1us;1us;1us;3us;1us;3us;1us;4us;1us;4us;1us;4us;1us;4us;2us;6us;7us;1us;6us;1us;6us;1us;8us;1us;9us;|] +let _fsyacc_stateToProdIdxsTableRowOffsets = [|0us;2us;4us;6us;8us;10us;12us;14us;16us;18us;20us;22us;25us;27us;29us;31us;|] +let _fsyacc_action_rows = 16 +let _fsyacc_actionTableElements = [|1us;16386us;8us;7us;0us;49152us;1us;32768us;2us;3us;1us;32768us;0us;4us;0us;16385us;1us;16386us;8us;7us;0us;16387us;1us;32768us;7us;8us;2us;16389us;1us;15us;8us;14us;1us;32768us;6us;10us;0us;16388us;1us;16391us;3us;12us;2us;16389us;1us;15us;8us;14us;0us;16390us;0us;16392us;0us;16393us;|] +let _fsyacc_actionTableRowOffsets = [|0us;2us;3us;5us;7us;8us;10us;11us;13us;16us;18us;19us;21us;24us;25us;26us;|] +let _fsyacc_reductionSymbolCounts = [|1us;3us;0us;2us;4us;0us;3us;1us;1us;1us;|] +let _fsyacc_productionToNonTerminalTable = [|0us;1us;2us;2us;3us;4us;4us;4us;5us;5us;|] +let _fsyacc_immediateActions = [|65535us;49152us;65535us;65535us;16385us;65535us;16387us;65535us;65535us;65535us;16388us;65535us;65535us;16390us;16392us;16393us;|] let _fsyacc_reductions = lazy [| -# 123 "Parser.fs" +# 128 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> - let _1 = parseState.GetInput(1) :?> Instr in + let _1 = parseState.GetInput(1) :?> Instr list in Microsoft.FSharp.Core.Operators.box ( ( raise (FSharp.Text.Parsing.Accept(Microsoft.FSharp.Core.Operators.box _1)) ) - : 'gentype__startinstr)); -# 132 "Parser.fs" + : 'gentype__startrung)); +# 137 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> - let _1 = parseState.GetInput(1) :?> string in - let _3 = parseState.GetInput(3) :?> 'gentype_operands in + let _1 = parseState.GetInput(1) :?> 'gentype_steps in Microsoft.FSharp.Core.Operators.box ( ( -# 29 "Parser.fsy" - { Op = _1; Args = _3 } +# 26 "Parser.fsy" + _1 ) -# 29 "Parser.fsy" - : Instr)); -# 144 "Parser.fs" +# 26 "Parser.fsy" + : Instr list)); +# 148 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> Microsoft.FSharp.Core.Operators.box ( ( -# 32 "Parser.fsy" +# 29 "Parser.fsy" [] ) -# 32 "Parser.fsy" +# 29 "Parser.fsy" + : 'gentype_steps)); +# 158 "Parser.fs" + (fun (parseState : FSharp.Text.Parsing.IParseState) -> + let _1 = parseState.GetInput(1) :?> 'gentype_instr in + let _2 = parseState.GetInput(2) :?> 'gentype_steps in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 30 "Parser.fsy" + _1 :: _2 + ) +# 30 "Parser.fsy" + : 'gentype_steps)); +# 170 "Parser.fs" + (fun (parseState : FSharp.Text.Parsing.IParseState) -> + let _1 = parseState.GetInput(1) :?> string in + let _3 = parseState.GetInput(3) :?> 'gentype_operands in + Microsoft.FSharp.Core.Operators.box + ( + ( +# 33 "Parser.fsy" + { Op = _1; Args = _3 } + ) +# 33 "Parser.fsy" + : 'gentype_instr)); +# 182 "Parser.fs" + (fun (parseState : FSharp.Text.Parsing.IParseState) -> + Microsoft.FSharp.Core.Operators.box + ( + ( +# 36 "Parser.fsy" + [] + ) +# 36 "Parser.fsy" : 'gentype_operands)); -# 154 "Parser.fs" +# 192 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> let _1 = parseState.GetInput(1) :?> 'gentype_operand in let _3 = parseState.GetInput(3) :?> 'gentype_operands in Microsoft.FSharp.Core.Operators.box ( ( -# 33 "Parser.fsy" +# 37 "Parser.fsy" _1 :: _3 ) -# 33 "Parser.fsy" +# 37 "Parser.fsy" : 'gentype_operands)); -# 166 "Parser.fs" +# 204 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> let _1 = parseState.GetInput(1) :?> 'gentype_operand in Microsoft.FSharp.Core.Operators.box ( ( -# 34 "Parser.fsy" +# 38 "Parser.fsy" [ _1 ] ) -# 34 "Parser.fsy" +# 38 "Parser.fsy" : 'gentype_operands)); -# 177 "Parser.fs" +# 215 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> let _1 = parseState.GetInput(1) :?> string in Microsoft.FSharp.Core.Operators.box ( ( -# 37 "Parser.fsy" +# 41 "Parser.fsy" OperandTag _1 ) -# 37 "Parser.fsy" +# 41 "Parser.fsy" : 'gentype_operand)); -# 188 "Parser.fs" +# 226 "Parser.fs" (fun (parseState : FSharp.Text.Parsing.IParseState) -> Microsoft.FSharp.Core.Operators.box ( ( -# 38 "Parser.fsy" +# 42 "Parser.fsy" OperandHole ) -# 38 "Parser.fsy" +# 42 "Parser.fsy" : 'gentype_operand)); |] -# 199 "Parser.fs" +# 237 "Parser.fs" let tables : FSharp.Text.Parsing.Tables<_> = { reductions = _fsyacc_reductions.Value; endOfInputTag = _fsyacc_endOfInputTag; @@ -218,5 +256,5 @@ let tables : FSharp.Text.Parsing.Tables<_> = numTerminals = 12; productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable } let engine lexer lexbuf startState = tables.Interpret(lexer, lexbuf, startState) -let instr lexer lexbuf : Instr = +let rung lexer lexbuf : Instr list = engine lexer lexbuf 0 :?> _ diff --git a/ldtext/Parser.fsi b/ldtext/Parser.fsi index 340c33e..19a1d95 100644 --- a/ldtext/Parser.fsi +++ b/ldtext/Parser.fsi @@ -23,7 +23,9 @@ type tokenId = | TOKEN_end_of_input | TOKEN_error type nonTerminalId = - | NONTERM__startinstr + | NONTERM__startrung + | NONTERM_rung + | NONTERM_steps | NONTERM_instr | NONTERM_operands | NONTERM_operand @@ -38,4 +40,4 @@ val prodIdxToNonTerminal: int -> nonTerminalId /// This function gets the name of a token as a string val token_to_string: token -> string -val instr : (FSharp.Text.Lexing.LexBuffer<'cty> -> token) -> FSharp.Text.Lexing.LexBuffer<'cty> -> (Instr) +val rung : (FSharp.Text.Lexing.LexBuffer<'cty> -> token) -> FSharp.Text.Lexing.LexBuffer<'cty> -> (Instr list) diff --git a/ldtext/Parser.fsy b/ldtext/Parser.fsy index 3294279..971bad6 100644 --- a/ldtext/Parser.fsy +++ b/ldtext/Parser.fsy @@ -3,9 +3,6 @@ open LDText.Ast open FSharp.Text.Lexing %} -// start token -%start instr - // tokens, used by lexer %token IDENTIFIER %token LEFT_PAREN @@ -17,13 +14,20 @@ open FSharp.Text.Lexing %token QUESTION_MARK %token EOF +// start token +%start rung + // return type of parser, marked by start token -%type instr +%type rung %% -//rung: -// | instr EOF { $1 } +rung: + | steps SEMICOLON EOF { $1 } + +steps: + | { [] } + | instr steps { $1 :: $2 } instr: | IDENTIFIER LEFT_PAREN operands RIGHT_PAREN { { Op = $1; Args = $3 } } diff --git a/ldtext/test.fsx b/ldtext/test.fsx index 8ac584f..d06074c 100644 --- a/ldtext/test.fsx +++ b/ldtext/test.fsx @@ -3,9 +3,24 @@ #load "Parser.fs" #load "Lexer.fs" -let parse (s:string) = - s |> System.Text.Encoding.ASCII.GetBytes |> FSharp.Text.Lexing.LexBuffer.FromBytes |> Parser.instr(Lexer.read) +let mutable failed = false -parse "abc()" -parse "abc(def)" -// parse "abc(def,ghi)" \ No newline at end of file +let parse (s:string) = + let lexbuf = s |> System.Text.Encoding.ASCII.GetBytes |> FSharp.Text.Lexing.LexBuffer.FromBytes + let msg = + try + sprintf "%A" <| Parser.rung Lexer.read lexbuf + with e -> + let pos = lexbuf.EndPos + let lastToken = System.Text.Encoding.ASCII.GetString lexbuf.Lexeme + failed <- true + sprintf "Parse failed at %d, last token = %A" pos.AbsoluteOffset lastToken + printf "%A -> %s\n" s msg + + +parse "abc();" +parse "abc(def);" +parse "abc(def,ghi);" +parse "abc(def,ghi) a(b) ;" + +if failed then exit 1 else exit 0 \ No newline at end of file