Consider the grammar below...
bexp -> bterm | bterm ‘||’ bexp
bterm -> bfact | bfact ‘&&’ bterm
bfact -> true | false | id | ‘(‘ bexp ‘)’
Suppose we extend BEXP with the '!' operator for negation by changing the bfact rule as follows:-
bfact -> true | false | id | '(' bexp ')' | '!' bexp
Lets call this extended grammar BEXP2. How can I prove that it is ambiguous?
You can prove that it is ambiguous by finding a string with two parses :)
In this case, try !id&&id. Is that (!id)&&id or !(id&&id)
Related
I'm sorry that this is a beginner question. I just trying to let x = 5, y = 2, and set all other variables to zero in a function s. All this work is to verify p computes 5! in the code below, where p representing
y:=1 ; while ¬(x=1) do (y:=y*x; x:=x-1);
type Num = Integer
type Var = String
type Z = Integer
type T = Bool
type State = Var -> Z
data Aexp = N Num | V Var | Add Aexp Aexp | Mult Aexp Aexp | Sub Aexp Aexp deriving (Show, Eq, Read)
data Bexp = TRUE | FALSE | Eq Aexp Aexp | Le Aexp Aexp | Neg Bexp | And Bexp Bexp deriving (Show, Eq, Read)
data Stm = Ass Var Aexp | Skip | Comp Stm Stm | If Bexp Stm Stm | While Bexp Stm deriving (Show, Eq, Read)
p::Stm
p = (Comp(Ass "y" (N 1))(While(Neg(Eq (V "x") (N 1)))(Comp (Ass "y" (Mult (V "y") (V "x")))(Ass "x" (Sub (V "x") (N 1))))))
s :: State {- It has to be Var -> Int-}
s x = 5
s y = 2
And when I try to compile this, ghci gives that the pattern matches are overlapped. I know this is a quite simple question, but there is not much information online for me to solve this. Could you give me any hints? Thanks!
You are pattern matching. This is typically done using different values of the argument type.
didSayHello :: String -> Bool
didSayHello "hello" = True
didSayHello x = False
This matches top-down, reading "if the string argument is 'hello', then True" and "if it is any random String argument (excluding 'hello'), then False"
Your matches are overlapping because in both patterns you're referring to any random String place holder. The one just happened to be called "x" and the other "y".
See this link for more details
The two alternatives are doing exactly the same thing: matching on any value passed in, and calling it x. Since the first case matches anything it always succeeds and returns 5.
To do what you seem to be trying to do, you cannot use pattern matching, you need to use equality (via the Eq class):
s :: Var -> Int
s v | v == x = 5
| v == y = 3
You cannot pattern match against other values, only patterns. x and y are values when you defined them using let, but x and y are patterns (matching absolutely any input value)
You mentioned that Var is a String, so this won't work if x and y are set like let x = 5, y = 2 because there is no instance for Num String, so x and y won't be Strings, and can't be tested for equality with a Var
It's pretty unclear what you are trying to do, but know that assignment does not really exist in Haskell. Perhaps you want to look at
s string =
let
x = 5
y = 2
in
-- something using x and y, e.g.
x + y
In this case s will return 7 no matter what string you pass it, i.e. :
s "alpha" => 7
s "beta" => 7
I have a huge ANTLR grammar, and I am facing problem with a small piece of it. Grammar has two rules expr and sets as defined below:
expr:
id
|(PLUS|MINUS|MULTIPLY|AND|NEGATION)expr
| expr (MULTIPLY |DIVIDE| MODULO)
| expr (PLUS | MINUS) expr
;
set:
EMPTY
| MULTIPLY set
| set PLUS set
| UNION '(' set (COMMA set)* ')'
| INTER '(' set (COMMA set)* ')'
| expr
;
The problem here is that for a set of form *s1 + *s2 should be reduced as following:
set -> set PLUS set
and then each set in RHS should reduce to:
set -> MULTIPLY set
set -> expr
term -> id
But instead they are reducing as:
set -> MULTIPLY set
set -> expr
expr -> expr PLUS expr
Because of whichset of forn *s1 +*s2 is parsed as *(s1 + *s2) instead of (*s1) + (*s2).
One of the rules of set, reduces it to expr. There are many other similar rules in grammar which reduces to expr. The problem is occurring here becuase some of the rules in set and expr are similar. But because some rules are different, I cannot merge them together.
In set even though the precedence of rule MULTIPLY set is higher than set PLUS set, set is reduced by MUTIPLY set rule.
Is there a way to fix this issue?
EDIT:
Adding a working example :
Grammar:
grammar T;
expr
: ID
| ( PLUS | MINUS | MULTIPLY | AND | NEGATION ) expr
| expr ( MULTIPLY | DIVIDE | MODULO )
| expr ( PLUS | MINUS ) expr
;
set:
EMPTY
| MULTIPLY set
| set PLUS set
| UNION '(' set (COMMA set)* ')'
| INTER '(' set (COMMA set)* ')'
| expr
;
ID : [a-zA-Z] [a-zA-Z0-9]*;
PLUS : '+';
MINUS : '-';
MULTIPLY : '*';
AND : '&&';
NEGATION : '!';
DIVIDE : '/';
MODULO : '%';
COMMA : ',';
EMPTY: '\\empty';
UNION: '\\union';
INTER: '\\inter';
SPACES : [ \t\r\n] -> skip;
Code to execute it:
TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2"));
TParser parser = new TParser(new CommonTokenStream(lexer));
RuleContext tree = parser.set();
tree.inspect(parser);
Output it generated:
set
/ \
* set
|
expr
/ | \
/ | \
expr + expr
| / \
s1 * expr
|
s2
I can't reproduce this.
Given the grammar:
grammar T;
expr
: ID
| ( PLUS | MINUS | MULTIPLY | AND | NEGATION ) expr
| expr ( MULTIPLY | DIVIDE | MODULO )
| expr ( PLUS | MINUS ) expr
;
ID : [a-zA-Z] [a-zA-Z0-9]*;
PLUS : '+';
MINUS : '-';
MULTIPLY : '*';
AND : '&&';
NEGATION : '!';
DIVIDE : '/';
MODULO : '%';
SPACES : [ \t\r\n] -> skip;
your input *s1 + *s2 will be parsed as:
expr
/ | \
/ | \
expr + expr
/ \ / \
* expr * expr
| |
s1 s2
Or, in plain code:
TLexer lexer = new TLexer(new ANTLRInputStream("*s1 + *s2"));
TParser parser = new TParser(new CommonTokenStream(lexer));
System.out.println(parser.expr().toStringTree(parser));
will print:
(expr (expr * (expr s1)) + (expr * (expr s2)))
I have my own data type that states:
data Commands = MoveLeft |
MoveRight |
MoveUp |
MoveDown |
IfVertical |
IfHorizontal |
InputChar |
InputInt |
OutputChar |
OutputInt |
OutputNewline |
PushInt Int |
Add |
Sub |
Mult |
Div |
Exp |
Pop |
Dup |
Switch |
Noop |
End
deriving (Show, Eq)
and I have a function, with which I'm trying to extract the number from the PushInt with:
extractNum :: PushInt -> Int
extractNum (PushInt n) = n
But when I try to run this, I get an error stating:
Parser.hs:32:19:
Not in scope: type constructor or class `PushInt'
A data constructor of that name is in scope; did you mean -XDataKinds?
As far as I knew I was allowed to extract a field from data with this method. I'm pretty sure that this is just a really simple mistake, but any help is appreciated.
Wow, was I right about a 2 am mistake. The function
extractNum :: PushInt -> Int
extractNum (PushInt n) = n
should be
extractNum :: Commands -> Int
extractNum (PushInt n) = n
The following code does not parse:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
print $ result
where result = last [1..1000000]
The compiler complains on the second print:
src/Main.hs:10:5: parse error on input `print'
Why is this?
The problem is that where clauses can be attached to bindings only, not to expressions.
In fact:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
is exactly equivalent to:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
i.e. the where defines local definitions for main not for the print $ result line.
Since where must be the last part of a binding obviously the following print expression causes a syntax error.
To use a where inside a do-block you have to use it when defining the let bindings such as this (very silly example):
main = do
let result = f
where f = foldl' (+) 0 [1..1000000]
print result
You can check this in the grammar:
decl → gendecl
| (funlhs | pat) rhs
rhs → = exp [where decls]
| gdrhs [where decls]
Note that the where decls is part of the rhs rule which defines the right hand side of a declaration. If you check the rules for exp you wont find where mentioned:
exp → infixexp :: [context =>] type (expression type signature)
| infixexp
infixexp → lexp qop infixexp (infix operator application)
| - infixexp (prefix negation)
| lexp
lexp → \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1)
| let decls in exp (let expression)
| if exp [;] then exp [;] else exp (conditional)
| case exp of { alts } (case expression)
| do { stmts } (do expression)
| fexp
fexp → [fexp] aexp (function application)
aexp → qvar (variable)
| gcon (general constructor)
| literal
| ( exp ) (parenthesized expression)
| ( exp1 , … , expk ) (tuple, k ≥ 2)
| [ exp1 , … , expk ] (list, k ≥ 1)
| [ exp1 [, exp2] .. [exp3] ] (arithmetic sequence)
| [ exp | qual1 , … , qualn ] (list comprehension, n ≥ 1)
| ( infixexp qop ) (left section)
| ( qop⟨-⟩ infixexp ) (right section)
| qcon { fbind1 , … , fbindn } (labeled construction, n ≥ 0)
| aexp⟨qcon⟩ { fbind1 , … , fbindn } (labeled update, n ≥ 1)
I've been given the following Data types:
data Aexp = N Integer | V Var | Add Aexp Aexp | Mult Aexp Aexp | Sub Aexp Aexp
data Bexp = Bcon Bool | Eq Aexp Aexp | Le Aexp Aexp | Neg Bexp | And Bexp Bexp
data Stm = Ass Var Aexp | Skip | Comp Stm Stm | If Bexp Stm Stm | While Bexp Stm | Block DecV DecP Stm | Call Pname
For Arithmetic expressions, Boolean expressions and Statements respectively.
I have been asked to return a Stm representing the following program:
x:=5;
y:=1;
while ¬(x=1) do
y:=y*x;
x:=x-1
So far I have the following :
p :: Stm
p = (Ass x 5) (Ass y 1) (While (Neg (Eq x 1)) Ass x (Sub x 1) Ass y (Mult y x))
I did this simply by writing out the program on paper and then drawing a syntax tree from it. Firstly I'm not sure if this is actually correct as I don't really know how to prove it. And secondy when I compile I get lots of errors like:
denotational.hs:122:10: Not in scope: `x'
denotational.hs:122:20: Not in scope: `y'
denotational.hs:122:41: Not in scope: `x'
denotational.hs:122:51: Not in scope: `x'
denotational.hs:122:58: Not in scope: `x'
denotational.hs:122:67: Not in scope: `y'
denotational.hs:122:75: Not in scope: `y'
denotational.hs:122:77: Not in scope: `x'
Any help with this would be greatly appreciated. Thanks
Your AST is a representation of the syntax of the (sub-)language. Everything that is in that sublanguage must be in your AST and nothing of Haskell.
So, assuming your language is fully represented by a list of Stms you might write
x:=5;
as
fragx :: [Stm]
fragx = [ Ass "x" (N 5) ]
which captures in the tree structure of your AST all of the information in that fragment from the sort of literal to the name of the variable being bound. A larger example
x:=5;
y:=1;
is
frag2 :: [Stm]
frag2 = [ Ass "x" (N 5)
, Ass "y" (N 1)
]
fragy :: [Stm]
fragy = [ Ass "y" (N 1) ]
with
frag2 == fragx ++ fragy
which demonstrates how we can talk about appending two programs syntactically as the Haskell function (++) :: [Stm] -> [Stm] -> [Stm]. Again, these fragments are simple static representations of the syntax of the sublanguage. There is nothing tricky going on in the Haskell side, in particular, no bleeding of Haskell variables into sublanguage variables.
The adding final fragment might look like
fragAll :: [Stm]
fragAll = fragx ++ fragy
++ [ While (Neg (Eq (V "x") (N 1))) (Block ...)
]
but it cannot be completed without looking into the structure of the arguments to Block.