Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //namespace Yard.Unger
- open LanguagePrimitives
- //open Yard.Generators.Common.FinalGrammar
- open System.IO
- type ProductionRule (leftHandSides : int, rightHandSides : List<int>) =
- let leftHandSide = leftHandSides
- let rightHandSide = rightHandSides
- //new() = new ProductionRule(0, [||])
- new() = new ProductionRule(0, [])
- member this.getLeftHandSide() = leftHandSide
- member this.getRightHandSide() = rightHandSide
- member this.equals(rule : ProductionRule) = ((rule.getLeftHandSide() = leftHandSide) && (rule.getRightHandSide() = rightHandSide))
- type ProductionRule1 (leftHandSides : string, rightHandSides : List<string>) =
- let leftHandSide = leftHandSides
- let rightHandSide = rightHandSides
- //new() = new ProductionRule(0, [||])
- new() = new ProductionRule1("", [])
- member this.getLeftHandSide() = leftHandSide
- member this.getRightHandSide() = rightHandSide
- member this.equals(rule : ProductionRule1) = ((rule.getLeftHandSide() = leftHandSide) && (rule.getRightHandSide() = rightHandSide))
- type Goal(r : ProductionRule, p : int, l : int) =
- let mutable rule : ProductionRule = r
- let mutable position : int = p
- let mutable length : int = l
- new() = new Goal(new ProductionRule(), 0, 0)
- member this.getRule() = rule
- member this.getPosition() = position
- member this.getLength() = length
- member this.equals(goal : Goal) = ((goal.getPosition() = position) && (goal.getLength() = length) && (goal.getRule().equals(rule)))
- type OperationTuple(g : Goal, rp : int, ir : int) =
- let mutable goal = g
- let mutable rhsPosition = rp
- let mutable inRec = ir
- new() = new OperationTuple(new Goal(),0,0)
- member this.getGoal() = goal
- member this.getRhsPosition() = rhsPosition
- member this.getInRec() = inRec
- member this.incrementRhsPosition(value : int) = rhsPosition <- rhsPosition + value;
- member this.incrementInRec( value : int) = inRec <- inRec + value
- member this.decrementRhsPosition(value : int) = rhsPosition <- rhsPosition - value
- member this.decrementInRec (value : int) = inRec <- inRec - value
- //type Grammar(grammarPath : string) =
- type Grammar() =
- (*let ilParser = new Yard.Frontends.YardFrontend.YardFrontend()
- let il = ilParser.ParseGrammar(grammarPath)
- let grammar = new FinalGrammar(il.grammar.[0].rules, true)
- *)
- let mutable productionRules = []
- //let mutable startSymbol : int = grammar.rules.leftSide grammar.startRule
- let mutable startSymbol : int = 69
- let mutable nonTerms = []
- let eor = -100
- (* member this.retgr = grammar
- member this.Grammar() =
- for i in 0..grammar.rules.rulesCount-1 do
- let lhs = grammar.rules.leftSide i
- productionRules <- List.append [new ProductionRule(lhs, (Array.append (grammar.rules.rightSide i) [|eor|]))] productionRules
- if (nonTerms.IsEmpty) || (not (List.exists(fun x -> x = lhs) nonTerms)) then nonTerms <- List.append nonTerms [lhs]
- *)
- member this.Grammar() =
- this.addProductionRule("E")
- this.addProductionRule("E: a;")
- this.addProductionRule("E: a T;")//("E",["E";"+";"T"]) E-> Et + r
- this.addProductionRule("T: a;")
- member this.addProductionRule(line : string) =
- if not (line.Contains(":") ) then
- startSymbol <- int(line.[0])
- else
- let rhs1 = List.filter (fun x -> not (x = "")) (Array.toList (line.Substring(line.IndexOf(" ") + 1).Replace("'","").Replace(";"," ;").Split(' ')))
- let mutable rhs = []
- for i in 0..rhs1.Length-1 do
- rhs <- List.append rhs [int(rhs1.[i].[0])]
- let lhs = int(line.[0])
- productionRules <- List.append [(new ProductionRule(lhs, rhs))] productionRules
- //productionRules <- List.append [(new ProductionRule(lhs,rhs))] productionRules
- if not (List.exists(fun x -> x = lhs) nonTerms) then nonTerms <- List.append nonTerms [lhs]
- member this.getRulesForSymbol(symbol : int) =
- let mutable rulesForSymbol = []
- for i in 0..productionRules.Length-1 do
- let rule : ProductionRule = productionRules.[i]
- if (rule.getLeftHandSide() = symbol) then
- rulesForSymbol <- List.append [rule] rulesForSymbol
- rulesForSymbol
- member this.getStartSymbol = startSymbol
- member this.isNonTerminal (symbol : int) = List.exists (fun x-> x = symbol) nonTerms
- type Stack<'T when 'T: equality>( st : list<'T>) =
- let mutable st = st
- let popEl stk =
- match stk with
- |[] -> []
- |_::tl -> tl
- new() = new Stack<'T>([])
- member this.peek() =
- match st with
- |[] -> None
- |hd :: _ -> Some(hd)
- member this.push(a) = st <- a :: st
- member this.pop() =st <- popEl st
- member this.toList = st
- member this.Length() = st.Length
- member this.Empty() = if st = [] then true else false
- type Parser(grammar : Grammar)=
- let mutable operationalStack = new Stack<_>()
- let mutable derivationStack = new Stack<_>()
- let mutable parsingForest = []
- let mutable grammar : Grammar = grammar
- let mutable word : List<int> = []
- let eor : int = -100
- let copy input =
- let rec copy acc input =
- match input with
- |[] -> List.rev acc
- |x::xs -> copy (x::acc) xs
- copy [] input
- let convertSymbolToString (symbol : int) =
- string(char(symbol))
- (*
- if symbol < grammar.indexator.nonTermCount
- then grammar.indexator.indexToNonTerm symbol
- elif symbol >= grammar.indexator.termsStart && symbol <= grammar.indexator.termsEnd
- then grammar.indexator.indexToTerm symbol
- else grammar.indexator.indexToLiteral symbol
- *)
- let convList (lst : List<int>) =
- let mutable l = []
- for i in 0..lst.Length-1 do
- l <- List.append l [convertSymbolToString lst.[i]]
- l
- member this.parse(inpWord : List<string>) =
- let wordConvert =
- let mutable w = []
- for i in 0..inpWord.Length-1 do
- w <- List.append w [int(inpWord.[i].[0])]
- (* try
- w <- List.append w [grammar.retgr.indexator.literalToIndex inpWord.[i]]
- with
- | :? System.Collections.Generic.KeyNotFoundException ->
- try
- w <- List.append w [grammar.retgr.indexator.termToIndex inpWord.[i]]
- with
- | :? System.Collections.Generic.KeyNotFoundException -> () *)
- w
- grammar.Grammar()
- word <- wordConvert
- this.tryAllRulesFor(grammar.getStartSymbol,0,word.Length)
- let mutable ret = true
- if parsingForest.Length = 0 then ret <- false
- let mutable derivation = [""]
- let su = (parsingForest.Length) - 1
- let mutable parsingForestString = []
- let pfs (parsingForest :List<List<ProductionRule>>) =
- let mutable parsingForestString = []
- let su = (parsingForest.Length) - 1
- for i in 0..su do
- let mutable uns = []
- for j in 0..parsingForest.[i].Length-1 do
- let mutable lft = convertSymbolToString(parsingForest.[i].[j].getLeftHandSide())
- uns <- List.append uns [new ProductionRule1(lft, convList(parsingForest.[i].[j].getRightHandSide()))]
- parsingForestString <- List.append parsingForestString [uns]
- parsingForestString
- let parsingForestString = pfs parsingForest
- printfn "%A" parsingForestString.Length
- for i in 0..su do
- derivation <- [""]
- let mutable lastString : string = string(char((grammar.getStartSymbol)))
- derivation <- List.append derivation [lastString]
- let pfell = parsingForestString.[i].Length - 1
- let mutable j = pfell
- while j >= 0 do
- let mutable length = lastString.Length
- let mutable k = 0
- while k < length do
- if (grammar.isNonTerminal(int(lastString.[k]))) then
- let mutable ending : string = lastString.Substring(k+1)
- if (k = 0) then lastString <- "" else lastString <- lastString.Substring(0,k)
- lastString <- lastString + (string(parsingForestString.[i].[j].getRightHandSide()).Replace("[","").Replace("]","").Replace(";","").Replace(" ","").Substring(0, (parsingForestString.[i].[j].getRightHandSide().Length - 1)))
- lastString <- lastString + ending
- derivation <- List.append derivation [lastString]
- k <- k + length
- else k <- k + 1
- j <- j - 1
- printfn "%A" derivation.[0]
- for j in 1..(derivation.Length - 1) do
- printfn " %A =>\n" derivation.[j]
- parsingForest
- member this.tryAllRulesFor(symbol : int, position : int, lenght : int) =
- let rulesForSymbol = grammar.getRulesForSymbol(symbol)
- for i in 0..rulesForSymbol.Length-1 do
- this.tryRule(rulesForSymbol.[i],position,lenght)
- member this.tryRule(rule : ProductionRule, position : int, lenght : int) =
- let goal : Goal = new Goal(rule, position, lenght)
- if (not (this.isToBeAvoided(goal)) ) then
- operationalStack.push(new OperationTuple(goal , -1, 0))
- derivationStack.push(rule)
- this.doTopOfStack()
- derivationStack.pop()
- operationalStack.pop()
- member this.doTopOfStack()=
- let s : OperationTuple = operationalStack.peek().Value
- let goal : Goal = s.getGoal()
- let nextRhsSymbol : int = goal.getRule().getRightHandSide().[s.getRhsPosition() + 1]
- if (nextRhsSymbol = int(';')) then
- if (s.getInRec() = goal.getLength()) then
- this.doNextOnStack()
- else if ((s.getInRec() < goal.getLength()) && (nextRhsSymbol = word.[goal.getPosition() + s.getInRec()])) then
- s.incrementRhsPosition(1)
- s.incrementInRec(1)
- this.doTopOfStack()
- s.decrementRhsPosition(1)
- s.decrementInRec(1)
- else if (grammar.isNonTerminal(nextRhsSymbol)) then
- this.tryAllLengthsFor(nextRhsSymbol, goal.getPosition() + s.getInRec(), goal.getLength() - s.getInRec())
- member this.doNextOnStack()=
- let s : OperationTuple = operationalStack.peek().Value
- operationalStack.pop()
- if (operationalStack.Empty()) then
- parsingForest <- parsingForest @ [(copy (derivationStack.toList))]
- else
- let s1 : OperationTuple = operationalStack.peek().Value
- s1.incrementRhsPosition(1)
- s1.incrementInRec(s.getGoal().getLength())
- this.doTopOfStack()
- s1.decrementInRec(s.getGoal().getLength())
- s1.decrementRhsPosition(1)
- operationalStack.push(s)
- member this.tryAllLengthsFor(nonTerminal : int, position : int , length : int )=
- for i in 0..length do
- this.tryAllRulesFor(nonTerminal, position, i)
- member this.isToBeAvoided(goal : Goal)=
- let mutable k = false
- for i in 0..(operationalStack.Length()-1) do
- if (operationalStack.toList.[i].getGoal().equals(goal) = true) then k <- true
- k
- let main =
- //let grammar : Grammar = new Grammar("../../../../Tests/Unger/A.yrd")
- let grammar = new Grammar()
- let parser : Parser = new Parser(grammar)
- let parsingForest = parser.parse(["r"])
- parsingForest
- let k = main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement